ФП: вводная статья
От: Quintanar Россия  
Дата: 27.09.04 15:01
Оценка: 189 (17)
К сожалению, создается впечатление, что идея о создании отдельного раздела посвященного ФЯ постепенно заглохла. Предлагаю заинтересованным лицам все-таки собраться и написать общими силами хотя бы статью-введение. Поскольку не совсем ясно, о чем стоит писать, а о чем нет, было бы неплохо, если бы незнакомые с ФП, но заинтересованные в его изучении люди, запостили здесь свои вопросы, на которые знакомые с ФП люди написали бы им ответы, объяснили трудные для понимания аспекты ФП и т.п. В общем, как писал VladD2 в соседней ветке, предлагается совместно создать документ, который действительно был бы полезен программистам не знакомым с функциональным стилем, чтобы изучив его, они легко могли бы составить впечатление о возможностях ФЯ, отличиях их от ИЯ, основных приемах программирования под ними и т.д.
Для начала со своей стороны я готов дать информацию по Haskell'ю и общим вопросам, связанным с ФП, а пока пощу здесь свою расшифровку некоторых базовых терминов часто употребляющихся по отношению к ФЯ.



Чистые ФЯ
Когда говорят о чистых ФЯ, обычно имеют ввиду языки, вычисления в которых осуществляются исключительно
при помощи композиции функции и где отсутствуют какие-либо сторонние эффекты. Данное
определение через чур строгое и, собственно говоря, под него не подходит ни один реальный
язык программирования. Т.е. ни один ЯП, который стоило бы использовать на практике.
Тем не менее полностью чистые ФЯП существуют. В качестве примера можно привести лямбда
исчисление.
Однако, имеет смысл несколько ослабить требование отсутствия сторонних эффектов, ибо ни
одна программа, которая принимает данные от пользователя и выдает ему в ответ результат, не
может без них обойтись. Если сторонние эффекты в ЯП "практически" отсутствуют, то ФЯ
называется чистым. К таким языкам относят, например, Haskell, где императивный ввод-вывод
осуществляется с помощью специального механизма монад, которые изолируют чистую
функциональную часть программы от нечистой императивной. В тоже время SML и OCaml
не являются чистыми функциональными языками, поскольку допускают использование императивных
конструкций типа операций присваивания и исключений.

Вызов по значению и вызов по имени
При вызове функции у нас есть два способа передать ей параметры. Первый способ заключается в
том, чтобы сначала вычислить параметры и потом передать в функцию вычисленные значения. А второй
в том, чтобы ничего не вычисляя передать в функцию выражения, по которым можно вычислить
ее параметры. Если функции понадобятся значения этих выражений, она их вычислит по мере
необходимости. Первый способ вызова называется вызовом по значению, поскольку в функцию передается
конкретное значение — целое, строка, список и т.д. Второй способ называется вызовом по имени,
поскольку в функцию передается невычисленное выражение. Вызов по имени в целом более выгоден,
так как экономится время необходимое для вычисления ненужных параметров, но он работает только
в чистых ФЯ, где нет сторонних эффектов. Другой особенностью вызова по имени является устойчивость
к ошибкам. Даже если вычисление одного из параметров приводит к ошибке, выражение в целом может быть
вычисленно, если в нем не задействовано значение этого параметра. В императивных языках есть функции,
которые симулируют вызов по имени. Например логическое "И" — && в С не вычисляет свой второй аргумент,
если первый равен 0. Эта особенность широко используется во многих программах, в том числе и в ядре Linux.
Языки поддерживающие вызов по значению называются строгими, те, что поддерживают вызов по имени,
называются нестрогими. Haskell нестрогий язык, а SML и OCaml строгие.

Строгая типизация
Не все функциональные языки обладают системой типов. Например, Lisp является бестиповым языком. Однако,
здесь речь пойдет только о языках со строгой типизацией. В таких языках каждая константа, каждое выражение
или функция имеют свой тип. Не допускается смешивание разных типов, даже если один из них можно легко
преобразовать в другой. Например, если у функции есть вещественный параметр, ей нельзя передать целое число
как в С++, сначала его нужно явно преобразовать в вещественное. Не допускается обестипливание как,
например, в C#. Невозможно преобразовать целое число к некоторому общему типу object. Эти строгости
компенсируются развитостью системы типов, легкостью работы со сложными типами и полиморфизмом. Легкость
работы обеспечивается сравнением с образцом (объяснено в другом разделе), а другие две темы мы обсудим чуть
ниже. При компиляции программы компилятор проверяет на соответствие все типы в программе и при несовпадении
типов выдает ошибку. В дальнейшем при выполнении программы уже не могут возникнуть исключительные ситуации
связанные с ошибочным типом, как это часто происходит в С++ или даже C#. Вам придется поверить мне на слово,
однако, я (и не только я) утверждаю, что благодаря строгой типизации и рвению компилятора в области
выявления связанных с этим ошибок, удается значительно сократить количество проблем, возникающих при
выполнении программы.
Ранее я упомянул, что строгость системы типов компенсируется ее развитостью. В самом деле, ФЯ позволяют
программисту малыми силами определять сложные типы данных типа списков, деревьев и т.п. Основным типом
ФЯ можно назвать список — создание списков и работа с ними упрощены до безобразия. Например, чтобы создать
список вам достаточно написать
[a,b,c]

где a,b и c — это элементы списка. Хотите создать список в списке? Пожалуйста
[[a,b,c],[],[n,r]]

Для работы со списками существует огромное количество функций, в том числе специальная функция помещения
элемента в список, которая обычно обозначается : или ::
1:[2,3]

Вторым важным конструктором новых типов является кортеж (tuple). Это всего лишь набор разнотипных значений
вроде
(1,"str",'a')

Кортежы используются для возвращения из функций нескольких значений, определения сложных типов типа деревьев
или списков и т.п.
Многие ФЯ допускают использование структур, которые по сути своей являются кортежами с именоваными полями.
Допускается определение древовидных или циклических структур данных. Например, определим тип для выражения
в языке программирования
data Expr = Var String | Integer Int | Str String | Assign Var Expr | Func Var [Expr]

Var, Integer, Str, Func и Assign — это так называемые конструкторы типа. С их помощью можно создать
значение типа Expr
Assign (Var "my_var") (Func (Var "my_func") [(Str "str"),(Integer 10)])

Возможности впечатляют, однако, это еще не все. Система типов в ФЯ полиморфна. Мы можем определять как
полиморфные функции так и полиморфные типы данных и при этом не теряется строгость типизации! Как
определить можно ли в качестве параметра функции типа A подставить значение или выражение типа B? Нужно
просто посмотреть, можно ли свести тип B к типу A. В С++ аналогичная ситуация возникает, если от класса
A унаследованы классы B и C. B можно свести к A, но нельзя свести к C. В ФЯ производится аналогичная
процедура проверки, только ввиду всеобщего полиморфизма она намного сложнее. Например функция
my_func x = [x]

имеет тип
a->[a]

т.е. преобразует значение типа a в список значений типа a.
my_func2 x = (Integer 10):[x]

имеет тип
Expr -> [Expr]

т.е. ee тип является частным случаем типа первой функции.
my_func my_func2
my_func:(my_func my_func2)

типы этих выражений
[Expr->[Expr]]
[Expr->[Expr]]

Заметьте мы смогли положить полиморфную функцию my_func в список специализированных функций. Обратное
было бы невозможно.
Данные примеры довольно просты, в реальных программах типы выражений и функций могут иметь весьма
значительный размер. Тот, кто видел шаблоны в С++ поймет о чем я говорю. Слава богу, в случае с ФЯ
программист не обязан переписывать километровые объявления типов раз за разом. Всю эту тяжелую работу
берет на себя компилятор. Более того, он выводит для каждой функции максимально общий (самый
полиморфный) из всех возможных типов. В принципе, вы можете вообще забыть о них и даже не знать точно
какой тип имеет ваша любимая функция. Если вы сомневаетесь в возможностях компилятора, то смею вас заверить,
что за всем этим стоит особая теория (что в случае ФЯ неудивительно), где строго доказывается возможность
вывода самого общего типа в любой ситуации, где это вообще возможно. Тем не
менее рекомендуется указывать типы по крайней мере у основных функций с тем,
чтобы повысить читаемость программы и облегчить работу компилятору. Иногда, в
сложных случаях, явное указание типа становится необходимостью, поэтому важно
знать, как выглядят объявления типов и уметь указывать из самому.
Остается добавить, что отдельные ФЯ расширяют стандартную систему типов разными способами. Например, в
OCaml добавлены классы, а в Haskell'e существуют классы типов, которые чем-то похожи на интерфейсы в ООП
языках.

Сравнение с образцом (pattern matching)
Поскольку в ФЯ широко используются сложные типы данных, для эффективной работы с ними существуют
мощные инструменты, а именно сравнение с образцом. Суть данного метода заключается в том, что мы
указываем некоторый каркас предполагаемого значения (образец), а программа пытается подогнать под этот
образец полученное значение. Например в этом примере
case list of
    head:tail -> ...
  | [] -> ...

мы пытаемся сравнить список list с двумя образцами head:tail и []. Если список не пустой, то сработает
первый образец, при этом head будет равен первому элементу списка, а в tail будет сохранен его хвост.
Если же список пустой, то сработает второй образец. Сложность образцов неограничена, вы можете использовать
для их создания все методы, с помощью которых можно создавать данные. Например в данном примере
case expr of
   Assign (Var my_var) (Func my_func [(Str "str"),(Integer 10)]) -> ...

если expr имеет указанную структуру, то my_var будет равен имени переменной, my_func будет равен
Var some_string. Заметим, что в образце можно указывать не только переменные, которые в случае
успешного сравнения будут связаны с частями сложного типа, но и константы.

Карринг
Одна из первых деталей, которая бросается в глаза человеку, привыкшему к императивным языкам
программирования, когда он видит функциональную программу, это отсутствие скобок вокруг параметров при
объявлении функций:
my_func a b c = ...
Это так называемая карринговая форма записи, которая получила свое название от имени Карри, который
первый указал на преимущества, которые она дает в ФЯП. В самом деле, поскольку в ФЯП функции и данные
равноправны, при такой записи параметров появляется ценная возможность использовать частичное определение
функций. Рассмотрим, например, функцию сложения двух чисел
add a b = a + b

Имея эту функцию мы можем создать новые функции типа
inc x = add 1 x
add10 x = add 10 x

первая из которых увеличивает свой аргумент на 1, а вторая на 10. Разница с обычным вызовом более
общей подфункции с некоторыми фиксированными аргументами заключается в том, что функция add 1 будет
частично вычислена один раз и при дальнейших вызовах перевычислятся не будет. В данном простом примере
это врядли приведет к существенному сокращению вычислений, однако, в более сложных случаях, выгода может
быть значительной. Дополнительно устраняется необходимость отдельного объявления специализированных
функций, что было бы неизбежно в случае обычной формы записи.

Функции высшего порядка (higher order functions)
Это функции, которые могут принимать в качестве аргумента и возвращать другие функции. Такие функции
повсеместно используются в ФЯП. Одной из классических функций такого рода является функция map, которая
принимает в качестве аргументов список элементов и функцию, которая преобразует эти элементы и возвращает
список с преобразоваными элементами. Вот как выглядит ее объявление
map f (head:tail) = (f head):(map f tail)
map f [] = []

Если мы объявим f как
f x = x*2

И применим map к f и списку [1,2,3], то получим список [2,4,6].

Ленивые вычисления
Как уже было сказано ранее, ФЯ делятся на строгие и нестрогие. Нестрогие языки
еше называют ленивыми. Это значит, что реальные вычисления в них откладываются
до того момента, когда они действительно становятся необходимы. На вопрос о том
насколько полезны ленивые вычисления нельзя дать однозначного ответа. В одних
случаях ленивость позволяет уменьшить количество вычислений и использовать
ленивые структуры данных типа бесконечных списков, а в других она становится
проблемой, когда память забивается недовычисленными выражениями, о которых
пока неизвестно, нужно их вычислять или нет. Такая ситуация возникает,
например, в LL(inf) парсере — парсере с произвольным заглядыванием вперед.
Для борьбы с лишней ленивостью применяются различные средства — форсирование
вычислений, специальные методы программирования типа CPS, строгие поля у типов
данных и т.п. Программист имеет возможность найти слабые места в своей
программе с помощью специальных инструментов и устранить их убрав, например,
ленивые вычисления там, где они не нужны.


16.10.04 22:19: Перенесено модератором из 'Философия программирования' — AndrewVK
Re: ФП: вводная статья
От: FR  
Дата: 27.09.04 15:58
Оценка:
Здравствуйте, Quintanar, Вы писали:

У меня такой вопрос какие задачи ложатся на ФЯ лучше чем на ИЯ. Просто из своего опыта и из тех веток где была задача с простыми числами, у меня сложилось впечатление что даже многие математические задачи проще решаются ИЯ, например у той же задачи про решето Эратосфена сишная реализация намного прозрачнее и ближе к описанию алгоритма на естественном языке.
Re: ФП: вводная статья
От: little_alex  
Дата: 27.09.04 16:21
Оценка: 8 (1)
Здравствуйте, Quintanar, Вы писали:



Q>Чистые ФЯ

Чистый ФЯ — язык в котором единственным результатом работы любой функции является возвращяемое значение.То есть максимально близко к математическому аналогу — функция это отображение множества входных
параметров в выходной.Результат функции не зависит от того когда эта фунция выполняется.Более того различные части одной функции могут быть вычеслены в разное время например result=f1(f2(A,B),f3(C,D))
Может быть вычислена так
A->C->D->B->f2->f3->f1

Это обстоятельсто усложняет отладку программ
Отсюда следут отсутствие глобальных переменных.Так как не одна ф-ия не может их изменить и не может от них зависить.С этим же связано отсутствие операции изменения переменной.



Q>Вызов по имени в целом более выгоден,

Спорно сам пишешь ниже.Выгодно когда то что нужно вычислить достатчно мало (занимает мало памяти для описания)
а вычисления достаточно долгие например 1000000000000! и не выгодно когда вычисленный результат во много раз меньше чем исходный.Например размер дерева или списка — проще сразу получить размер и удалить саму структуру(если она не используется далее) чем хранить ее до последнего

Q>Языки поддерживающие вызов по значению называются строгими, те, что поддерживают вызов по имени,

Q>называются нестрогими. Haskell нестрогий язык, а SML и OCaml строгие.
И Haskell и Ocaml поддерживают оба способа.Просто по умолчанию поведение Haskell нестрогое а OCaml строгое.

Q> Основным типом ФЯ можно назвать список

Основным типом ФЯ Haskell является алгебраический тип данных.Близкий аналог в ИЯ это enum(C).
Списки и кортежи является частным случаем.

2.4 Built-in Types Are Not Special
Earlier we introduced several "built-in" types such as lists, tuples, integers, and characters. We have also shown how new user-defined types can be defined. Aside from special syntax, are the built-in types in any way more special than the user-defined ones? The answer is no. The special syntax is for convenience and for consistency with historical convention, but has no semantic consequences.

We can emphasize this point by considering what the type declarations would look like for these built-in types if in fact we were allowed to use the special syntax in defining them. For example, the Char type might be written as:

data Char = 'a' | 'b' | 'c' | ... -- This is not valid
| 'A' | 'B' | 'C' | ... -- Haskell code!
| '1' | '2' | '3' | ...
...

These constructor names are not syntactically valid; to fix them we would have to write something like:

data Char = Ca | Cb | Cc | ...
| CA | CB | CC | ...
| C1 | C2 | C3 | ...
...

Even though these constructors are more concise, they are quite unconventional for representing characters.

In any case, writing "pseudo-Haskell" code in this way helps us to see through the special syntax. We see now that Char is just an enumerated type consisting of a large number of nullary constructors. Thinking of Char in this way makes it clear that we can pattern-match against characters in function definitions, just as we would expect to be able to do so for any of a type's constructors.

[This example also demonstrates the use of comments in Haskell; the characters -- and all subsequent characters to the end of the line are ignored. Haskell also permits nested comments which have the form {-...-} and can appear anywhere (§2.2).]

Similarly, we could define Int (fixed precision integers) and Integer by:

data Int = -65532 | ... | -1 | 0 | 1 | ... | 65532 -- more pseudo-code
data Integer = ... -2 | -1 | 0 | 1 | 2 ...

where -65532 and 65532, say, are the maximum and minimum fixed precision integers for a given implementation. Int is a much larger enumeration than Char, but it's still finite! In contrast, the pseudo-code for Integer is intended to convey an infinite enumeration.

Tuples are also easy to define playing this game:

data (a,b) = (a,b) -- more pseudo-code
data (a,b,c) = (a,b,c)
data (a,b,c,d) = (a,b,c,d)
. .
. .
. .

Each declaration above defines a tuple type of a particular length, with (...) playing a role in both the expression syntax (as data constructor) and type-expression syntax (as type constructor). The vertical dots after the last declaration are intended to convey an infinite number of such declarations, reflecting the fact that tuples of all lengths are allowed in Haskell.

Lists are also easily handled, and more interestingly, they are recursive:

data [a] = [] | a : [a] -- more pseudo-code

We can now see clearly what we described about lists earlier: [] is the empty list, and : is the infix list constructor; thus [1,2,3] must be equivalent to the list 1:2:3:[]. (: is right associative.) The type of [] is [a], and the type of : is a->[a]->[a].

[The way ":" is defined here is actually legal syntax---infix constructors are permitted in data declarations, and are distinguished from infix operators (for pattern-matching purposes) by the fact that they must begin with a ":" (a property trivially satisfied by ":").]

At this point the reader should note carefully the differences between tuples and lists, which the above definitions make abundantly clear. In particular, note the recursive nature of the list type whose elements are homogeneous and of arbitrary length, and the non-recursive nature of a (particular) tuple type whose elements are heterogeneous and of fixed length. The typing rules for tuples and lists should now also be clear:

For (e1,e2,...,en), n>=2, if ti is the type of ei, then the type of the tuple is (t1,t2,...,tn).

For [e1,e2,...,en], n>=0, each ei must have the same type t, and the type of the list is [t].

(отсюда)
Или по другому список
data List a = Only a | Pair a (List a)
кортеж
data C1 a = C1 a
data C2 a b = C2 a b
...

Списки — это основной тип данных для Lisp


Q>Карринг

Предположим есть функция — сложение.
Можно рассматривать ее как функцию от 2 аргументов int и возвращающюю int
А можно как функцию 1-ого числа x возвращающюю другую функцию 1-ого аргумента f ,такую что f y =x+y — это карринг или частичное применение функции
Re[2]: ФП: вводная статья
От: Nick_ Россия  
Дата: 27.09.04 16:26
Оценка: +1
Здравствуйте, FR, Вы писали:

FR>У меня такой вопрос какие задачи ложатся на ФЯ лучше чем на ИЯ. Просто из своего опыта и из тех веток где была задача с простыми числами, у меня сложилось впечатление что даже многие математические задачи проще решаются ИЯ, например у той же задачи про решето Эратосфена сишная реализация намного прозрачнее и ближе к описанию алгоритма на естественном языке.


Хорошо, давайте сравним.

Быстрая сортировка на ФЯ:

qsort []     = []
qsort (x:xs) = qsort elts_lt_x ++ [x] ++ qsort elts_greq_x
                 where
                   elts_lt_x   = [y | y <- xs, y < x]
                   elts_greq_x = [y | y <- xs, y >= x]


Решето эрастофена на ФЯ:

ld n = ldf 2 n

divides d n = rem n d == 0

ldf k n | divides k n = k
        | k^2 > n     = n
        | otherwise   = ldf (k+1) n

prime n | n < 1     = error "not a positive integer"
        | n == 1    = False
        | otherwise = ld n == n


Императивные аналоги, я думаю, Вы себе представляете.

На функциональных языках многое записывается проще. Проблема же состоит только в том, что современные компиляторы функциональных языков не могут сгененрировать эффективный код. Но это не принципиальная проблема. Рано или позно появятся эффективные компиляторы. Еще одна проблема функциональных языков — это убогая семантика массивов. Но и она, скорее всего, тоже окажется в прошлом.
Идея любого языка программирования заключается в том, что бы переложить максимальное количество рутинной работы на компьютер. А для этого задача должна описываться на максимально возможном для машины уровне абстракции. Пока что для этого ничего лучше функционального и логического подхода не придумано.
Re[2]: ФП: вводная статья
От: little_alex  
Дата: 27.09.04 16:34
Оценка:
Здравствуйте, FR, Вы писали:

FR>У меня такой вопрос какие задачи ложатся на ФЯ лучше чем на ИЯ. Просто из своего опыта и из тех веток где была задача с простыми числами, у меня сложилось впечатление что даже многие математические задачи проще решаются ИЯ, например у той же задачи про решето Эратосфена сишная реализация намного прозрачнее и ближе к описанию алгоритма на естественном языке.


Как минимум
1.Для манипуляции сложных древовидных структур (попробуй реализовать AVL или RB дерево)- синтаксические деревья и алгебраические выражения — например встроенный язык в программе Mathematica имеет много функциональных конструкций.А ее бесплатный аналог Maxima написан на lisp.
integral x^n,dz =if z==x then x^(n+1)/(n+1) else x^n*z
integral a*x+b = a*x*x+b*x ...
Вообщем pattern matching -та черта ФЯ полезность которой не вызывает сомнений
2.Для реализации алгоритмов легко распадающиеся не составные части
3.Где активно применяется рекурсия например LL — разбор
Re[3]: ФП: вводная статья
От: little_alex  
Дата: 27.09.04 16:37
Оценка:
N_> Еще одна проблема функциональных языков — это убогая семантика массивов. Но и она, скорее всего, тоже окажется в прошлом.
Вообще-то верно,но посмотри в сторону Haskell — Array не так уж и плох.Плохо массивы вписываюся в pattern matching вот в чем проблема.
Re[3]: ФП: вводная статья
От: hrg Россия  
Дата: 27.09.04 16:50
Оценка:
Nick_ -> "Re[2]: ФП: вводная статья" :

FR>> математические задачи проще решаются ИЯ, например у той же задачи

FR>> про решето Эратосфена сишная реализация намного прозрачнее и ближе
FR>> к описанию алгоритма на естественном языке.

N> Хорошо, давайте сравним.


N> Быстрая сортировка на ФЯ:


N> Решето эрастофена на ФЯ:


Все клева.... только часто ли необходимо изобретать велосипеды и писать
qsort & ero_filter?
Мне вот интересно, как с помощью ФП пишется бизнес- логика? Как описать
поведение не_знаю_как_будет_в_ФП_объекты? Такие вот банальные
сермяжно-прагматические вопросы

Yury Kopyl aka hrg | http://id.totem.ru |
"Если ты плюнешь на коллектив — коллектив утрется,
но если коллектив плюнет на тебя — ты утонешь" (С)Баралгин
Posted via RSDN NNTP Server 1.9 gamma
Re[4]: ФП: вводная статья
От: Nick_ Россия  
Дата: 27.09.04 16:57
Оценка:
Здравствуйте, little_alex, Вы писали:

_>Вообще-то верно,но посмотри в сторону Haskell — Array не так уж и плох.Плохо массивы вписываюся в pattern matching вот в чем проблема.


Array сделан с помощью монад, чтобы избежать копирования. По моему, это глупо. И пользоваться такими массивами практически невозможно. Как, например, записать независимое обновление двух ячеек массива, что бы компилятор мог это распараллелить? А ведь без этого нельзя сделать эффективную обработку массивов с использованием SIMD инструкций...
Хотя у меня в этом опыта практически нет. Надо будет попробовать реализовать какую-нибудь задачу с обработкой матриц чтобы проверить насколько я прав.
Re[4]: ФП: вводная статья
От: Nick_ Россия  
Дата: 27.09.04 17:09
Оценка: 4 (1)
Здравствуйте, hrg, Вы писали:
hrg>Все клева.... только часто ли необходимо изобретать велосипеды и писать
hrg>qsort & ero_filter?
hrg>Мне вот интересно, как с помощью ФП пишется бизнес- логика? Как описать
hrg>поведение не_знаю_как_будет_в_ФП_объекты? Такие вот банальные
hrg>сермяжно-прагматические вопросы

Бизнес-логика пишется абсолютно так же как и моделируются конечные автоматы.
Поведение (последовательное изменение состояние обьекта) обычно описывается функцией которая по исходному состоянию выдает следующее. А для того что бы гарантировать то, что объект при этом не копируется используются монады (я про haskell). Кстати, для ввода-вывода монады нужны только для того, что бы гарантировать последовательную работу с устройством ввода-вывода, что исходное состояние обьекта нигде не будет использовано два раза. Иначе компилятор не поймет в каком месте использовать объект раньше.
Я примеры приводить не буду, потому как пора уже домой. Но может кто-нибудь приведет.
Re[4]: ФП: вводная статья
От: Gaperton http://gaperton.livejournal.com
Дата: 27.09.04 17:16
Оценка:
Здравствуйте, little_alex, Вы писали:

N_>> Еще одна проблема функциональных языков — это убогая семантика массивов. Но и она, скорее всего, тоже окажется в прошлом.

_>Вообще-то верно,но посмотри в сторону Haskell — Array не так уж и плох.Плохо массивы вписываюся в pattern matching вот в чем проблема.

import StdClass, StdInt, _SystemArray

Swap i j a =:{ [i] = ai, [j] = aj } = { a & [i] = aj, [j] = ai }

Start:: .{Int}
Start = Swap 3 7 { x \\ x <- [1..10] }

Clean. Меняем местами 3-е и 7-е элементы массива целых чисел от 1 до 10. Изменение деструктивно, массив не копируется. Применяем pattern matching и array comprehensions.
Re[3]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.09.04 18:25
Оценка: 1 (1)
Здравствуйте, Nick_, Вы писали:

N_>Быстрая сортировка на ФЯ:


N_>
N_>qsort []     = []
N_>qsort (x:xs) = qsort elts_lt_x ++ [x] ++ qsort elts_greq_x
N_>                 where
N_>                   elts_lt_x   = [y | y <- xs, y < x]
N_>                   elts_greq_x = [y | y <- xs, y >= x]
N_>


Это не быстрая сортировка. Это медленная. Да еще и алгоритм перевран.

Ты классический реализуй. Так чтобы для перекидки брался средний элемент. И что бы перекидка была "по месту" (без создания копий). Вот тогда и объем кода сравним. Ну, и переменные не стоит однобуквенные делать.

Насколько я понял, ОКамл как раз и работает более менее быстро из-за того, что в нем введены императивные средства, на которых и реализованы базовые алгоритмы. И по мне, так очень разумное решение. Вот еще бы более приличный императивный синтаксис. Да и вообще сделать бы синтаксис по ближе к мэйстримным С-подобным языкам. Было бы куда проще осваивать.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.09.04 18:25
Оценка:
Здравствуйте, little_alex, Вы писали:

_>1.Для манипуляции сложных древовидных структур (попробуй реализовать AVL или RB дерево)- синтаксические деревья и алгебраические выражения — например встроенный язык в программе Mathematica имеет много функциональных конструкций.А ее бесплатный аналог Maxima написан на lisp.


И почему-то все это с успехом делается на ИЯ.

_>Вообщем pattern matching -та черта ФЯ полезность которой не вызывает сомнений


+1

_>2.Для реализации алгоритмов легко распадающиеся не составные части


Для этого нужна поддержка компилятра вот и все. Тот же С++ прекрасно распараллеливается спец. средствами (например, от Интел).

_>3.Где активно применяется рекурсия например LL — разбор


Но опчему-то для постраения парсеров в ФЯ все равно создают постоители парсеров (вроде Яка/Лекса). А ЛЛ(1) легко делается методом рекурсивного спуска на любом ИЯ.

Так что приемущества именно в декларативности и фичах вроде патерн-матчинга и функциях высшего порядка.

Многое же выдаваемое за достоинство ФЯ на самом деле является всего лишь фичами конкретных языков и без проблем может быть реализовано (да и реализуется) на ИЯ.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: ФП: вводная статья
От: FR  
Дата: 27.09.04 19:14
Оценка: 16 (1)
Здравствуйте, Nick_, Вы писали:

N_>Быстрая сортировка на ФЯ:


N_>
N_>qsort []     = []
N_>qsort (x:xs) = qsort elts_lt_x ++ [x] ++ qsort elts_greq_x
N_>                 where
N_>                   elts_lt_x   = [y | y <- xs, y < x]
N_>                   elts_greq_x = [y | y <- xs, y >= x]
N_>



ФЯ тут ни причем, это будет также просто и на императивном языке с
хорошей реализацией встроенных списков, например на питоне:

def qsort(aList): 
        if not aList: 
                return [] 
        ltList=[y for y in aList[1:] if y<aList[0]] 
        gtList=[y for y in aList[1:] if y>=aList[0]] 
        return qsort(ltList)+[aList[0]]+qsort(gtList)


N_>Решето эрастофена на ФЯ:


N_>
N_>ld n = ldf 2 n

N_>divides d n = rem n d == 0

N_>ldf k n | divides k n = k
N_>        | k^2 > n     = n
N_>        | otherwise   = ldf (k+1) n

N_>prime n | n < 1     = error "not a positive integer"
N_>        | n == 1    = False
N_>        | otherwise = ld n == n
N_>


это не решето эратосфена, это алгоритм в лоб (если я конечно не запутался в синтаксисе)

N_>Императивные аналоги, я думаю, Вы себе представляете.


зависит от языка


N_>На функциональных языках многое записывается проще. Проблема же состоит только в том, что современные компиляторы функциональных языков не могут сгененрировать эффективный код. Но это не принципиальная проблема. Рано или позно появятся эффективные компиляторы. Еще одна проблема функциональных языков — это убогая семантика массивов. Но и она, скорее всего, тоже окажется в прошлом.


насколько я понял из чтения документации по ocaml там уже есть обычные императивные
массивы.

N_>Идея любого языка программирования заключается в том, что бы переложить максимальное количество рутинной работы на компьютер. А для этого задача должна описываться на максимально возможном для машины уровне абстракции. Пока что для этого ничего лучше функционального и логического подхода не придумано.


Мне пока больше понравился импреративно-декларативный стиль питона. Не нравится только его динамическая типизация и то что интерпретатор(хотя если psyco доведут до ума то скорость будет очень хорошая).
Re[3]: ФП: вводная статья
От: WolfHound  
Дата: 27.09.04 19:18
Оценка:
Здравствуйте, Nick_, Вы писали:

N_>Хорошо, давайте сравним.

Ну давай попробуем
N_>Быстрая сортировка на ФЯ:
ну эту "быструю" сортировку уже со всех сторон обсасали в соседнем флейме.

N_>Решето эрастофена на ФЯ:

Я не спец в ФЯ но из того что мне удалось понять это не решето эратосфена, а тупейшая проверка одного числа на простоту.
N_>Императивные аналоги, я думаю, Вы себе представляете.
И переводится на С++ дословно
bool divides(int k, int n)
{
    return n%k==0;
}
int ldf(int k, int n)
{
    if(divides(k, n))   return k;
    if(k*k>n)           return n;
    return ldf(k+1, n);
}
int ld(int n)
{
    return ldf(2, n);
}
bool prime(int n)
{
    if(n<1)     throw "not a positive integer";
    if(n==1)    return false;
    return ld(n)==n;
}

что эквивалентно
bool prime(int n)
{
    if(n<1)     throw "not a positive integer";
    if(n==1)    return false;
    for(int k=2;k*k<=n;++k)
        if(n%k==0)
            return false;
    return true;
}

А вот простейшая реализация решита Эратосфена
int main()
{
    size_t size=100;
    std::vector<bool> is_prime(size, true);//помечаем все числа как простые
    for(size_t i=2;i<size;++i)//ищем очередное не вычеркнутое число
        if(is_prime[i])
        {
            //i очередное простое число
            for(size_t n=i+i;n<size;n+=i)//вычеркиваем все числа кратные данному числу
                is_prime[n]=false;
        }
}

Находит все простые числа меньше заданного. Изобрази этот алгоритм на функциональном языке, а мы посмеемся...

N_>На функциональных языках многое записывается проще.

Я бы сказал кое что
N_>Проблема же состоит только в том, что современные компиляторы функциональных языков не могут сгененрировать эффективный код.
N_>Но это не принципиальная проблема.
А! Ну-ну... интересно когда появится компилятор который будет способен превратить то что написал ты в решито Эратосфена... Тут настоящий AI нужен.
N_>Рано или позно появятся эффективные компиляторы.
Ой не скоро если вобще появятся... Алгоритм преобразовать это вам не рекурсию развернуть...
N_>Идея любого языка программирования заключается в том, что бы переложить максимальное количество рутинной работы на компьютер. А для этого задача должна описываться на максимально возможном для машины уровне абстракции.
Кто бы спорил.
N_>Пока что для этого ничего лучше функционального и логического подхода не придумано.
А вот это уже спорно.
... << RSDN@Home 1.1.4 rev. 185 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[4]: ФП: вводная статья
От: Lloyd Россия  
Дата: 27.09.04 19:42
Оценка: :)
Здравствуйте, VladD2, Вы писали:

VD>Это не быстрая сортировка. Это медленная. Да еще и алгоритм перевран.


VD>Ты классический реализуй. Так чтобы для перекидки брался средний элемент.


Удивительно, но у Кнута тогда он тоже перевран.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re[4]: ФП: вводная статья
От: Nick_ Россия  
Дата: 28.09.04 06:06
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>А вот простейшая реализация решита Эратосфена

WH>
WH>int main()
WH>{
WH>    size_t size=100;
WH>    std::vector<bool> is_prime(size, true);//помечаем все числа как простые
WH>    for(size_t i=2;i<size;++i)//ищем очередное не вычеркнутое число
WH>        if(is_prime[i])
WH>        {
WH>            //i очередное простое число
WH>            for(size_t n=i+i;n<size;n+=i)//вычеркиваем все числа кратные данному числу
WH>                is_prime[n]=false;
WH>        }
WH>}
WH>

WH>Находит все простые числа меньше заданного. Изобрази этот алгоритм на функциональном языке, а мы посмеемся...


main = putStr (show (filter primes [1..100]))


primes определен как я писал выше.
Re[4]: ФП: вводная статья
От: Nick_ Россия  
Дата: 28.09.04 06:09
Оценка: -1 :)
Здравствуйте, VladD2, Вы писали:

VD>И почему-то все это с успехом делается на ИЯ.


VD>Для этого нужна поддержка компилятра вот и все. Тот же С++ прекрасно распараллеливается спец. средствами (например, от Интел).


VD>Но опчему-то для постраения парсеров в ФЯ все равно создают постоители парсеров (вроде Яка/Лекса). А ЛЛ(1) легко делается методом рекурсивного спуска на любом ИЯ.


VD>Так что приемущества именно в декларативности и фичах вроде патерн-матчинга и функциях высшего порядка.


VD>Многое же выдаваемое за достоинство ФЯ на самом деле является всего лишь фичами конкретных языков и без проблем может быть реализовано (да и реализуется) на ИЯ.


Голодная кума Лиса залезла в сад,
В нем винограду кисти рделись.
У кумушки глаза и зубы разгорелись;
А кисти сочные как яхонты горят;
Лишь то беда, висят они высоко:
Отколь и как она к ним ни зайдет,
Хоть видит око,
Да зуб неймет.
Пробившись попусту час целой,
Пошла и говорит с досадою: "Ну, что ж!
На взгляд-то он хорош,
Да зелен — ягодки нет зрелой:
Тотчас оскомину набьешь".
Re[5]: ФП: вводная статья
От: FR  
Дата: 28.09.04 06:57
Оценка:
Здравствуйте, Nick_, Вы писали:

WH>>Находит все простые числа меньше заданного. Изобрази этот алгоритм на функциональном языке, а мы посмеемся...



N_>
N_>main = putStr (show (filter primes [1..100]))
N_>


N_>primes определен как я писал выше.


нет на самом деле уже смешно, про эффективность конечно вообще забываем, но ладно но различий с ИЯ тут тоже нет на C++ это тоже одна строка с готовой то функцией primes.
Re[5]: ФП: вводная статья
От: FR  
Дата: 28.09.04 06:57
Оценка:
Здравствуйте, Nick_, Вы писали:

Насчет басни, лиса все-таки добралась до винограда, но не съедобный он для нее, вот и спрашивает как его вкуснее приготовить.
Re[4]: ФП: вводная статья
От: Gaperton http://gaperton.livejournal.com
Дата: 28.09.04 07:11
Оценка:
Здравствуйте, FR, Вы писали:

FR>ФЯ тут ни причем, это будет также просто и на императивном языке с

FR>хорошей реализацией встроенных списков, например на питоне:
Питон позволяет писать в функциональном стиле, было-бы желание. Что мы и видим в твоем примере. Так что ФЯ здесь причем — откуда, ты думаешь, в питоне взялись list comprehensions?

FR>
FR>def qsort(aList): 
FR>        if not aList: 
FR>                return [] 
FR>        ltList=[y for y in aList[1:] if y<aList[0]] 
FR>        gtList=[y for y in aList[1:] if y>=aList[0]] 
FR>        return qsort(ltList)+[aList[0]]+qsort(gtList) 
FR>
Re[5]: ФП: вводная статья
От: FR  
Дата: 28.09.04 07:33
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Здравствуйте, FR, Вы писали:


FR>>ФЯ тут ни причем, это будет также просто и на императивном языке с

FR>>хорошей реализацией встроенных списков, например на питоне:
G>Питон позволяет писать в функциональном стиле, было-бы желание. Что мы и видим в твоем примере. Так что ФЯ здесь причем — откуда, ты думаешь, в питоне взялись list comprehensions?

Извини, но в этом примере я не вижу ни грамма функциональности, наоборот это пример применения декларативно-императивных средств которые активно продвигаются создателями пимтона в последних версиях. А списки по моему безразличны к ФЯ и ИЯ (и к ЛЯ в прологе списки не хуже лисповских), и там и там их можно красиво реализовать,
Re[6]: ФП: вводная статья
От: Gaperton http://gaperton.livejournal.com
Дата: 28.09.04 07:36
Оценка:
Здравствуйте, FR, Вы писали:

FR>Здравствуйте, Nick_, Вы писали:


WH>>>Находит все простые числа меньше заданного. Изобрази этот алгоритм на функциональном языке, а мы посмеемся...



N_>>
N_>>main = putStr (show (filter primes [1..100]))
N_>>


N_>>primes определен как я писал выше.


FR>нет на самом деле уже смешно, про эффективность конечно вообще забываем, но ладно но различий с ИЯ тут тоже нет на C++ это тоже одна строка с готовой то функцией primes.


Да, а еще на С++ 2+2 выглядит совершенно так же, как на хаскель. Сразу видно — у языков много общего — да одно и тоже практически.

На, посмотри, как мы забиваем на эффективность. И найди здесь свой питон (подсказка: ищи в конце), который проиграл вдвое даже динамически типизированному Erlang-у. А если обратить внимание, что в данный момент реализация на haskell занимает в рейтинге первое место, обогнав gcc, то просто обхохочешься.

Советую обратить внимание на позиции haskell и clean сравнительно с gcc — это чисто функциональные языки без императивных расширений. Если кого нибудь расстраивает позиция gcc или java — текст прог можно посмтореть на сайте, изменить, и отправить туда. Это открытое соревнование, так что я думаю, что Haskell недолго будет занимать первую позицию. Это и в самом деле странно.

Sieve of Eratosthenes
(showing CPU minus startup)
[sort] [sort] [sort]
Source Code CPU (sec) Mem (KB) Lines Code Log
ghc 0.11 1032 11 log out
sbcl 0.14 6256 12 log out
gcc 0.14 264 19 log out
cmucl 0.15 4908 12 log out
oberon2 0.15 1096 28 log out
se 0.15 360 57 log out
stalin 0.16 684 20 log out
ocaml 0.16 488 17 log out
bigloo 0.17 888 24 log out
nice 0.17 10340 15 log out
gcj 0.18 10208 15 log out
g++ 0.20 760 19 log out
mlton 0.21 588 39 log out
clean 0.23 440 17 log out
java 0.29 8828 15 log out
kaffe 0.31 6000 15 log out
gwydion 0.33 2300 27 log out
gnat 0.51 1016 33 log out
smlnj 0.62 1116 34 log out
chicken 0.65 1088 23 log out
gforth 1.02 756 33 log out
mercury 7.13 8564 32 log out
sablevm 7.71 2832 15 log out
ocamlb 7.72 696 17 log out
hipe 7.76 4992 18 log out
oz 7.84 4292 19 log out
rep 8.79 1192 18 log out
gij 8.88 10344 15 log out
erlang 9.44 4548 18 log out
lua 10.83 932 21 log out
pike 13.57 2996 15 log out
slang 14.66 844 14 log out
xemacs 14.89 8200 16 log out
gst 15.57 4140 15 log out
python 16.64 2112 18 log out
Re[5]: ФП: вводная статья
От: INTP_mihoshi Россия  
Дата: 28.09.04 07:38
Оценка: +1
Здравствуйте, Nick_, Вы писали:

VD>>Многое же выдаваемое за достоинство ФЯ на самом деле является всего лишь фичами конкретных языков и без проблем может быть реализовано (да и реализуется) на ИЯ.

+1

N_>Голодная кума Лиса залезла в сад,

N_> В нем винограду кисти рделись...
Не нада. А то будет как в прошлой ветке...
Re[6]: ФП: вводная статья
От: Gaperton http://gaperton.livejournal.com
Дата: 28.09.04 07:44
Оценка:
Здравствуйте, FR, Вы писали:

FR>Здравствуйте, Gaperton, Вы писали:


G>>Здравствуйте, FR, Вы писали:


FR>>>ФЯ тут ни причем, это будет также просто и на императивном языке с

FR>>>хорошей реализацией встроенных списков, например на питоне:
G>>Питон позволяет писать в функциональном стиле, было-бы желание. Что мы и видим в твоем примере. Так что ФЯ здесь причем — откуда, ты думаешь, в питоне взялись list comprehensions?

FR>Извини, но в этом примере я не вижу ни грамма функциональности, наоборот это пример применения декларативно-императивных средств которые активно продвигаются создателями пимтона в последних версиях.


Я вот в твоем коде не вижу императивности. Причем совсем. Ты бы для начала почитал где-нибудь, что такое "функциональность", например в comp.lang.functional FAQ. Но впрочем, что это я к тебе пристаю? Не видишь — и хорошо.

FR> А списки по моему безразличны к ФЯ и ИЯ (и к ЛЯ в прологе списки не хуже лисповских), и там и там их можно красиво реализовать,

Конечно можно. Кто-то здесь утверждал обратное?
Re[6]: ФП: вводная статья
От: INTP_mihoshi Россия  
Дата: 28.09.04 08:08
Оценка:
Здравствуйте, FR, Вы писали:

Эратосфен — явно итеративный алгоритм, так что чудес от функционального cтиля в нем не найти.
Так что функциональный аналог выглядит практически один-в один.

let addprime arr n size = fold (fun a i -> set a (i*n)) [2..(size/n)] arr
let sieve size = fold (fun a i -> if get a i then addprime a i size else a) [2..size] (make size true)


На выходе sieve массив с true для простых и false для составных.

fold fun list accum — переводится примерно как foreach value in list (accum := fun accum value).
Например, fold (+) [1..10] 0 равно 55.

get a i — возвращает значение iго элемента массива a
set a i v — массив, в ктоором iый элемент установлен в v, остальные — так же, как в a
make size v — создает массив размером s забитый значениями v
Re[7]: ФП: вводная статья
От: FR  
Дата: 28.09.04 08:28
Оценка:
Здравствуйте, Gaperton, Вы писали:

.

FR>>нет на самом деле уже смешно, про эффективность конечно вообще забываем, но ладно но различий с ИЯ тут тоже нет на C++ это тоже одна строка с готовой то функцией primes.


G>Да, а еще на С++ 2+2 выглядит совершенно так же, как на хаскель. Сразу видно — у языков много общего — да одно и тоже практически.


Практически везде функциональчики утверждают, что программы на функциональных языках короче и легче для понимания чем на императивных, но чем дальше я пытаюсь изучать эти языки тем меньше это вижу.

G>На, посмотри, как мы забиваем на эффективность. И найди здесь свой питон (подсказка: ищи в конце), который проиграл вдвое даже динамически типизированному Erlang-у. А если обратить внимание, что в данный момент реализация на haskell занимает в рейтинге первое место, обогнав gcc, то просто обхохочешься.


Не стоит так эмоционально реагировать. Под эффективностью я имел в виду только то что используется абсолютно тупейший алгоритм, и с таким алгоритмом это и на си выглядит красиво и коротко.
А по питону они в этом тесте смухлевали, JIT компилятор закоментировали
Re[7]: ФП: вводная статья
От: FR  
Дата: 28.09.04 08:28
Оценка:
Здравствуйте, Gaperton, Вы писали:


FR>>Извини, но в этом примере я не вижу ни грамма функциональности, наоборот это пример применения декларативно-императивных средств которые активно продвигаются создателями пимтона в последних версиях.

G>
G>Я вот в твоем коде не вижу императивности. Причем совсем. Ты бы для начала почитал где-нибудь, что такое "функциональность", например в comp.lang.functional FAQ. Но впрочем, что это я к тебе пристаю? Не видишь — и хорошо.

то есть цикл for это теперь функциональный стиль? Спасибо не знал.

FR>> А списки по моему безразличны к ФЯ и ИЯ (и к ЛЯ в прологе списки не хуже лисповских), и там и там их можно красиво реализовать,

G>Конечно можно. Кто-то здесь утверждал обратное?

Подразумевал, когда приводил алгоритм сортировки на языке со встроенными списками.
Re[8]: ФП: вводная статья
От: Gaperton http://gaperton.livejournal.com
Дата: 28.09.04 09:14
Оценка:
Здравствуйте, FR, Вы писали:

FR>то есть цикл for это теперь функциональный стиль? Спасибо не знал.

Функциональный стиль это теперь, как и всегда, в первую очередь — отсутствие побочных эффектов, а не наличие рекурсии со встроенными списками или отсутствие слова for в языке. Не зачто, всегда пожалуйста .

Кстати, слепенький я наверно. Ну не вижу я цикла for в твоем коде. А вот list comprehensions вижу, как и отсутствие побочных эффектов.
def qsort(aList): 
        if not aList: 
                return [] 
        ltList=[y for y in aList[1:] if y<aList[0]] 
        gtList=[y for y in aList[1:] if y>=aList[0]] 
        return qsort(ltList)+[aList[0]]+qsort(gtList)


FR>>> А списки по моему безразличны к ФЯ и ИЯ (и к ЛЯ в прологе списки не хуже лисповских), и там и там их можно красиво реализовать,

G>>Конечно можно. Кто-то здесь утверждал обратное?
FR>Подразумевал, когда приводил алгоритм сортировки на языке со встроенными списками.
Откуда ты знаешь, что именно он подразумевал? Ментальное сканирование?

Что характерно, если ты добавишь в любой язык встроенные списки так, как это сделано в современных ФЯ, то на нем сразу станет удобно писать в функциональном стиле. Одного не понимаю, каким именно образом это порочит "светлую идею" ФЯ?
Re[4]: ФП: вводная статья
От: INTP_mihoshi Россия  
Дата: 28.09.04 09:35
Оценка:
Здравствуйте, VladD2, Вы писали:

_>>Вообщем pattern matching -та черта ФЯ полезность которой не вызывает сомнений

VD>+1

Опять же, является ли это чертой именно ФЯ...

_>>2.Для реализации алгоритмов легко распадающиеся не составные части

VD>Для этого нужна поддержка компилятра вот и все. Тот же С++ прекрасно распараллеливается спец. средствами (например, от Интел).

Поддержка компилятора и распараллеливания разруливание ручками под каждую кончигурацию машины?
Или ты хочешь сказать, что на C или C++ можно написать код, который компилятор сам эффективно распараллелит?

_>>3.Где активно применяется рекурсия например LL — разбор

VD>Но опчему-то для постраения парсеров в ФЯ все равно создают постоители парсеров (вроде Яка/Лекса).

Обычно на функциональных языках. Хотя бывают варианты. В Ocaml есть и чисто камшловый парсер, и парсер со вставками на C.


VD>Так что приемущества именно в декларативности и фичах вроде патерн-матчинга и функциях высшего порядка.

VD>Многое же выдаваемое за достоинство ФЯ на самом деле является всего лишь фичами конкретных языков и без проблем может быть реализовано (да и реализуется) на ИЯ.

Я бы сказал, функции высшего порядка и высокий уровень абстракции. Функциональные языки оперируют наиболее простыми единицами языка — значениями, множествами(т.е. типами) и отображениями (функциями). Все что нужно, ничего лишнего. На этом уровне инкапсуляция иполиморфизм получается гораздо лучше чем в ООП — программа состоит как правило из меньших и менее связанных элементов, чем программа в объектном стиле.
Re[5]: ФП: вводная статья
От: WolfHound  
Дата: 28.09.04 09:39
Оценка:
Здравствуйте, Nick_, Вы писали:

WH>>Находит все простые числа меньше заданного. Изобрази этот алгоритм на функциональном языке, а мы посмеемся...

N_>
N_>main = putStr (show (filter primes [1..100]))
N_>

N_>primes определен как я писал выше.
1)Всеравно кода получилось больше.
2)Давай сравним производительность на болие серьезном объеме. Думаю миллиарда будет достаточно
    unsigned x=1;
    timer_t timer;

    unsigned size=1000000000;
    std::vector<bool> is_prime(size, true);//помечаем все числа как простые
    for(unsigned i=2;i<size;++i)//ищем очередное не вычеркнутое число
        if(is_prime[i])
        {
            //i очередное простое число
            if(i>x)//иначе вывод становится ОЧЕНЬ узким местом
            {
                std::cout<<i<<" "<<timer.time()<<"\n";
                x<<=1;
            }
            for(unsigned n=i+i;n<size;n+=i)//вычеркиваем все числа кратные данному числу
                is_prime[n]=false;
        }
    std::cout<<timer.time()<<"\n";

2 0.259567
3 2.23898
5 3.56067
11 4.92444
17 5.60239
37 6.54752
67 7.292
131 8.47562
257 10.5407
521 14.3472
1031 19.2141
2053 24.9814
4099 30.7079
8209 36.4478
16411 42.7149
32771 49.6374
65537 56.8574
131101 63.8289
262147 70.5661
524309 76.7928
1048583 82.2505
2097169 87.0388
4194319 91.121
8388617 94.4375
16777259 96.9167
33554467 98.4748
67108879 99.433
134217757 100.051
268435459 100.865
536870923 102.164
104.226

В прочем можешь не напрягаться я и так знаю что твоя программа на ТАКИХ объемах просто сдохнет. Ибо ты использовал ТУПОЙ алгоритм.
Разберись с моей программой и попробуй реализовать МОЙ алгоритм на ФЯ.
ЗЫ Gaperton в соседнем флейме расписался
Автор: Gaperton
Дата: 13.09.04
в том что не может сделать алгоритм на ФЯ быстрее.
ЗЗЫ Все дело в том что сложность твоего алгоритма O(N*sqrt(N)). Сложность моего алгоритма мне лень считать но она около O(N*log(N)) к тому же у меня константа меньше.
... << RSDN@Home 1.1.4 rev. 185 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[6]: ФП: вводная статья
От: Gaperton http://gaperton.livejournal.com
Дата: 28.09.04 09:54
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>ЗЫ Gaperton в соседнем флейме расписался
Автор: Gaperton
Дата: 13.09.04
в том что не может сделать алгоритм на ФЯ быстрее.


Он расписался
Автор: Gaperton
Дата: 13.09.04
также в том, что заметил лучшую асимптотику твоего алгоритма но не хочет заниматься алгоритмической оптимизацией. Лень ему, понимаешь, и смысла в этом он не видит. Что ты сравнить хочешь, эффективность компиляторов, или что?
Re[9]: ФП: вводная статья
От: FR  
Дата: 28.09.04 09:58
Оценка:
Здравствуйте, Gaperton, Вы писали:


G>Кстати, слепенький я наверно. Ну не вижу я цикла for в твоем коде. А вот list comprehensions вижу, как и отсутствие побочных эффектов.


перевожу для слабовидящих:
ltList=[y for y in aList[1:] if y<aList[0]]


равносильно
ltList = []
for y in aList[1:] :
    if y<aList[0]: ltList.append(y)


просто ты не хочешь признать что императивный язык тоже может быть декларативным.

FR>>>> А списки по моему безразличны к ФЯ и ИЯ (и к ЛЯ в прологе списки не хуже лисповских), и там и там их можно красиво реализовать,

G>>>Конечно можно. Кто-то здесь утверждал обратное?
FR>>Подразумевал, когда приводил алгоритм сортировки на языке со встроенными списками.
G>Откуда ты знаешь, что именно он подразумевал? Ментальное сканирование?

ну там прямо дальше говорилось Императивные аналоги, я думаю, Вы себе представляете
я представил и оказалсь разницы нет.

G>Что характерно, если ты добавишь в любой язык встроенные списки так, как это сделано в современных ФЯ, то на нем сразу станет удобно писать в функциональном стиле. Одного не понимаю, каким именно образом это порочит "светлую идею" ФЯ?


я не собираюсь ничего порочить, просто пытаюсь понять смогу ли я использовать ФЯ в своей практической работе, пока преимуществ не вижу, буду изучать как хобби
Re[7]: ФП: вводная статья
От: FR  
Дата: 28.09.04 10:24
Оценка:
Здравствуйте, Gaperton, Вы писали:

По тестам которые ты выше привел, на другой странице я нашел тест с psyco(jit компилятор питона) у них результаты практически одинаковы с интерпретатором, у меня при включении psyco тест срабатывает в 25 раз быстрее чем интерпретируемый, если они и с остальными языками также намеряли, то доверия к ним нет никакого.
Re[7]: ФП: вводная статья
От: WolfHound  
Дата: 28.09.04 10:25
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>На, посмотри, как мы забиваем на эффективность. И найди здесь свой питон (подсказка: ищи в конце), который проиграл вдвое даже динамически типизированному Erlang-у. А если обратить внимание, что в данный момент реализация на haskell занимает в рейтинге первое место, обогнав gcc, то просто обхохочешься.

До 8192 это даже не смешно. Вот если они сделают тесты до 10'000'000 вот тогда будет понятно кто тут рулит. К стати почему там нет VC++?
int main()
{
    int NUM = 10;
    const unsigned size=8192;
    static char flags[size + 1];
    int count = 0;

    while (NUM--) 
    {
        count = 0;
        for (unsigned i=2; i <= size; i++) 
            flags[i] = 1;
        for (unsigned i=2; i <= size; i++) 
            if (flags[i]) 
            {
                // remove all multiples of prime: i
                for (unsigned k=i+i; k <= size; k+=i) 
                    flags[k] = 0;
                count++;
            }
    }
    printf("Count: %d\n", count);
}

_main    PROC NEAR                    ; COMDAT

; 4    : {

    push    ebx
    push    esi
    push    edi

; 5    :     int NUM = 10;

    mov    ebx, 10                    ; 0000000aH
    xor    edx, edx
    npad    6
$L64207:

; 11   :     {
; 12   :         count = 0;
; 13   :         for (unsigned i=2; i <= size; i++) 
; 14   :             flags[i] = 1;

    mov    ecx, 2047                ; 000007ffH
    mov    eax, 16843009                ; 01010101H
    mov    edi, OFFSET FLAT:?flags@?1??main@@9@4PADA+2
    rep stosd
    stosw
    xor    esi, esi
    stosb

; 15   :         for (unsigned i=2; i <= size; i++) 

    mov    ecx, 2
    npad    5
$L64214:

; 16   :             if (flags[i]) 

    cmp    BYTE PTR ?flags@?1??main@@9@4PADA[ecx], dl
    je    SHORT $L64215

; 17   :             {
; 18   :                 // remove all multiples of prime: i
; 19   :                 for (unsigned k=i+i; k <= size; k+=i) 

    cmp    ecx, 4096                ; 00001000H
    lea    eax, DWORD PTR [ecx+ecx]
    ja    SHORT $L64221
$L64219:

; 20   :                     flags[k] = 0;

    mov    BYTE PTR ?flags@?1??main@@9@4PADA[eax], dl
    add    eax, ecx
    cmp    eax, 8192                ; 00002000H
    jbe    SHORT $L64219
$L64221:

; 21   :                 count++;

    inc    esi
$L64215:

; 15   :         for (unsigned i=2; i <= size; i++) 

    inc    ecx
    cmp    ecx, 8192                ; 00002000H
    jbe    SHORT $L64214

; 6    :     const unsigned size=8192;
; 7    :     static char flags[size + 1];
; 8    :     int count = 0;
; 9    : 
; 10   :     while (NUM--) 

    dec    ebx
    jne    SHORT $L64207

; 22   :             }
; 23   :     }
; 24   :     printf("Count: %d\n", count);

    push    esi
    push    OFFSET FLAT:??_C@_0L@NKLBHBJO@Count?3?5?$CFd?6?$AA@
    call    _printf
    add    esp, 8
    pop    edi
    pop    esi

; 25   : }

    xor    eax, eax
    pop    ebx
    ret    0
_main    ENDP

Ктонить покажите что gcc генерит.
... << RSDN@Home 1.1.4 rev. 185 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[10]: ФП: вводная статья
От: Gaperton http://gaperton.livejournal.com
Дата: 28.09.04 10:33
Оценка:
Здравствуйте, FR, Вы писали:
G>>Кстати, слепенький я наверно. Ну не вижу я цикла for в твоем коде. А вот list comprehensions вижу, как и отсутствие побочных эффектов.

FR>перевожу для слабовидящих:

FR>
FR>ltList=[y for y in aList[1:] if y<aList[0]] 
FR>


FR>равносильно

FR>
FR>ltList = []
FR>for y in aList[1:] :
FR>    if y<aList[0]: ltList.append(y)
FR>


Да ну? А я думал, это равносильно маленькой рекурсивной функции, или коду с оператором goto, или вставке на языке Клиппер (для скорости).

А на самом деле это один из вариантов ZF-нотации, что и есть list comprehensions. В питоне заимствовано из функциональных языков.
ltList = [ y | y <- tail( aList ), y < head( aList ) ]

FR>просто ты не хочешь признать что императивный язык тоже может быть декларативным.

Просто ты за меня выдумываешь, что я имею в виду. Прочитай comp.lang.functional FAQ, чтобы понять, что такое функциональный стиль и при каких условиях язык можно отнести к функциональному. Питон, например, вполне можно — было-бы желание.

FR>я не собираюсь ничего порочить, просто пытаюсь понять смогу ли я использовать ФЯ в своей практической работе, пока преимуществ не вижу, буду изучать как хобби

Успехов.
Re[8]: ФП: вводная статья
От: Gaperton http://gaperton.livejournal.com
Дата: 28.09.04 10:40
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, Gaperton, Вы писали:


G>>На, посмотри, как мы забиваем на эффективность. И найди здесь свой питон (подсказка: ищи в конце), который проиграл вдвое даже динамически типизированному Erlang-у. А если обратить внимание, что в данный момент реализация на haskell занимает в рейтинге первое место, обогнав gcc, то просто обхохочешься.

WH>До 8192 это даже не смешно.
Согласен.

WH>Вот если они сделают тесты до 10'000'000 вот тогда будет понятно кто тут рулит. К стати почему там нет VC++?

Потому что тесты пускаются под линухом. А сети есть вариант этих тестов под Win32, может там есть.
Re[8]: ФП: вводная статья
От: FR  
Дата: 28.09.04 10:42
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Ктонить покажите что gcc генерит.


gcc 3.2

    .intel_syntax
    .file    "sieve2.cpp"
    .def    ___main;    .scl    2;    .type    32;    .endef
.lcomm _ZZ4mainE5flags,8208
    .text
LC0:
    .ascii "Count: %d\12\0"
    .align 2
    .p2align 4,,15
.globl _main
    .def    _main;    .scl    2;    .type    32;    .endef
_main:
LFB1:
    push    ebp
LCFI0:
    xor    eax, eax
    mov    ebp, esp
LCFI1:
    push    ebx
LCFI2:
    mov    ebx, 9
    push    edx
    and    esp, -16
    call    __alloca
    call    ___main
L21:
    xor    ecx, ecx
    mov    eax, 2
    .p2align 4,,7
L9:
    mov    BYTE PTR _ZZ4mainE5flags[eax], 1
    inc    eax
    cmp    eax, 8192
    jbe    L9
    mov    edx, 2
    .p2align 4,,7
L20:
    cmp    BYTE PTR _ZZ4mainE5flags[edx], 0
    je    L12
    lea    eax, [edx+edx]
    cmp    eax, 8192
    ja    L29
    .p2align 4,,7
L19:
    mov    BYTE PTR _ZZ4mainE5flags[eax], 0
    add    eax, edx
    cmp    eax, 8192
    jbe    L19
L29:
    inc    ecx
L12:
    inc    edx
    cmp    edx, 8192
    jbe    L20
    dec    ebx
    cmp    ebx, -1
    jne    L21
    push    eax
    push    eax
    push    ecx
    push    OFFSET FLAT:LC0
LCFI3:
    call    _printf
    mov    ebx, DWORD PTR [ebp-4]
    xor    eax, eax
    leave
    ret
LFE1:
    .def    _printf;    .scl    2;    .type    32;    .endef
Re[8]: ФП: вводная статья
От: Gaperton http://gaperton.livejournal.com
Дата: 28.09.04 10:43
Оценка:
Здравствуйте, FR, Вы писали:

FR>Здравствуйте, Gaperton, Вы писали:


FR>По тестам которые ты выше привел, на другой странице я нашел тест с psyco(jit компилятор питона) у них результаты практически одинаковы с интерпретатором, у меня при включении psyco тест срабатывает в 25 раз быстрее чем интерпретируемый, если они и с остальными языками также намеряли, то доверия к ним нет никакого.

Возможно, у них старая версия этого psyco. Возможно, это просто ошибка. Возможно, ты смотришь страницу где включено время старта проги. Если ты им напишешь, они поправят.
Re[2]: ФП: вводная статья
От: Quintanar Россия  
Дата: 28.09.04 10:51
Оценка:
Здравствуйте, little_alex, Вы писали:


Q>>Вызов по имени в целом более выгоден,

_>Спорно сам пишешь ниже.Выгодно когда то что нужно вычислить достатчно мало (занимает мало памяти для описания)
_>а вычисления достаточно долгие например 1000000000000! и не выгодно когда вычисленный результат во много раз меньше чем исходный.Например размер дерева или списка — проще сразу получить размер и удалить саму структуру(если она не используется далее) чем хранить ее до последнего

Да, это верно. Вернее было бы сказать теоретически более выгоден. На практике, я думаю, выгоден симбиоз ленивых и строгих вычислений.

_>И Haskell и Ocaml поддерживают оба способа.Просто по умолчанию поведение Haskell нестрогое а OCaml строгое.


Так можно сказать, что и С поддерживает ленивые вычисления и это будет правдой. Просто уровень поддержки существенно разный. Haskell изначально поддерживает один тип вызова функций, а OCaml другой. Это существенная разница, поскольку это влияет на то, как будет написан компилятор.

Q>> Основным типом ФЯ можно назвать список

_>Основным типом ФЯ Haskell является алгебраический тип данных.Близкий аналог в ИЯ это enum(C).

Это верно, конечно, что список и кортеж частные случаи более общего типа данных. Но они играют довольно важную роль в функциональных программах, поэтому, я думаю, стоит особо отметить их роль.
Enums лишь слегка похожи на алгебраический тип данных, как ты выражаешься, поскольку они нерекурсивны и не могут содержать другие типы данных.

Q>>Карринг

_>Предположим есть функция — сложение.
_>Можно рассматривать ее как функцию от 2 аргументов int и возвращающюю int
_>А можно как функцию 1-ого числа x возвращающюю другую функцию 1-ого аргумента f ,такую что f y =x+y — это карринг или частичное применение функции

Про карринг можно и нужно написать больше, поскольку это очень важная на мой взгляд концепция.
Re[11]: ФП: вводная статья
От: FR  
Дата: 28.09.04 10:57
Оценка:
Здравствуйте, Gaperton, Вы писали:


G>А на самом деле это один из вариантов ZF-нотации, что и есть list comprehensions. В питоне заимствовано из функциональных языков.

G>ltList = [ y | y <- tail( aList ), y < head( aList ) ]

а я говорю они это из пролога уперли

FR>>просто ты не хочешь признать что императивный язык тоже может быть декларативным.

G>Просто ты за меня выдумываешь, что я имею в виду. Прочитай comp.lang.functional FAQ, чтобы понять, что такое функциональный стиль и при каких условиях язык можно отнести к функциональному. Питон, например, вполне можно — было-бы желание.

На питоне можно писать и в чисто функциональном стиле, я не спорю, просто тот же list comprehensions в питоне на обычный язык все таки переводится как императивный алгоритм, но кроме него в новых версия много вещей (те же итераторы и генераторы) которые императивно делают то что раньше было проще делать функционально.
Re[2]: ФП: вводная статья
От: Quintanar Россия  
Дата: 28.09.04 11:01
Оценка:
Здравствуйте, FR, Вы писали:

FR>У меня такой вопрос какие задачи ложатся на ФЯ лучше чем на ИЯ. Просто из своего опыта и из тех веток где была задача с простыми числами, у меня сложилось впечатление что даже многие математические задачи проще решаются ИЯ, например у той же задачи про решето Эратосфена сишная реализация намного прозрачнее и ближе к описанию алгоритма на естественном языке.


Задачи, где необходимо работать со сложными типами данных типа деревьев, списков, скорее всего будут более эффективно решаться на ФЯ. Задачи связанные с большим количеством вычислений над простыми типами (int и т.п.), работой с массивами и т.п. будут работать быстрее на ИЯ.
К первым задачам можно отнести всякие системы компьютерной алгебры, символьных вычислений, доказательств теорем, компиляторы с парсерами и т.п. Ко второй — численные задачи с большим объемом вычислений.
Решето Эратосфена как раз императивная задача, поскольку сводится к изменению массива.
Re[9]: ФП: вводная статья
От: FR  
Дата: 28.09.04 11:08
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Здравствуйте, FR, Вы писали:


FR>>Здравствуйте, Gaperton, Вы писали:


FR>>По тестам которые ты выше привел, на другой странице я нашел тест с psyco(jit компилятор питона) у них результаты практически одинаковы с интерпретатором, у меня при включении psyco тест срабатывает в 25 раз быстрее чем интерпретируемый, если они и с остальными языками также намеряли, то доверия к ним нет никакого.

G>Возможно, у них старая версия этого psyco. Возможно, это просто ошибка. Возможно, ты смотришь страницу где включено время старта проги. Если ты им напишешь, они поправят.

У них та же версия psyco что и у меня.
Время старта программы не имеет значения для 1200 прогонов, проверял разница на проценты.
Скорее всего ошибка, так как время с psyco примерно равно времени интерпретатора.
Писать им не буду, не хочу смешить своим английским
Re[4]: ФП: вводная статья
От: Quintanar Россия  
Дата: 28.09.04 11:08
Оценка:
Здравствуйте, hrg, Вы писали:

hrg>Мне вот интересно, как с помощью ФП пишется бизнес- логика? Как описать

hrg>поведение не_знаю_как_будет_в_ФП_объекты? Такие вот банальные
hrg>сермяжно-прагматические вопросы

Объектов в большинстве ФЯ нет. Там есть свои способы изолировать технические детали реализации от сути программы. В Haskell'е есть монады, например, и классы типов. Классы типов по сути, кстати, есть классы в понимании С++, только поскольку переменных в языке нет, то и нет возможности представить объект как отдельную сущность, т.е. классы в Хаскелле — это классы в С++ без членов-переменных и где все функции статические.
Re[4]: ФП: вводная статья
От: Quintanar Россия  
Дата: 28.09.04 11:11
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Насколько я понял, ОКамл как раз и работает более менее быстро из-за того, что в нем введены императивные средства, на которых и реализованы базовые алгоритмы. И по мне, так очень разумное решение. Вот еще бы более приличный императивный синтаксис. Да и вообще сделать бы синтаксис по ближе к мэйстримным С-подобным языкам. Было бы куда проще осваивать.


В OCaml есть парсер P4, с помощью которого можно сделать свой собственный синтаксис — хочешь императивный, хочешь функциональный.
Re[4]: ФП: вводная статья
От: Quintanar Россия  
Дата: 28.09.04 11:22
Оценка:
Здравствуйте, VladD2, Вы писали:


_>>3.Где активно применяется рекурсия например LL — разбор


VD>Но опчему-то для постраения парсеров в ФЯ все равно создают постоители парсеров (вроде Яка/Лекса). А ЛЛ(1) легко делается методом рекурсивного спуска на любом ИЯ.


Як — это другое дело, такие парсеры везде выгоднее генерировать, а не писать руками. А вот как выглядит монадный LL парсер написанный с помощью небольшой библиотеки базовых функций. Обрати внимание, что все детали реализации скрыты в монадах и остается только суть — сама граматика. Исходники библиотеки, кстати, можно изучить за час — два, настолько она проста.

Здесь только часть парсера, чтобы была понятна идея. Думаю, надо написать LL парсер C# на Haskell'e и сравнить с вашей реализацией.

-----------------------------------------------------------
-- GRAMMAR ELEMENTS
-----------------------------------------------------------
compilationUnit :: Parser CompilationUnit
compilationUnit =
    do{ whiteSpace
      ; reserved "package"
      ; name  <- option [""] packageName
      ; decls <- option []   declarations
      ; eof
      ; return $ Package name decls
      }

-----------------------------------------------------------
-- Declarations
-----------------------------------------------------------
declarations =
    braces (semiSep1 declaration)

declaration =
        importDeclaration
    <|> classDeclaration
    <|> variableSignatureDeclaration
    <?> "declaration"

variableSignatureDeclaration =
    do{ name <- variableName
      ; variableDeclaration name <|> signatureDeclaration name
      }

variableDeclaration name =
    do{ symbol "="
      ; expr <- expression
      ; return $ VarDecl name expr
      }
    <?> "variable declaration"

importDeclaration =
    do{ reserved "import"
      ; name <- packageName
      ; star <- option [] (do{ symbol "."
                             ; symbol "*"
                             ; return ["*"]
                             })
      ; return $ ImportDecl (name ++ star)
      }

classDeclaration =
    do{ reserved "class"
      ; name    <- className
      ; extends <- option [] (do{ reserved "extends"
                                ; n <- className
                                ; return [n]
                                })
      ; decls   <- option [] declarations
      ; return $ ClassDecl name extends decls

      }

signatureDeclaration name =
    do{ symbol "::"
      ; texpr  <- typeExpression
      ; return $ SigDecl name texpr
      }
    <?> "type declaration"


-----------------------------------------------------------
-- Expressions
-----------------------------------------------------------
expression :: Parser Expr
expression =
        lambdaExpression
    <|> letExpression
    <|> newExpression
    <|> infixExpression
    <?> "expression"

lambdaExpression =
    do{ symbol "\\"
      ; name <- variableName
      ; symbol "->"
      ; expr <- expression
      ; return $ groupLambdas (Lambda [name] expr)
      }

letExpression =
    do{ reserved "let"
      ; decls <- declarations
      ; reserved "in"
      ; expr <- expression
      ; return $ Let decls expr
      }

newExpression =
    do{ reserved "new"
      ; name  <- className
      ; decls <- option [] declarations
      ; return $ New name decls
      }
Re[8]: ФП: вводная статья
От: Quintanar Россия  
Дата: 28.09.04 11:26
Оценка:
Здравствуйте, FR, Вы писали:

FR>Здравствуйте, Gaperton, Вы писали:


FR>По тестам которые ты выше привел, на другой странице я нашел тест с psyco(jit компилятор питона) у них результаты практически одинаковы с интерпретатором, у меня при включении psyco тест срабатывает в 25 раз быстрее чем интерпретируемый, если они и с остальными языками также намеряли, то доверия к ним нет никакого.


Я думаю, они там тестировали только интерпретатор.
Re[8]: ФП: вводная статья
От: Quintanar Россия  
Дата: 28.09.04 11:27
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>До 8192 это даже не смешно. Вот если они сделают тесты до 10'000'000 вот тогда будет понятно кто тут рулит. К стати почему там нет VC++?


Потому что они использовали только свободные компиляторы/интерпретаторы, которые есть в Debian.
Re[7]: ФП: вводная статья
От: WolfHound  
Дата: 28.09.04 12:02
Оценка: +1
Здравствуйте, Gaperton, Вы писали:

G>Он расписался
Автор: Gaperton
Дата: 13.09.04
также в том, что заметил лучшую асимптотику твоего алгоритма но не хочет заниматься алгоритмической оптимизацией. Лень ему, понимаешь, и смысла в этом он не видит. Что ты сравнить хочешь, эффективность компиляторов, или что?

Я хочу сравнить компиляторы на алгоритме с одинаковой асимптотикой. И еще хочу увидить реализацию алгоритма на функциональном языке(без императивности)с тойже асимптотикой что и у меня.
Кстати либо я чего не понял либо алгоритм по твоей ссылке имеет асимптотику хуже чем алгоритм "в лоб"
sieve :: [Int] -> [Int]
sieve [] = []
sieve (h:t) = h : sieve [x| x<-t, x`mod`h /= 0]

И что мы видим? А видим мы то что каждое число делится на все простые числа меньше минимального простого делителя те для простых чисел мы получаем что они делятся на все простые числа меньшие данного простого числа.
Для простоты принебрегаем составными числами.
Учитывая что плотность простых чисел примерно N/ln(N) то мы получаем сложность O((N/ln(N))^2) что гораздо хуже чем O(N^(3/2)) у алгоритма в лоб. А если учесть что N/ln(N) это оценка снизу и то что мы забыли про составные числа то картина становится мягко говоря плачевной.
... << RSDN@Home 1.1.4 rev. 185 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[5]: ФП: вводная статья
От: hrg Россия  
Дата: 28.09.04 12:45
Оценка:
Quintanar -> "Re[4]: ФП: вводная статья" :

Q> Здравствуйте, hrg, Вы писали:


hrg>> Мне вот интересно, как с помощью ФП пишется бизнес- логика? Как

hrg>> описать поведение не_знаю_как_будет_в_ФП_объекты? Такие вот
hrg>> банальные сермяжно-прагматические вопросы

Q> Объектов в большинстве ФЯ нет. Там есть свои способы изолировать

Q> технические детали реализации от сути программы. В Haskell'е есть
Q> монады, например, и классы типов. Классы типов по сути, кстати, есть
Q> классы в понимании С++, только поскольку переменных в языке нет, то и
Q> нет возможности представить объект как отдельную сущность, т.е.
Q> классы в Хаскелле — это классы в С++ без членов-переменных и где все
Q> функции статические.

Спасибо. Интересно, но не понятно

Yury Kopyl aka hrg | http://id.totem.ru | "Спам придумали боги в отместку
за наши молитвы."
Posted via RSDN NNTP Server 1.9 gamma
Re[8]: ФП: вводная статья
От: Gaperton http://gaperton.livejournal.com
Дата: 28.09.04 13:13
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, Gaperton, Вы писали:


G>>Он расписался
Автор: Gaperton
Дата: 13.09.04
также в том, что заметил лучшую асимптотику твоего алгоритма но не хочет заниматься алгоритмической оптимизацией. Лень ему, понимаешь, и смысла в этом он не видит. Что ты сравнить хочешь, эффективность компиляторов, или что?

WH>Я хочу сравнить компиляторы на алгоритме с одинаковой асимптотикой. И еще хочу увидить реализацию алгоритма на функциональном языке(без императивности)с тойже асимптотикой что и у меня.
Я тоже хочу именно этого. Приступим. Вот дословный перевод твоего алгоритма на Clean.
// фигня всякая...
import StdClass
import StdInt, _SystemArray, StdEnum

/*
Давай мы все-таки не будем меряться скоростью свопа и количеством оперативки, хорошо? :)))
Твоя прога выделяет минимум гигабайт памяти - у меня столько нет.
Так что давай меряться на 100 миллионах, ок? ;)
*/     
Size :== 100000000 

// функция - аналог главного цикла. 
sieve primes i
    | i == Size    = primes // здесь, типа, выходим из цикла
    | primes.[ i ] = sieve { primes & [n] = False \\ n <- [ 2*i, 3*i..(Size - 1) ] } ( i + 1 ) // здесь вычеркиваем
                        = sieve primes ( i + 1 ) // а здесь пустая итерация

// уникальный массив unboxed bool длины Size инициализированный True. Будет меняться деструктивно.
IsPrime:: .{#Bool}
IsPrime = createArray Size True

Start:: Bool
Start =    ( sieve IsPrime 2 ).[31] // ломает меня с вводом-выводом разбираться. Поэтому просто вернем значение ячейки №31.

Как видишь, получилось короче — в основном заслуга array и list comprehensions.

Сами числа не распечатывал, так как ломало ковыряться с Clean-овским вводом-выводом.
Вот exe. http://www.rsdn.ru:80/File/20496/fsieve2.exe

23.59 секунд на моей системе.

WH>Кстати либо я чего не понял либо алгоритм по твоей ссылке имеет асимптотику хуже чем алгоритм "в лоб"

Не, у меня в тот раз была асимптотика O(N*sqrt(N)) — я делал отсечку по sqrt. А перебирал с шагом 4-6-4-6-4-6...
Re[6]: ФП: вводная статья
От: Quintanar Россия  
Дата: 28.09.04 13:22
Оценка:
Здравствуйте, hrg, Вы писали:

hrg>Спасибо. Интересно, но не понятно


Я хотел просто отметить, что объектов в ФЯ нет по той причине, что там не приветствуется программирование с помощью некотролируемого изменения состояния. А если у объекта нет состояния, то зачем он собственно нужен — в этом случае все объекты получаются одинаковыми.

Если посмотреть на стандартные библиотеки в ФЯ, то видно, что близкие по смыслу функции выделяются в отдельные модули типа HashTable, FiniteMap, Tree и т.п.

Есть и другие методы организации вычислений кроме объектного-ориентированного — монады, стрелки, continuation passing style, может еще чего. Все они могут быть реализованы и на С++, только смысла в этом будет немного (исключая CPS).
Re[9]: ФП: вводная статья
От: Gaperton http://gaperton.livejournal.com
Дата: 28.09.04 13:23
Оценка:
Гхм, эта... Вот, ассемблер, значить, какой получается...
    .data
m__fsieve:
    .long    6
    .ascii    "fsieve"
    .byte    0,0
    .text
    .globl    _start
_start:
    .globl    ____fsieve__Start
____fsieve__Start:
    cmpl    end_heap,%edi
    jae    i_1
i_2:
    movl    $n3,(%edi)
    movl    %edi,%ecx
    addl    $12,%edi
    jmp    __driver
    .align    4
    .long    0
n3:
    movl    %ecx,(%esi)
    movl    $__cycle__in__spine,(%ecx)
    leal    4(%esi),%esi
    call    ea3
    movl    -4(%esi),%ecx
    movl    $BOOL+2,(%ecx)
    movl    %eax,4(%ecx)
    leal    -4(%esi),%esi
    ret
ea3:
s3:
    call    s2
    movl    $2,%eax
    call    s5
    movzbl    43(%ecx),%eax
    ret
s5:
    cmpl    $100000000,%eax
    jne    else_P1
    ret
else_P1:
    movzbl    12(%ecx,%eax),%ebx
    testl    %ebx,%ebx
    je    else_P2
    cmpl    end_heap,%edi
    jae    i_3
i_4:
    movl    %ecx,(%esi)
    movl    %eax,%ebx
    addl    $1,%ebx
    pushl    %ebx
    pushl    $e_0
    movl    $100000000,%ebx
    subl    $1,%ebx
    pushl    %ebx
    movl    %eax,%ebx
    shl    $1,%ebx
    movl    %eax,%edx
    shl    $1,%edx
    addl    %edx,%eax
    movl    $__cycle__in__spine,(%edi)
    movl    %edi,%ecx
    addl    $12,%edi
    leal    4(%esi),%esi
    jmp    e____SystemEnum__s__from__then__to_I10
e_0:
    movl    -4(%esi),%edx
    leal    -4(%esi),%esi
    call    s6
    popl    %eax
    jmp    s5
else_P2:
    addl    $1,%eax
    jmp    s5
s6:
    xchg    %edx,%ecx
s8:
    cmpl    $__Cons+18,(%edx)
    jne    case_P4
case_P3:
    movl    %ecx,(%esi)
    movl    4(%edx),%ecx
    movl    8(%edx),%edx
    leal    4(%esi),%esi
    testb    $2,(%edx)
    jne    e_1
    movl    %ecx,(%esi)
    addl    $4,%esi
    movl    %edx,%ecx
    call    (%edx)
    movl    %ecx,%edx
    movl    -4(%esi),%ecx
    subl    $4,%esi
e_1:
    testb    $2,(%ecx)
    jne    e_2
    movl    %edx,(%esi)
    addl    $4,%esi
    call    (%ecx)
    movl    -4(%esi),%edx
    subl    $4,%esi
e_2:
    movl    -4(%esi),%eax
    pushl    %eax
    movl    4(%ecx),%eax
    popl    %ebx
    movb    $0,12(%ebx,%eax)
    movl    %edx,%eax
    movl    %ebx,%edx
    movl    %eax,%ecx
    leal    -4(%esi),%esi
    jmp    s6
case_P4:
    ret
s2:
    movl    $1,%eax
    movl    $100000000,%ebx
    call    create_arrayB
    ret
i_1:
    call    collect_0
    jmp    i_2
i_3:
    call    collect_1
    jmp    i_4


Компере ву?
Re[12]: ФП: вводная статья
От: eugals Россия  
Дата: 28.09.04 13:27
Оценка:
Здравствуйте, FR, Вы писали:

FR>Здравствуйте, Gaperton, Вы писали:



G>>А на самом деле это один из вариантов ZF-нотации, что и есть list comprehensions. В питоне заимствовано из функциональных языков.

G>>ltList = [ y | y <- tail( aList ), y < head( aList ) ]

FR>а я говорю они это из пролога уперли


Из Haskell-а. Ещё в версии 2.0.
Кстати, list comprehensions, мягко говоря, не самая быстрая часть языка (хоть и удобная).
Лично мне больше понравились расширенная семантика итераторов (модуль itertools), которая была введена в 2.3.
... << RSDN@Home 1.1.4 beta 2 >>
Re[9]: ФП: вводная статья
От: Gaperton http://gaperton.livejournal.com
Дата: 28.09.04 13:29
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Как видишь, получилось короче — в основном заслуга array и list comprehensions.

Впрочем нет — получилось совершенно одинаково
Re[12]: ФП: вводная статья
От: Gaperton http://gaperton.livejournal.com
Дата: 28.09.04 13:42
Оценка:
Здравствуйте, FR, Вы писали:

FR>Здравствуйте, Gaperton, Вы писали:



G>>А на самом деле это один из вариантов ZF-нотации, что и есть list comprehensions. В питоне заимствовано из функциональных языков.

G>>ltList = [ y | y <- tail( aList ), y < head( aList ) ]
FR>а я говорю они это из пролога уперли
Да ладно тебе

FR>На питоне можно писать и в чисто функциональном стиле, я не спорю, просто тот же list comprehensions в питоне на обычный язык все таки переводится как императивный алгоритм,

Так и в функциональных языках это не святым духом выполняется . Если нет ленивых вычислений, то функциональный код без проблем транслируется в императивный, с цыклами (хвостовая рекурсия переводится в цикл). Что, собственно, и происходит даже в ленивых языках. Смотри, что произошло с моим примером на Clean: http://www.rsdn.ru/Forum/Message.aspx?mid=828170&amp;only=1
Автор: Gaperton
Дата: 28.09.04


FR>но кроме него в новых версия много вещей (те же итераторы и генераторы) которые императивно делают то что раньше было проще делать функционально.

Ну и хорошо. Питон, должно быть, удобный язык.
Re[13]: ФП: вводная статья
От: FR  
Дата: 28.09.04 14:01
Оценка:
Здравствуйте, Gaperton, Вы писали:


FR>>На питоне можно писать и в чисто функциональном стиле, я не спорю, просто тот же list comprehensions в питоне на обычный язык все таки переводится как императивный алгоритм,

G>Так и в функциональных языках это не святым духом выполняется . Если нет ленивых вычислений, то функциональный код без проблем транслируется в императивный, с цыклами (хвостовая рекурсия переводится в цикл). Что, собственно, и происходит даже в ленивых языках. Смотри, что произошло с моим примером на Clean: http://www.rsdn.ru/Forum/Message.aspx?mid=828170&amp;only=1
Автор: Gaperton
Дата: 28.09.04


Понятно что в конечном коде все императивно, дело не в этом, ту же инициацию списка можно вполне императивно описать на естественном языке, и любой кто программировал до этого на императивных языках быстро понимает эту питоновскую конструкцию.

FR>>но кроме него в новых версия много вещей (те же итераторы и генераторы) которые императивно делают то что раньше было проще делать функционально.

G>Ну и хорошо. Питон, должно быть, удобный язык.

Угу, к сожалению функциональные языки (я сейчас ocaml ковыряю) оказались не такими удобными, вроде бы и абстракция на самом деле выше, но все равно они кажутся более далекими от человеческого мышления
Re[14]: ФП: вводная статья
От: Nick_ Россия  
Дата: 28.09.04 14:05
Оценка:
Здравствуйте, FR, Вы писали:

FR>Угу, к сожалению функциональные языки (я сейчас ocaml ковыряю) оказались не такими удобными, вроде бы и абстракция на самом деле выше, но все равно они кажутся более далекими от человеческого мышления


Это только так кажется на первый взгляд.
Re[14]: ФП: вводная статья
От: Gaperton http://gaperton.livejournal.com
Дата: 28.09.04 14:16
Оценка:
Здравствуйте, FR, Вы писали:

FR>Угу, к сожалению функциональные языки (я сейчас ocaml ковыряю) оказались не такими удобными, вроде бы и абстракция на самом деле выше, но все равно они кажутся более далекими от человеческого мышления


Навеяло.

Он обнажил меч и прикинул вес: проделав им несколько пробных взмахов.
— Никудышный баланс, — поморщился он.
— Вы к нему привыкнете.
— Паршивая сталь, — провозгласил он, пристально разглядывая меч.
— Однако с приличной режущей кромкой.
— Ну, мой тренер всегда мне говорил: "Если ты позаботишься о своем
мече, то он позаботится о тебе!"
— Нас, должно быть, обучал один и тот же тренер.
Они улыбнулись друг другу. Я почувствовал себя слегка нехорошо.
— И все же я не знаю. Пятьдесят золотых — большие деньги.
— Да вы только посмотрите на эти камни в рукояти.
— Смотрел. Они фальшивые.
— Ага! Они сделаны так, чтобы выглядеть фальшивыми. Это скрывает их
ценность.
— Безусловно, делает это здорово. Что это за камни?
— Камни Афера.
— Камни Афера?
— Да. Говорят, что они обеспечивают популярность у женщин, если вы
понимаете, что я имею в виду.

http://www.lib.ru/ASPRIN/myth_1.txt
Re: ФП: вводная статья
От: little_alex  
Дата: 28.09.04 14:31
Оценка:
Ну вот опять — обсуждение статьи 5 постов а остальное 'Нужны ли ФЯ.Какая область применимости.Banchmakrs.....'
Было же в двух или трех топиках.Сколько можно.
Что не у кого нет предложений и замечаний по статье.
Re[9]: ФП: вводная статья
От: WolfHound  
Дата: 28.09.04 15:01
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Я тоже хочу именно этого. Приступим. Вот дословный перевод твоего алгоритма на Clean.

Так так... Деструктивное изменение массива... те от функционального языка остался только синтаксис...

G>Давай мы все-таки не будем меряться скоростью свопа и количеством оперативки, хорошо?

А у тебя что меньше ста дватцати метров?
G>Твоя прога выделяет минимум гигабайт памяти — у меня столько нет.
Не она выделяет примеро 120 метров... ибо std::vector<bool> это массив битов по стандарту...
G>Так что давай меряться на 100 миллионах, ок?
Да мне пофигу.
G>ломает меня с вводом-выводом разбираться. Поэтому просто вернем значение ячейки №31.
Ой как все запущено то...
G>Как видишь, получилось короче — в основном заслуга array и list comprehensions.
Да я бы не сказал.
    unsigned size=1000000000;
    std::vector<bool> is_prime(size, true);//помечаем все числа как простые
    for(unsigned i=2;i<size;++i)//ищем очередное не вычеркнутое число
        if(is_prime[i])
            for(unsigned n=i+i;n<size;n+=i)//вычеркиваем все числа кратные данному числу
                is_prime[n]=false;

; 6    :     unsigned size=100000000;
; 7    :     std::vector<bool> is_prime(size, true);    //помечаем все числа как простые

    lea    edx, DWORD PTR $T74423[esp+76]
    push    edx
    xor    esi, esi
    push    3125000                    ; 002faf08H
    lea    ecx, DWORD PTR _is_prime$[esp+88]
    mov    DWORD PTR _is_prime$[esp+84], esi
    mov    DWORD PTR $T74423[esp+84], -1
    call    ?_Construct_n@?$vector@IV?$allocator@I@std@@@std@@QAEXIABI@Z ; std::vector<unsigned int,std::allocator<unsigned int> >::_Construct_n
    push    100000000                ; 05f5e100H
    lea    ecx, DWORD PTR _is_prime$[esp+80]
    mov    DWORD PTR __$EHRec$[esp+88], esi
    call    ?_Trim@?$vector@_NV?$allocator@_N@std@@@std@@IAEXI@Z ; std::vector<bool,std::allocator<bool> >::_Trim

; 9    :         if(is_prime[i])                        //i очередное простое число

    mov    ebx, DWORD PTR _is_prime$[esp+84]
    mov    DWORD PTR __$EHRec$[esp+84], 1
    mov    edi, 2
    push    ebp
$L74729:
    xor    eax, eax
    mov    eax, edi
    mov    ecx, eax
    shr    ecx, 5
    and    eax, 31                    ; 0000001fH
    lea    edx, DWORD PTR [ebx+ecx*4]
    mov    ecx, eax
    mov    eax, DWORD PTR [edx]
    mov    esi, 1
    shl    esi, cl
    test    esi, eax
    je    SHORT $L64774

; 10   :             for(unsigned n=i+i;n<size;n+=i)    //вычеркиваем все числа кратные данному числу

    cmp    edi, 50000000                ; 02faf080H
    lea    edx, DWORD PTR [edi+edi]
    jae    SHORT $L64774

; 11   :                 is_prime[n]=false;

    xor    ebp, ebp
$L64833:
    mov    eax, ebp
    add    eax, edx
    mov    esi, eax
    mov    ecx, ebx
    shr    esi, 5
    lea    esi, DWORD PTR [ecx+esi*4]
    and    eax, 31                    ; 0000001fH
    mov    ecx, 1
    mov    DWORD PTR tv359[esp+80], ecx
    mov    ecx, eax
    mov    eax, DWORD PTR tv359[esp+80]
    shl    eax, cl
    mov    ecx, DWORD PTR [esi]
    add    edx, edi
    not    eax
    and    ecx, eax
    cmp    edx, 100000000                ; 05f5e100H
    mov    DWORD PTR [esi], ecx
    jb    SHORT $L64833
$L64774:

; 8    :     for(unsigned i=2;i<size;++i)            //ищем очередное не вычеркнутое число

    inc    edi
    cmp    edi, 100000000                ; 05f5e100H
    jb    SHORT $L74729

G>23.59 секунд на моей системе.
Execution: 21.31 Garbage collection: 0.21 Total: 21.53 и примерно 290 метров памяти.
Моя программа
8.66727 и примерно 12.8 метров памяти.

Хотя если выкинуть std::vector<bool> и работать с битами ручками то получается лучше хотя и не на много
const unsigned bits=CHAR_BIT*sizeof(unsigned);
void set_bit(unsigned n, unsigned* arr)
{
    unsigned pos=n/bits;
    unsigned ofs=n%bits;
    arr[pos]|=1<<ofs;
}
bool get_bit(unsigned n, unsigned* arr)
{
    unsigned pos=n/bits;
    unsigned ofs=n%bits;
    return arr[pos]&(1<<ofs);
}
int main()
{
    timer_t timer;
    unsigned size=100000000;
    std::vector<unsigned> v(size/bits+1);
    unsigned* arr=&v[0];
    for(unsigned i=2;i<size;++i)//ищем очередное не вычеркнутое число
        if(!get_bit(i, arr))//в i очередное простое число
            for(unsigned n=i+i;n<size;n+=i)//вычеркиваем все кратные данному числу
                set_bit(n, arr);
    std::cout<<timer.time()<<"\n";
    return 0;
}

; 65   :     unsigned size=1000000000;
; 66   :     std::vector<unsigned> v(size/bits+1);

    lea    edx, DWORD PTR $T72444[esp+76]
    push    edx
    xor    esi, esi
    push    31250001                ; 01dcd651H
    lea    ecx, DWORD PTR _v$[esp+84]
    mov    DWORD PTR $T72444[esp+84], esi
    call    ?_Construct_n@?$vector@IV?$allocator@I@std@@@std@@QAEXIABI@Z ; std::vector<unsigned int,std::allocator<unsigned int> >::_Construct_n

; 67   :     unsigned* arr=&v[0];
; 68   :     for(unsigned i=2;i<size;++i)//ищем очередное не вычеркнутое число

    mov    edi, DWORD PTR _v$[esp+80]
    mov    DWORD PTR __$EHRec$[esp+84], esi
    mov    esi, 2
    npad    6
$L72548:

; 69   :         if(!get_bit(i, arr))

    mov    ecx, esi
    and    ecx, 31                    ; 0000001fH
    mov    eax, 1
    shl    eax, cl
    mov    ecx, esi
    shr    ecx, 5
    test    eax, DWORD PTR [edi+ecx*4]
    jne    SHORT $L64574

; 70   :         {
; 71   :             //в i очередное простое число
; 72   :             for(unsigned n=i+i;n<size;n+=i)//вычеркиваем все кратные данному числу

    cmp    esi, 500000000                ; 1dcd6500H
    lea    edx, DWORD PTR [esi+esi]
    jae    SHORT $L64574
$L72547:

; 73   :                 set_bit(n, arr);

    mov    ecx, edx
    and    ecx, 31                    ; 0000001fH
    mov    eax, edx
    mov    ebp, 1
    shl    ebp, cl
    shr    eax, 5
    mov    ecx, DWORD PTR [edi+eax*4]
    add    edx, esi
    or    ecx, ebp
    cmp    edx, 1000000000                ; 3b9aca00H
    mov    DWORD PTR [edi+eax*4], ecx
    jb    SHORT $L72547
$L64574:

; 67   :     unsigned* arr=&v[0];
; 68   :     for(unsigned i=2;i<size;++i)//ищем очередное не вычеркнутое число

    inc    esi
    cmp    esi, 1000000000                ; 3b9aca00H
    jb    SHORT $L72548


8.45668


G>Не, у меня в тот раз была асимптотика O(N*sqrt(N)) — я делал отсечку по sqrt. А перебирал с шагом 4-6-4-6-4-6...

Да я не про твою, а про тот тест который лежит тут
... << RSDN@Home 1.1.4 rev. 185 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[10]: ФП: вводная статья
От: Gaperton http://gaperton.livejournal.com
Дата: 28.09.04 15:27
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, Gaperton, Вы писали:


G>>Я тоже хочу именно этого. Приступим. Вот дословный перевод твоего алгоритма на Clean.

WH>Так так... Деструктивное изменение массива... те от функционального языка остался только синтаксис...
Не так. Деструктивное изменение массива происходит в том случае, если не остается ссылок не старый массив, что и имеет место быть (в Clean это проверяется на этапе компиляции, поэтому программист может на это рассчитывать). Так что функциональная семантика полностью сохраняется. Программа чисто функциональна, и лишена побочных эффектов.

G>>Давай мы все-таки не будем меряться скоростью свопа и количеством оперативки, хорошо?

WH>А у тебя что меньше ста дватцати метров?
Нет, дело в том, что компилятор Clean не умеет паковать unboxed bool массивы в битовые маски, вот и все. Так что у меня это гиг. В теории, это поправимо, нет серьезных причин мешающих добавить эту оптимизацию в компилятор.

G>>23.59 секунд на моей системе.

WH>Execution: 21.31 Garbage collection: 0.21 Total: 21.53 и примерно 290 метров памяти.
WH>Моя программа
WH>8.66727 и примерно 12.8 метров памяти.
В 2.5 раза быстрее. Вполне адекватно. Я, правда, рассчитывал на проигрыш максимум вдвое. У них видимо большой оверхэд на управление памятью. На самом деле, нет никаких принципиальных проблем, мешающих сгенерировать эффективный код по приведенной программе на Clean. Кстати, не хочешь померять на векторе char вместо bool? Просто любопытно, как изменится скорость.

WH>Хотя если выкинуть std::vector<bool> и работать с битами ручками то получается лучше хотя и не на много

Ну ты еще SSE2 c MMX поюзай. Пишем обычный гражданский код, нечего тут
Re[10]: ФП: вводная статья
От: Gaperton http://gaperton.livejournal.com
Дата: 28.09.04 17:39
Оценка:
Здравствуйте, WolfHound, Вы писали:

G>>23.59 секунд на моей системе.

WH>Execution: 21.31 Garbage collection: 0.21 Total: 21.53 и примерно 290 метров памяти.
WH>Моя программа
WH>8.66727 и примерно 12.8 метров памяти.

Чудеса оптимизации.

sieve primes i
    | i == Size    = primes
     | primes.[ i ] = sieve { primes & [ n * i ] = False \\ n <- [ 2.. (Size - 1)/i ] } ( i + 1 )
                        = sieve primes ( i + 1 )


Что сделано: заменяем [ 2*i, 3*i..Size-1 ] на [ 2..(Size — 1)/i ].

15.67 секунд, 98 мегов памяти. Вот теперь все нормально.
У тебя на компе будет ~14.16 секунд. Против 8.66 твоих. Теперь ты примерно в 1.6 раз быстрее. А разница в расходе памяти объясняется только отсутствием упаковки bool массивов. Т. е. все в порядке. Хотя такие вещи компилятор мог бы делать и сам. Ну как, сделаешь версию на char?

экзешник я заменил на новый.
Re: ФП: БИБЛИОТЕКИ???
От: Дм.Григорьев  
Дата: 28.09.04 18:19
Оценка:
Здравствуйте, Quintanar, Вы писали:

[skipped]

Прочитал с интересом почти все (и в этой теме, и в флейме про ФЯ), кое-что даже понял, и созрел у меня серьезный вопрос: БИБЛИОТЕКИ??? Работа с файлами, GUI, TCP-сокеты, интерфейсы к базам данных, написание служб NT, multitier, и т.д., и т.п. Реально на нынешних ФЯ написать реальные программы? А то все эти демонстрации возможностей смахивают больше на школьный курс программирования, или на фортран в руках математика:

10 input(n)
20 длинный алгоритим без ввода-вывода
1000 output(s)


Не выльется ли разработка скажем простейшей складской программы для малого предприятия в извращение, вроде моих отчаянных попыток использовать XML-файлы в веб-сайтах любой сложности, чтобы не связываться с непонравившимся мне MySQL?
http://dimgel.ru/lib.web — thin, stateless, strictly typed Scala web framework.
Re: ФП: вводная статья
От: Banch  
Дата: 28.09.04 18:21
Оценка: 1 (1) +1
Здравствуйте, Quintanar, Вы писали:

несколько раз читал всякие вводные статьи по ФЯ и так ничего и не понял, потому что в какой-то момент автор вводил какую-нть закорюку и забывал ее объяснить, а потом оказывалось что на ней то все и строиться

немного моих вопросов, заранее прошу прощения если тупых:

Q>Вторым важным конструктором новых типов является кортеж (tuple). Это всего лишь набор разнотипных значений

Q>вроде
Q>
Q>(1,"str",'a')
Q>

Q>Кортежы используются для возвращения из функций нескольких значений, определения сложных типов типа деревьев
Q>или списков и т.п.

и чем тогда кортеж отличается от списка?
как я в структуре типа дерево отлечу какой элемент кортежа относиться к какой ветке? по индексу в кортеже?

Q>Например, определим тип для выражения

Q>в языке программирования
Q>
Q>data Expr = Var String | Integer Int | Str String | Assign Var Expr | Func Var [Expr]
Q>


что означает эта строка?
ну первую часть я кажется понял, но все равно не уверен

Q>Var, Integer, Str, Func и Assign — это так называемые конструкторы типа. С их помощью можно создать

Q>значение типа Expr
Q>
Q>Assign (Var "my_var") (Func (Var "my_func") [(Str "str"),(Integer 10)])
Q>

Q>Возможности впечатляют, однако, это еще не все.

какие возможности? написать нечитаемый ужас из смеси скобок?

Q>имеет тип

Q>
a->>[a]
Q>


хм, что это за тип?

Q>
Q>my_func my_func2
Q>my_func:(my_func my_func2)
Q>


что это за выражения? что в них написано?

Q>Остается добавить, что отдельные ФЯ расширяют стандартную систему типов разными способами. Например, в

Q>OCaml добавлены классы, а в Haskell'e существуют классы типов, которые чем-то похожи на интерфейсы в ООП
Q>языках.

а как тогда быть с бизнес объектами?
как разбивать логику?
с математическими задачами я примерно понял, действительно удобно

Q>Имея эту функцию мы можем создать новые функции типа

Q>
Q>inc x = add 1 x
Q>add10 x = add 10 x
Q>

Q>первая из которых увеличивает свой аргумент на 1, а вторая на 10. Разница с обычным вызовом более
Q>общей подфункции с некоторыми фиксированными аргументами заключается в том, что функция add 1 будет
Q>частично вычислена один раз и при дальнейших вызовах перевычислятся не будет.

не понял что там можно частично вычислить в выражении add 1 ?? заранее вычислить что 1 это 1 ?!
даже допустим там стоит не 1, а sqrt(2), ну и что — я могу положить это один раз в статическую переменную


Кроме того хотелось бы каких-нть реалистичных примеров, которые трудно или громоздко реализовать с помощью ИЯ (реализацию на ИЯ обязательно нужно тоже привести, причем несколько человек должны на этот код посмотреть и сказать что он действительно написан хорошо и довольно оптимально) и подробнейшего описания к этим примерам, до последней запятой, потому что, как я понял, любой знак в ФЯ может иметь кардинальное значение: за ним может стоять целая теория, мега базовая функциональность системы или библиотека.
Я понимаю что многого хочу, но если есть желание объяснять, то я готов разбираться
Re[2]: ФП: вводная статья
От: Дм.Григорьев  
Дата: 28.09.04 18:29
Оценка:
Здравствуйте, Banch, Вы писали:

B>немного моих вопросов, заранее прошу прощения если тупых:

B>[]

+1. Мне тоже интересно. Вводная статья не должна быть написана в предположении, что о синтаксических и прочих ньюансах читатели сами догадаются.
http://dimgel.ru/lib.web — thin, stateless, strictly typed Scala web framework.
Re[11]: ФП: вводная статья
От: WolfHound  
Дата: 28.09.04 20:03
Оценка: 12 (1)
Здравствуйте, Gaperton, Вы писали:

G>Чудеса оптимизации.

хъ
G>15.67 секунд, 98 мегов памяти. Вот теперь все нормально.
Гы!
G>У тебя на компе будет ~14.16 секунд. Против 8.66 твоих. Теперь ты примерно в 1.6 раз быстрее.
У меня Execution: 13.85 Garbage collection: 0.00 Total: 13.85
G>А разница в расходе памяти объясняется только отсутствием упаковки bool массивов.
Я тебе больше скажу... Этим же объясняется и разрыв в производительности... См ниже...
G>Ну как, сделаешь версию на char?
Сделал... Блин я чуть со стула не упал... 13.5022
int main()
{
    timer_t timer;
    unsigned size=100000000;
    std::vector<char> is_prime(size, true);    //помечаем все числа как простые
    for(unsigned i=2;i<size;++i)            //ищем очередное не вычеркнутое число
        if(is_prime[i])                        //i очередное простое число
            for(unsigned n=i+i;n<size;n+=i)    //вычеркиваем все числа кратные данному числу
                is_prime[n]=false;
    std::cout<<timer.time()<<"\n";
}

Хотя код получился на много меньше и с виду быстрее...
; 34   :     unsigned size=100000000;
; 35   :     std::vector<char> is_prime(size, true);    //помечаем все числа как простые

    lea    edx, DWORD PTR $T72542[esp+72]
    push    edx
    push    100000000                ; 05f5e100H
    lea    ecx, DWORD PTR _is_prime$[esp+80]
    mov    BYTE PTR $T72542[esp+80], 1
    call    ?_Construct_n@?$vector@DV?$allocator@D@std@@@std@@QAEXIABD@Z ; std::vector<char,std::allocator<char> >::_Construct_n

; 36   :     for(unsigned i=2;i<size;++i)            //ищем очередное не вычеркнутое число

    mov    esi, DWORD PTR _is_prime$[esp+76]
    mov    DWORD PTR __$EHRec$[esp+80], 0
    mov    ecx, 2
    npad    5
$L64503:

; 37   :         if(is_prime[i])                        //i очередное простое число

    cmp    BYTE PTR [esi+ecx], 0
    je    SHORT $L64504

; 38   :             for(unsigned n=i+i;n<size;n+=i)    //вычеркиваем все числа кратные данному числу

    cmp    ecx, 50000000                ; 02faf080H
    lea    eax, DWORD PTR [ecx+ecx]
    jae    SHORT $L64504
$L64508:

; 39   :                 is_prime[n]=false;

    mov    BYTE PTR [esi+eax], 0
    add    eax, ecx
    cmp    eax, 100000000                ; 05f5e100H
    jb    SHORT $L64508
$L64504:

; 36   :     for(unsigned i=2;i<size;++i)            //ищем очередное не вычеркнутое число

    inc    ecx
    cmp    ecx, 100000000                ; 05f5e100H
    jb    SHORT $L64503

Но оказывается узкое место ПАМЯТЬ...
Теперь понятно почему ручная работа с битами практически не сказалась на производительности...
... << RSDN@Home 1.1.4 rev. 185 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[5]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.09.04 20:03
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Удивительно, но у Кнута тогда он тоже перевран.


На память говорить не хорошо, но вроде бы был верным. Уж точно сортировка была по месту. К тмоу же у алгоритма есть автор. И кнут к нему не имеет ни малейшего отношения. Так что классический, есть классический.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.09.04 20:03
Оценка:
Здравствуйте, Quintanar, Вы писали:

Q>В OCaml есть парсер P4, с помощью которого можно сделать свой собственный синтаксис — хочешь императивный, хочешь функциональный.


И все же заявляя о краткости хорошо бы сравнивать идентичные по смыслу и скоростным характеристикам алгоритмы. А то введя несколько функций в ИЯ тоже без труда можно сделать запись очень короткой, вот только скоростные характеристики будут уже не те.

В С++, в конце концов, тоже есть препроцессор с помощью которого и какой-то матери много чего можно сильно сократить. Только это уже не совсем выражение алгоритма на языке. К тому же пример был на Хаскеле, как я понимаю...
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.09.04 20:03
Оценка:
Здравствуйте, Nick_, Вы писали:

VD>>Многое же выдаваемое за достоинство ФЯ на самом деле является всего лишь фичами конкретных языков и без проблем может быть реализовано (да и реализуется) на ИЯ.


N_>Голодная кума Лиса залезла в сад,

N_> В нем винограду кисти рделись.
N_> У кумушки глаза и зубы разгорелись;
N_>А кисти сочные как яхонты горят;
N_> Лишь то беда, висят они высоко:
N_> Отколь и как она к ним ни зайдет,
N_> Хоть видит око,
N_> Да зуб неймет.
N_> Пробившись попусту час целой,
N_>Пошла и говорит с досадою: "Ну, что ж!
N_> На взгляд-то он хорош,
N_> Да зелен — ягодки нет зрелой:
N_> Тотчас оскомину набьешь".

Ну, что же... достойный уход от дисскусси. Коне дет аргументов в бой идут аллегории. Так?
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.09.04 20:03
Оценка:
Здравствуйте, INTP_mihoshi, Вы писали:

_>>>Вообщем pattern matching -та черта ФЯ полезность которой не вызывает сомнений

VD>>+1

INT>Опять же, является ли это чертой именно ФЯ...


Ну, в принцпе зачатки есть в С++. Но в большей степени они реализуется в ФЯ, да и само наличие pattern matching уже приводит к улучшению создания кода в функциональном стиле.

INT>Поддержка компилятора и распараллеливания разруливание ручками под каждую кончигурацию машины?


Нет. Очень многое делается в автомате. Нужно только указать, что вот эту часть кода (обычно цикл) нужно распараллелить. Понятно что недеструктивные вычисления упрощают задачу, но и только. Сам принцип распространим и на ИЯ.

INT>Или ты хочешь сказать, что на C или C++ можно написать код, который компилятор сам эффективно распараллелит?


Мы ту недавно опубликовали статью на эту тему. Проще прочесть ее чем обсуждать
Автор(ы): Intel Corporation
Дата: 05.08.2004
Эта статья предоставлена Intel как часть программы для разработчиков Intel Developer Services. Участникам программы предоставляется доступ к полной версии этой и других статей. Чтобы стать участником программы, достаточно зарегистрироваться на нашем сайте по адресу http://rsdn.ru/article/baseserv/intel/reg.aspx.
.

INT>Обычно на функциональных языках. Хотя бывают варианты. В Ocaml есть и чисто камшловый парсер, и парсер со вставками на C.


Ну, создаются же? Зачем, если все так пушисто и без них?

INT>Я бы сказал, функции высшего порядка и высокий уровень абстракции.


Можно сказать и так. Тут бесспорно у ФЯ есть явные преимущества перед ИЯ.

INT> Функциональные языки оперируют наиболее простыми единицами языка — значениями, множествами(т.е. типами) и отображениями (функциями). Все что нужно, ничего лишнего. На этом уровне инкапсуляция иполиморфизм получается гораздо лучше чем в ООП


Вот это уже спорно.

INT> — программа состоит как правило из меньших и менее связанных элементов, чем программа в объектном стиле.


Возможно. Но воспринимать функциональную запись сложно. Особенно если нет должной тренировки. А между тем полезные (с моей точки зрения) фичи ФЯ можно применять и с использыванием куда более интуитивно понятного синтаксиса. Более того. По-моему, нет особых пролем красиво сопрягать декларативных стиль кодирования и императивную реализацию. Грубо говоря декларативные вещи можно описывать в виду императивных алгоритмов, а потом использовать в чисто деларативном стиле. Это с одной стороны похоже на ФЯ, так как использует похожие принцип, но с другой несклько иная концепция и реализация. Но в итоге язык позволяющий объявлять чистые абстракции может давать значительно более понятный код. Ведь не нужно подстравиваться под принципы записи и ограничения. Вместо этого просто можно подстраивать сам язык. Собствнно это то, что мы хотим реализовать в R#-е. Думаю, что и многие функциональные фичи можно будет реализовать таким образом. Возможно я и не прав, но пока что эта идея мне кажется верной и я не вижу серьезной аргументации опровергающей ее.

ЗЫ

В общем, по-моему, ключевым моментом является именно повышение уровня абстракции и тут ФЯ, ЛЯ, ООП, АОП и то что хочется сделать мне пересекается. Так что есть о чем поговорить. Вот только хотелось бы без издевок и наездов. А то я тоже быстро завожусь.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.09.04 20:03
Оценка:
Здравствуйте, Quintanar, Вы писали:

Q> А вот как выглядит монадный LL парсер написанный с помощью небольшой библиотеки базовых функций. Обрати внимание, что все детали реализации скрыты в монадах и остается только суть — сама граматика.


Да, согласен, не плохо. Но все же это не EBNF. Много лишней шелухи, другой синтаксис. Да и наверняка будет проблемы с отделением продукций от генерируемого АСТ. Вот собственно и хотелось бы заполучить продукт не имеющий вообще ограничений подобного рода (или хотя бы сводящий их к минимуму).

Q>Исходники библиотеки, кстати, можно изучить за час — два, настолько она проста.


Q>Здесь только часть парсера, чтобы была понятна идея. Думаю, надо написать LL парсер C# на Haskell'e и сравнить с вашей реализацией.


Ну, это явно не Шарп. Скорее похоже на Яву, да и то с горой ошибок и упущений. Из-за непривычного синтаксиса сразу сказать затрудняюсь. Граматика для LL(k)-парсера в формате EBNF (точнее генератора парсеров на C# CocoR) можно взять тут: http://gzip.rsdn.ru/projects/RSharp/vcs.aspx (там лежит граматика для C# 2.0).

Чистым LL(1) Шарп не парсится в принципе. Да и с нечистым возникают проблемы так как в языке есть контекстно-зависимые ключевые слова.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: ФП: вводная статья
От: FR  
Дата: 28.09.04 20:29
Оценка:
Здравствуйте, VladD2, Вы писали:


VD>Возможно. Но воспринимать функциональную запись сложно. Особенно если нет должной тренировки. А между тем полезные (с моей точки зрения) фичи ФЯ можно применять и с использыванием куда более интуитивно понятного синтаксиса. Более того. По-моему, нет особых пролем красиво сопрягать декларативных стиль кодирования и императивную реализацию. Грубо говоря декларативные вещи можно описывать в виду императивных алгоритмов, а потом использовать в чисто деларативном стиле. Это с одной стороны похоже на ФЯ, так как использует похожие принцип, но с другой несклько иная концепция и реализация. Но в итоге язык позволяющий объявлять чистые абстракции может давать значительно более понятный код. Ведь не нужно подстравиваться под принципы записи и ограничения. Вместо этого просто можно подстраивать сам язык. Собствнно это то, что мы хотим реализовать в R#-е. Думаю, что и многие функциональные фичи можно будет реализовать таким образом. Возможно я и не прав, но пока что эта идея мне кажется верной и я не вижу серьезной аргументации опровергающей ее.


В последних версиях питона это практически реализовано.
Re[10]: ФП: вводная статья
От: Sinclair Россия https://github.com/evilguest/
Дата: 29.09.04 06:20
Оценка: +1
Здравствуйте, FR, Вы писали:

FR>просто ты не хочешь признать что императивный язык тоже может быть декларативным.

Увы. Самое главное — в твоем коде нет изменения состояния. Ты выразил именно зависимость между входом и выходом. А эквивалентность этого некоторому конкретному ходу исполнения императивной программы — не более чем забавный факт. В коде с циклом изменение состояния уже есть, поскольку можно фиксировать квантованные шаги, на которых ltList неполон. Т.е. в таком случае машина вынуждена делать определенные элементарные действия в определенном порядке.

Примеры функционально плоховыразимых задач лежат не здесь. Пока состояние маленькое, можно пользоваться семантикой копирования. В конце концов, есть алгоритмы SSA и SSI, которые превращают любую императивную программу в функциональную.
Что мне пока не очень ясно, так это как можно применять ФП для Enterprise — приложений. Ну вот типа есть у нас БД гигов на восемь-двенадцать. Нет, конечно формально мы можем функцию регистрации заказа определить как отображение одной БД на другую БД, в которой отличается только остаток товара на конкретном складе. Но как сделать СУБД, способную понять взаимозависимости между параллельно выполняемыми запросами в ФП-стиле, я понять не могу.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: ФП: вводная статья
От: INTP_mihoshi Россия  
Дата: 29.09.04 07:20
Оценка: 4 (1)
Здравствуйте, Banch, Вы писали:

Q>>Кортежы используются для возвращения из функций нескольких значений, определения сложных типов типа деревьев

Q>>или списков и т.п.
B>и чем тогда кортеж отличается от списка?
Кортеж, он же tuple.
В данном случае — конечная последовательность значений. Отличается от списка тем, что кол-во элементов фиксировано и типы значений могут быть различными. От Cшной структуры отлисается тем, что элементы различаются по порядку, а не по имени.

Тип аргумента соответствует последовательности типов аргументов. Например, тип кортежа (1, 1., "1") равен int*float*string. Элементы из кортежа достаются обычно с помощью pettern-matching. Например:


let (min,max) = (main_and_max_of_list somelist) in
print_int min; 
print_int max;


B>как я в структуре типа дерево отлечу какой элемент кортежа относиться к какой ветке? по индексу в кортеже?

Примерно так. Например: let (leftleaf, rightleaf) = leafs_of node ...

Q>>
Q>>data Expr = Var String | Integer Int | Str String | Assign Var Expr | Func Var [Expr]
Q>>


B>что означает эта строка?

B>ну первую часть я кажется понял, но все равно не уверен

Это т.н. variant. Что-то типа Сшного union, но с известным типом текущего значения.
type expr = Integer of Int | Str of String | Assign of expr * expr обозначает, что значение типа Expr может быть равно Var строчка, Str строчка, Integer целое и т.д.


string_of_expr expr = match expr with
  |Var v -> "variable %s" v
  |Str v -> "string %s" v
  |Int v -> "integer %d" v
  |Assign lv rv -> sprintf "let %d = %d" (string_of_expr lv) (string_of_expr rv)
  | _ -> "don't know how to write it"


Вобщем, в языках со строгой типизацией вместо enum и union используются variant.


Q>>имеет тип

Q>>
a->[a]
Q>>


B>хм, что это за тип?


Отображение значения типа а в список значений типа а. В Ocaml перед a стоял бы апостроф, обозначающий, что a — произвольный тип, а не какой-то известный тип, названный a.

B>а как тогда быть с бизнес объектами?

B>как разбивать логику?
B>с математическими задачами я примерно понял, действительно удобно
Разбивать, как всегда, по модулям.

B>не понял что там можно частично вычислить в выражении add 1 ?? заранее вычислить что 1 это 1 ?!

B>даже допустим там стоит не 1, а sqrt(2), ну и что — я могу положить это один раз в статическую переменную

Нет, add 1 — это функция одного аргумента, возвращающая сумму его с 1.
Т.е., если мы даем функции меньше аргументов, чем необходимо, то получаем такую же функцию, но с уже известной частью аргументов. Вообще это иногда полезный побочный эффект карринга. Вобщем, того же эффекта можно добиться другими способами. Например, следующие определения совершенно эквивалентны
let inc v = add 1 v

let inc = add 1
Re[11]: ФП: вводная статья
От: FR  
Дата: 29.09.04 07:52
Оценка: +1
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, FR, Вы писали:


FR>>просто ты не хочешь признать что императивный язык тоже может быть декларативным.

S>Увы. Самое главное — в твоем коде нет изменения состояния. Ты выразил именно зависимость между входом и выходом. А эквивалентность этого некоторому конкретному ходу исполнения императивной программы — не более чем забавный факт. В коде с циклом изменение состояния уже есть, поскольку можно фиксировать квантованные шаги, на которых ltList неполон. Т.е. в таком случае машина вынуждена делать определенные элементарные действия в определенном порядке.

На эту конструкцию можно смотреть с двух сторон, и я не думаю что один взгляд правильнее другого.
Re[2]: ФП: БИБЛИОТЕКИ???
От: Quintanar Россия  
Дата: 29.09.04 08:47
Оценка:
Здравствуйте, Дм.Григорьев, Вы писали:

ДГ>Прочитал с интересом почти все (и в этой теме, и в флейме про ФЯ), кое-что даже понял, и созрел у меня серьезный вопрос: БИБЛИОТЕКИ??? Работа с файлами, GUI, TCP-сокеты, интерфейсы к базам данных, написание служб NT, multitier, и т.д., и т.п. Реально на нынешних ФЯ написать реальные программы? А то все эти демонстрации возможностей смахивают больше на школьный курс программирования, или на фортран в руках математика:


У всех серьезных языков есть стандартные библиотеки, которые включают в себя всякие базовые нужные функции, работу с файлами, различными типами данных, системой, сетью. Есть, как правило, возможность использовать GUI типа TCL/TK. Есть и сторонние библиотеки, но их надо скачивать отдельно, где реализованы более специфические вещи типа Corba, DB и т.п. Если библиотеки нет, можно использовать внешние С-шные модули, они подключаются без особых трудозатрат.
Re[2]: ФП: вводная статья
От: Quintanar Россия  
Дата: 29.09.04 09:57
Оценка: 11 (2)
Здравствуйте, Banch, Вы писали:

B>и чем тогда кортеж отличается от списка?

B>как я в структуре типа дерево отлечу какой элемент кортежа относиться к какой ветке? по индексу в кортеже?

Кортеж имеет фиксированную длину и элементы в нем могут быть разных типов. В ИЯ его аналогом являются структуры. Доступ к элементам кортежа осуществляется с помощью pattern matching
let (x,y,z) = ("a",(1,'a'),'b')

здесь x будет связано со значением "a", y = (1,'a'), z = 'b'.
С деревом аналогично:
data Tree = Node Tree Tree | Leaf Int
do_something tree = 
  case tree of
    Node left right -> ...
    Leaf value -> ...


Q>>
Q>>data Expr = Var String | Integer Int | Str String | Assign Expr Expr | Func Expr [Expr]
Q>>

B>что означает эта строка?
B>ну первую часть я кажется понял, но все равно не уверен

Это объявление сложного типа Expr. Такая запись означает, что Expr может быть равен Var String, Integer Int и т.д. Первое имя в такой записи — конструктор типа, по которому мы можем в дальнейшем распознать чему равен Expr (как выше в примере с деревом), создать соответствующее значение этого типа (Var "my_var", например). Дальше идут типы аргументов конструктора типа. Запись Var String означает, что конструктор Var принимает аргумент типа String и создает значение типа Expr. Func Expr [Expr] значит, что конструктор Func принимает два аргумента типа Expr и список из Expr и создает значение типа Expr. Таким образом Expr может быть равен некоторой строке, целому, паре двух Expr'ов и т.д. Т.е. его можно представлять себе как объединение нескольких структур и простых типов, где доступ к различным элементам union осуществляется с помощью конструкторов типа.
union Expr = {
  Var : String,
  Integer : Int,
  Str : String,
  Assign: { Expr, Expr },
  Func : { Expr, [Expr] }
}


Q>>
Q>>Assign (Var "my_var") (Func (Var "my_func") [(Str "str"),(Integer 10)])
Q>>

B>какие возможности? написать нечитаемый ужас из смеси скобок?

Это пример. Руками это создавать вовсе не обязательно, можно прочитать из файла, сгенерировать или еще как нибудь. Возможности заключаются в простой работе со сложными стуктурами типа такой. Ее легко создать, ее легко разделить на части с помощью pattern matching.

Q>>
a->[a]
Q>>

B>хм, что это за тип?

У каждой переменной или функции есть тип. Записывается он следующим образом:
Если у переменной тип простой и заранее известный, то так и пишется — Int, String ...
Если тип переменной неизвестен, то пишется — a,b,c,... (или `a,`b... в зависимости от языка)
Если тип параметризирован, то пишется вместе с параметрами — [a], Tree Int, (Int, String) ...
[a] — список неизвестного типа, Tree Int — Дерево из Int'ов.
Если есть функция с n параметрами, то ее тип записывается следующим образом:
type of arg1 -> type of arg2 -> ... -> type of argn -> type of result
Для функции сложения тип будет такой — Int->Int->Int
Для функции добавления элемента в список — a->[a]->[a]
Для функции возвращающей первый элемент бинарного кортежа — (a,b)->a

Q>>
Q>>my_func my_func2
Q>>my_func:(my_func my_func2)
Q>>

B>что это за выражения? что в них написано?

my_func создает список состоящий из одного элемента = ее аргументу => в данном случае создается список функций, в котором лежит одна функция my_func2. Во втором случае в этот список добавляется второй элемент — сама функция my_func. Выглядит забавно, но зато демонстрирует, что мы можем свести полиморфный тип к более узкому типу (my_func имеет тип a->[a], а список состоит из элементов типа Expr->[Expr]).

B>а как тогда быть с бизнес объектами?

B>как разбивать логику?
B>с математическими задачами я примерно понял, действительно удобно

Приведи пример разбиения и я скажу как это делается в ФЯ, а так сложно сказать.

B>Кроме того хотелось бы каких-нть реалистичных примеров, которые трудно или громоздко реализовать с помощью ИЯ (реализацию на ИЯ обязательно нужно тоже привести, причем несколько человек должны на этот код посмотреть и сказать что он действительно написан хорошо и довольно оптимально) и подробнейшего описания к этим примерам, до последней запятой, потому что, как я понял, любой знак в ФЯ может иметь кардинальное значение: за ним может стоять целая теория, мега базовая функциональность системы или библиотека.

B>Я понимаю что многого хочу, но если есть желание объяснять, то я готов разбираться

Это надо посмотреть.
Re[6]: ФП: вводная статья
От: Quintanar Россия  
Дата: 29.09.04 10:02
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Quintanar, Вы писали:


Q>>В OCaml есть парсер P4, с помощью которого можно сделать свой собственный синтаксис — хочешь императивный, хочешь функциональный.


VD>И все же заявляя о краткости хорошо бы сравнивать идентичные по смыслу и скоростным характеристикам алгоритмы. А то введя несколько функций в ИЯ тоже без труда можно сделать запись очень короткой, вот только скоростные характеристики будут уже не те.


VD>В С++, в конце концов, тоже есть препроцессор с помощью которого и какой-то матери много чего можно сильно сократить. Только это уже не совсем выражение алгоритма на языке. К тому же пример был на Хаскеле, как я понимаю...


Не ты не понял. Ты жаловался на то, что в OCaml трудно понимать программы. Так вот у них там есть P4, с помощью которого можно адаптировать синтаксис OCaml'a к своим нуждам. У них самих на нем сделана новая форма записи — т.е. изменен синтаксис языка без изменения самого языка.
Re[7]: ФП: вводная статья
От: INTP_mihoshi Россия  
Дата: 29.09.04 10:38
Оценка:
Здравствуйте, Quintanar, Вы писали:

Q>Не ты не понял. Ты жаловался на то, что в OCaml трудно понимать программы. Так вот у них там есть P4, с помощью которого можно адаптировать синтаксис OCaml'a к своим нуждам. У них самих на нем сделана новая форма записи — т.е. изменен синтаксис языка без изменения самого языка.


Дополню.
Препроцессор P4 в Ocaml — это не макроподстановки. Это инструмент, который работает непосредственно с синтаксисом языка. Например, он позволяет не только добавлять, но и убирать правила из грамматики.
Пример с удаленями правил можно посмотреть в туториале.
Вот простой пример добавления правил — добавление конструкции repeat/until.

       open Pcaml;;
       EXTEND
         expr: LEVEL "expr1"
           [[ "repeat"; e1 = expr; "until"; e2 = expr ->
                 <:expr< do { $e1$; while not $e2$ do { $e1$; } } >> ]];
       END;;
Re[2]: ФП: БИБЛИОТЕКИ???
От: gloomy rocker Россия  
Дата: 29.09.04 10:42
Оценка:
Здравствуйте, Дм.Григорьев, Вы писали:

ДГ>Здравствуйте, Quintanar, Вы писали:


ДГ>[skipped]


ДГ>Прочитал с интересом почти все (и в этой теме, и в флейме про ФЯ), кое-что даже понял, и созрел у меня серьезный вопрос: БИБЛИОТЕКИ??? Работа с файлами, GUI, TCP-сокеты, интерфейсы к базам данных, написание служб NT, multitier, и т.д., и т.п. Реально на нынешних ФЯ написать реальные программы? А то все эти демонстрации возможностей смахивают больше на школьный курс программирования, или на фортран в руках математика:


ДГ>
ДГ>10 input(n)
ДГ>20 длинный алгоритим без ввода-вывода
ДГ>1000 output(s)
ДГ>


ДГ>Не выльется ли разработка скажем простейшей складской программы для малого предприятия в извращение, вроде моих отчаянных попыток использовать XML-файлы в веб-сайтах любой сложности, чтобы не связываться с непонравившимся мне MySQL?


Посмотри на F#
На нем можно писать код, используя FCL, в которой собрано огромное количество велосипедов.
... << Rsdn@Home 1.1.4 beta 1 >>
Скука — двигатель прогресса.
Re[12]: ФП: вводная статья
От: Gaperton http://gaperton.livejournal.com
Дата: 29.09.04 11:48
Оценка:
Здравствуйте, WolfHound, Вы писали:

G>>У тебя на компе будет ~14.16 секунд. Против 8.66 твоих. Теперь ты примерно в 1.6 раз быстрее.

WH>У меня Execution: 13.85 Garbage collection: 0.00 Total: 13.85
G>>А разница в расходе памяти объясняется только отсутствием упаковки bool массивов.
WH>Я тебе больше скажу... Этим же объясняется и разрыв в производительности... См ниже...
G>>Ну как, сделаешь версию на char?
WH>Сделал... Блин я чуть со стула не упал... 13.5022

WH>Но оказывается узкое место ПАМЯТЬ...

Так я и предполагал, но говорить не стал — вдруг ошибусь? Ее все-таки в восемь раз активнее читать приходится, это не могло не повлиять на производительность. Но того, что это единственный значимый фактор, я, конечно, не ожидал. Прикольно.

Неплохой компилятор у Clean. Но зело глючный — писать на нем серьезные программы страшновато. У меня он на довольно простых вещах крешится.
Re[11]: ФП: вводная статья
От: Gaperton http://gaperton.livejournal.com
Дата: 29.09.04 13:47
Оценка:
Здравствуйте, Sinclair, Вы писали:

S> В коде с циклом изменение состояния уже есть, поскольку можно фиксировать квантованные шаги, на которых ltList неполон. Т.е. в таком случае машина вынуждена делать определенные элементарные действия в определенном порядке.

Нет, дело не в этом. Дело именно в наличии/отсутствии операций с модифицирующей семантикой, как ты и написал вначале. А для цикла несложно ввести нормальную функциональную семантику. Пример.

Цикл foreach приводится к такой общей форме: foreach X in C do Something( X, S ), где С — коллекция, Х — элемент, а Something изменяет состояние объекта S (побочное действие), не возвращая ничего.

1) Изменяем Something таким образом, что она возвращает новое состояние S, не меняя исходное. Snew = Something( X, S )
2) Таким образом, цикл for — это функция, преобразующая исходное состояние S в состояние Snew посредством применения серии операций Something. Что соответствует рекурсивному паттерну (Erlang):

foreach( [ X | C ], S, Something ) -> foreach( C, Something( X, S ), Something );
foreach( [], S, _ ) -> S


Собственно, все. Как видишь, здесь тоже вполне можно фиксировать квантовые шаги, в которых S (в нашем случае — ltList) неполон. И ничего. Выполняться будет совершенно идентично циклу.

S>Примеры функционально плоховыразимых задач лежат не здесь. Пока состояние маленькое, можно пользоваться семантикой копирования. В конце концов, есть алгоритмы SSA и SSI, которые превращают любую императивную программу в функциональную.

Прикольно. Ссылки приведешь?
Re[12]: ФП: вводная статья
От: Sinclair Россия https://github.com/evilguest/
Дата: 29.09.04 14:26
Оценка:
Здравствуйте, Gaperton, Вы писали:

S>>Примеры функционально плоховыразимых задач лежат не здесь. Пока состояние маленькое, можно пользоваться семантикой копирования. В конце концов, есть алгоритмы SSA и SSI, которые превращают любую императивную программу в функциональную.

G>Прикольно. Ссылки приведешь?
Э-э... пока что сам разбираюсь. Услышал ссылку на них, пока гуглю. Ключевые слова — single state assignment и single state information.
Фактически, это формализация того, что ты только что произвел "на пальцах".
P.S мне самому это требуется для преобразования кода на императивном языке (MSIL) в функциональную форму. А это, в свою очередь, надо для того, чтобы реализовать оптимизацию полиморфных запросов. На основе функционального представления будет сформирован предикат, среди термов которого придется искать допускающие индексный поиск. После оценки стоимости выполнения каждого из вариантов, надо будет сгенерировать императивный код, выполняющий index seek по выбранным термам, и вычисление остальных для каждого результатв
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[13]: ФП: вводная статья
От: Quintanar Россия  
Дата: 29.09.04 15:48
Оценка:
Здравствуйте, Gaperton, Вы писали:

WH>>Но оказывается узкое место ПАМЯТЬ...

G>Так я и предполагал, но говорить не стал — вдруг ошибусь? Ее все-таки в восемь раз активнее читать приходится, это не могло не повлиять на производительность. Но того, что это единственный значимый фактор, я, конечно, не ожидал. Прикольно.

G>Неплохой компилятор у Clean. Но зело глючный — писать на нем серьезные программы страшновато. У меня он на довольно простых вещах крешится.


На Haskell'e массивы помедленнее работают Моя программа выполнилась за 66 секунд, программа на С++ за 24. Причем пришлось попинать ghc, чтобы он улучшил скорость программы. Одна оптимизация с INLINE сократила время выполнения на 24 секунды. Так что ghc оптимизировать еще и оптимизировать. Вариант с битовыми массивами работал еще медленнее, хотя я его не оптимизировал.

import Data.Word
import Data.Array.MArray
import Data.Array.IO

type Atype = IOUArray Word32 Word8

newIOArray::(Word32, Word32) -> Word8 -> IO Atype
newIOArray = newArray

size::Word32
size = 100000000

{-# INLINE delete_elems #-}

delete_elems::Atype->Word32->Word32->IO Atype
delete_elems array i fi
    | i >= size = return array
    | otherwise =
        do
          writeArray array i 1
          delete_elems array (i+fi) fi

{-# INLINE sieve #-}

sieve::Atype->Word32->IO Atype
sieve array i
    | i == size = return array
    | otherwise =
        do
          elem <- readArray array i
          array <- if (elem == 0) then delete_elems array (i*2) i else return array
          sieve array (i+1)

main = 
    do
      array <- newIOArray (1,size) 0
      array <- sieve array 2
      return ()
Re[14]: ФП: вводная статья
От: Gaperton http://gaperton.livejournal.com
Дата: 29.09.04 16:46
Оценка:
Здравствуйте, Quintanar, Вы писали:

Q> Здравствуйте, Gaperton, Вы писали:


WH>>>Но оказывается узкое место ПАМЯТЬ...

G>>Так я и предполагал, но говорить не стал — вдруг ошибусь? Ее все-таки в восемь раз активнее читать приходится, это не могло не повлиять на производительность. Но того, что это единственный значимый фактор, я, конечно, не ожидал. Прикольно.

G>>Неплохой компилятор у Clean. Но зело глючный — писать на нем серьезные программы страшновато. У меня он на довольно простых вещах крешится.


Q>На Haskell'e массивы помедленнее работают Моя программа выполнилась за 66 секунд, программа на С++ за 24. Причем пришлось попинать ghc, чтобы он улучшил скорость программы. Одна оптимизация с INLINE сократила время выполнения на 24 секунды. Так что ghc оптимизировать еще и оптимизировать. Вариант с битовыми массивами работал еще медленнее, хотя я его не оптимизировал.


1) Попробуй пометить аргументы функций как strict. Насколько я помню, это делается так же как в Clean (!). Strictness analyzer не способен определить все strict вызовы, ему надо помочь.
2) Попробуй использовать STUArray c типом Bool(Data.Array.ST).

Может, будет лучше. А может, и нет.
Re[15]: ФП: вводная статья
От: Quintanar Россия  
Дата: 29.09.04 17:45
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>1) Попробуй пометить аргументы функций как strict. Насколько я помню, это делается так же как в Clean (!). Strictness analyzer не способен определить все strict вызовы, ему надо помочь.

G>2) Попробуй использовать STUArray c типом Bool(Data.Array.ST).


strict аргументов там нет, да и так там ничего ленивого в сущности нет. STUArray работает буквально на пару секунд побыстрее. С Bool оба массива тормозят — 1м30 и 1м28 соответственно.
Re[12]: ФП: вводная статья
От: prVovik Россия  
Дата: 29.09.04 19:46
Оценка:
Здравствуйте, WolfHound, Вы писали:

Если уж и начали мерятся скоростями, то со стороны С++ должен выступать ICC. Ибо он рулит.
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[13]: ФП: вводная статья
От: WolfHound  
Дата: 29.09.04 19:52
Оценка: +1
Здравствуйте, prVovik, Вы писали:

V>Если уж и начали мерятся скоростями, то со стороны С++ должен выступать ICC. Ибо он рулит.

Ну выступи. Ибо ICC у меня нет. К томуже на таких расчетах VC++ тоже рулит.
... << RSDN@Home 1.1.4 rev. 185 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[13]: ФП: вводная статья
От: FR  
Дата: 29.09.04 20:09
Оценка:
Здравствуйте, prVovik, Вы писали:

V>Здравствуйте, WolfHound, Вы писали:


V>Если уж и начали мерятся скоростями, то со стороны С++ должен выступать ICC. Ибо он рулит.


задача уперлась в память так что ни какой ICC не поможет.

Да всем, вам не кажется что ваши результаты имеют очень малое отношение к реальной скорости кода созданного разными компиляторами и только показывают что они способны создавать программы которые успевают просчитать элемент массива быстрее чем идет обращение к памяти(не лезущей в кеш), для получения реальных результатов быстродействия надо мерять на малых массивах.
Re[14]: ФП: вводная статья
От: prVovik Россия  
Дата: 29.09.04 20:23
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, prVovik, Вы писали:


V>>Если уж и начали мерятся скоростями, то со стороны С++ должен выступать ICC. Ибо он рулит.

WH>Ну выступи. Ибо ICC у меня нет.
А у меня тоже
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[7]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.09.04 21:53
Оценка: :)
Здравствуйте, FR, Вы писали:

FR>В последних версиях питона это практически реализовано.


Дык правильные идею очень часто приходят сразу во много голов.

Кстати, питон ведь тоже можно отнести к функциональным языкам.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.09.04 21:53
Оценка:
Здравствуйте, Quintanar, Вы писали:

Q>Не ты не понял. Ты жаловался на то, что в OCaml трудно понимать программы. Так вот у них там есть P4, с помощью которого можно адаптировать синтаксис OCaml'a к своим нуждам. У них самих на нем сделана новая форма записи — т.е. изменен синтаксис языка без изменения самого языка.


Это очень интересный подход. Я с Павлом Леоновым как раз пытаюсь создать нечто-подобне дя Шарпа.

Но все же к примеру квиксорта на Хаскеле эта информация не имеет отношения.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.09.04 21:53
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Питон позволяет писать в функциональном стиле, было-бы желание. Что мы и видим в твоем примере. Так что ФЯ здесь причем — откуда, ты думаешь, в питоне взялись list comprehensions?


А тебе не кажется, что это как раз и есть правильный подход? Ну, совмещение декларативного и императивного стилей...

Я лично вижу это совмещение так: Создается некий фрэймворк для решения конретных задач. Этот фрэймворк может содержать императивный стиль. Цель этого фрэймворка свести задачу к минимуму при этом не проиграв в производительности и функциональности.

Вот только динамическая типизация Питона и его ориентированность на интерпретацию не дают ему шанса стать серьезным универсальным языком. Ну, да идейный вклад — это уже не мало.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.09.04 21:53
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Я вот в твоем коде не вижу императивности. Причем совсем. Ты бы для начала почитал где-нибудь, что такое "функциональность", например в comp.lang.functional FAQ. Но впрочем, что это я к тебе пристаю? Не видишь — и хорошо.


Может быть ты не заметил, что ты только что задел человека. Даж если он не прав все равно можно было бы вместо надменного тона попытаться ему объяснить в чем он не прав.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.09.04 21:53
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Здравствуйте, FR, Вы писали:


FR>>то есть цикл for это теперь функциональный стиль? Спасибо не знал.

G>Функциональный стиль это теперь, как и всегда, в первую очередь — отсутствие побочных эффектов, а не наличие рекурсии со встроенными списками или отсутствие слова for в языке. Не зачто, всегда пожалуйста .

G>Кстати, слепенький я наверно. Ну не вижу я цикла for в твоем коде. А вот list comprehensions вижу, как и отсутствие побочных эффектов.

G>
G>def qsort(aList): 
G>        if not aList: 
G>                return [] 
G>        ltList=[y for y in aList[1:] if y<aList[0]] 
G>        gtList=[y for y in aList[1:] if y>=aList[0]] 
G>        return qsort(ltList)+[aList[0]]+qsort(gtList) 
G>


Ну, вот тебе те же яйца, только в профиль на шарпе:
static void Main(string[] args)
{
    List<int> list = new List<int>(new int[]{ 2, 5, 1, 4, 3, 9, 4, 7});

    List<int> result = QuickSort<int>(list);
    result.ForEach(delegate(int elem) { Console.WriteLine(elem); });
}

static List<T> QuickSort<T>(List<T> list) where T : IComparable<T>
{
    if (list.Count <= 1)
        return list;
    T mid = list[list.Count / 2];
    List<T> ltList = list.FindAll(delegate(T elem) { return elem.CompareTo(mid) < 0; });
    List<T> eqList = list.FindAll(delegate(T elem) { return elem.CompareTo(mid) == 0; });
    List<T> gtList = list.FindAll(delegate(T elem) { return elem.CompareTo(mid) > 0; });
    return Concatenate(QuickSort<T>(ltList), eqList, QuickSort<T>(gtList));
}

static List<T> Concatenate<T>(params List<T>[] lists)
{
    List<T> result = new List<T>();
    foreach (List<T> list in lists)
        result.AddRange(list);
    return result;
}


без всяких патрен-матчингов и т.п. Конкатинацию списков правда пришлось ручками дореализовывать. Да и операции со списками выглядят подлиннее так как не встренны в язык. Но по сути тоже самое. Зато нет проблем в взятии среднего элемента списка, а не первого. Правда с производительностью проблемы те же. Неоправданный заем памяти...

G>Что характерно, если ты добавишь в любой язык встроенные списки так, как это сделано в современных ФЯ, то на нем сразу станет удобно писать в функциональном стиле. Одного не понимаю, каким именно образом это порочит "светлую идею" ФЯ?


А что ее кто-то порочил?
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.09.04 21:53
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>А на самом деле это один из вариантов ZF-нотации, что и есть list comprehensions. В питоне заимствовано из функциональных языков.

G>ltList = [ y | y <- tail( aList ), y < head( aList ) ]

В любом случае синтаксис питона более понятен для не связаных с ФЯ людей.

FR>>просто ты не хочешь признать что императивный язык тоже может быть декларативным.

G>Просто ты за меня выдумываешь, что я имею в виду. Прочитай comp.lang.functional FAQ, чтобы понять, что такое функциональный стиль и при каких условиях язык можно отнести к функциональному. Питон, например, вполне можно — было-бы желание.

А шарп можно? В нем ведь тоже можно в функциональном стиле писать. Причем многие концепции ФЯ успешно эмулируются. Да и на С++ тоже...

ЗЫ

Кстати, тут одна дама, автор одного из учебников, по лиспу отнесла Питон к фнкциональным языкам.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[15]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.09.04 21:53
Оценка:
Здравствуйте, Nick_, Вы писали:

N_>Здравствуйте, FR, Вы писали:


FR>>Угу, к сожалению функциональные языки (я сейчас ocaml ковыряю) оказались не такими удобными, вроде бы и абстракция на самом деле выше, но все равно они кажутся более далекими от человеческого мышления


N_>Это только так кажется на первый взгляд.


Ага. Я даже как-то слышал, что первый взгляд он самый верный.

Если серьезно, то речь о том и идет, что синтаксис ФЯ требует "ломать голову". Я вот для себя провожу аналогию с тем же парсингом. К примеру, арифметические выражения проще записывать как леворекурсивную граматику. Но тот же метод рекурсивного спуска требует устранение левой рекурсии. Сделать это не сложно. Получающаяся при этом граматика не намного сложнее исходной. Но при этом она крайне трудно воспринимается. Ну, привык человек рассматривать выражения как "А + Б", а не как "А +Б С". Нужна нехилая тренировка чтобы не напрягаясь воспринимать такую переделанную граматику. В общем, нужно учиться переключать мозг от обычного (применяемого в жизни) стиля мышления к "нужному". И если питон позволяет поднимать уровень абстракции не заставляя при этом человека "переключать" мозг, то это замечательно.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.09.04 21:53
Оценка:
Здравствуйте, FR, Вы писали:

FR>По тестам которые ты выше привел, на другой странице я нашел тест с psyco(jit компилятор питона) у них результаты практически одинаковы с интерпретатором, у меня при включении psyco тест срабатывает в 25 раз быстрее чем интерпретируемый, если они и с остальными языками также намеряли, то доверия к ним нет никакого.


Там все еще забавнее. В ОКамле алгоритмы в императивном стиле. Возми к примеру хип-сорт. Так что... Да и редко когда код на функциональном языке оказывается сильно короче того же С. И частенько хваленый хаскель сливает по черному (например, в Spell Checker или в Word Frequency).
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[16]: ФП: вводная статья
От: Nick_ Россия  
Дата: 30.09.04 01:31
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Если серьезно, то речь о том и идет, что синтаксис ФЯ требует "ломать голову". Я вот для себя провожу аналогию с тем же парсингом. К примеру, арифметические выражения проще записывать как леворекурсивную граматику. Но тот же метод рекурсивного спуска требует устранение левой рекурсии. Сделать это не сложно. Получающаяся при этом граматика не намного сложнее исходной. Но при этом она крайне трудно воспринимается. Ну, привык человек рассматривать выражения как "А + Б", а не как "А +Б С". Нужна нехилая тренировка чтобы не напрягаясь воспринимать такую переделанную граматику. В общем, нужно учиться переключать мозг от обычного (применяемого в жизни) стиля мышления к "нужному". И если питон позволяет поднимать уровень абстракции не заставляя при этом человека "переключать" мозг, то это замечательно.


Ну во первых, наверное не синтаксис требует ломать голову. Синтаксис проще некуда.
Во вторых, любые нетривиальные задачи, которые стоят перед программистами требуют "ломать голову". И от этого по словам Брукса (Мифический человеко-месяц) никуда не деться.
Ну и в третих, то, что функциональный стиль труднее воспринимается — это не правда. Часто рекурсивные программы проще. А на императивных языках, из-за того, что рекурсия неэффективно компилируется тот же алгоритм начинает напоминать грамматику в форме Грейбах (как говорите "A +B C"). Хуже от этого может и не становится, но изящность теряется.
Если бы у вас было бы математическое образование (а похоже, что оно у вас не математическое), то вы бы когда-то изучали логику и вам было бы проще "переключать мозг" в "нужную" сторону. А пока, вы мне напоминаете того, кто всю жизнь работает с грамматиками "A +B C" и так привык к этому, что "A + B" кажентся непривычным.
Re: Вопрос о конкретных примерах
От: borisman2 Киргизия  
Дата: 30.09.04 05:30
Оценка:
У меня вопрос следующий.

Я изучал ФЯ главным образом по языку Clean. Как работвют основные конструкции, что почем, я понял. Однако куда реально это применить — не знаю.

Иными словами, необходимы конкретные примеры применения ФЯ как внутри ИЯ проектов, так и в самостоятельных проектах, полностью написанных на ФЯ.
Re[12]: ФП: вводная статья
От: FR  
Дата: 30.09.04 05:57
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Кстати, тут одна дама, автор одного из учебников, по лиспу отнесла Питон к фнкциональным языкам.


При желании наверно можно, но питон как и C++ мультипарадигменный. Хотя так и ocaml можно отнести к императивным
Re[17]: ФП: вводная статья
От: FR  
Дата: 30.09.04 05:57
Оценка: :)
Здравствуйте, Nick_, Вы писали:


N_>Ну во первых, наверное не синтаксис требует ломать голову. Синтаксис проще некуда.


Не синтаксис, а процесс программирования. Мне сейчас функциональные языки в этом отношении кажутся похожими на forth, написание любой программки это тренинг мышления, попытка понять через месяц что написал тоже

N_>Во вторых, любые нетривиальные задачи, которые стоят перед программистами требуют "ломать голову". И от этого по словам Брукса (Мифический человеко-месяц) никуда не деться.

N_>Ну и в третих, то, что функциональный стиль труднее воспринимается — это не правда. Часто рекурсивные программы проще. А на императивных языках, из-за того, что рекурсия неэффективно компилируется тот же алгоритм начинает напоминать грамматику в форме Грейбах (как говорите "A +B C"). Хуже от этого может и не становится, но изящность теряется.
N_>Если бы у вас было бы математическое образование (а похоже, что оно у вас не математическое), то вы бы когда-то изучали логику и вам было бы проще "переключать мозг" в "нужную" сторону. А пока, вы мне напоминаете того, кто всю жизнь работает с грамматиками "A +B C" и так привык к этому, что "A + B" кажентся непривычным.

По математике, я нормально воспринимаю мат. символику, и раньше немного программировал на Прологе, вот пролог почем-то у меня не вызвал никакого оторжения было сначало непривычно а потом наооборот легко.
Re[2]: Вопрос о конкретных примерах
От: FR  
Дата: 30.09.04 06:02
Оценка:
Здравствуйте, borisman2, Вы писали:

B>У меня вопрос следующий.


B>Я изучал ФЯ главным образом по языку Clean. Как работвют основные конструкции, что почем, я понял. Однако куда реально это применить — не знаю.


Вот у меня тоже самое, правда только с ocaml.
Правда на ocaml можно и императивно писать, но бессмысленно C++ лучше приспособлен для этого.


B>Иными словами, необходимы конкретные примеры применения ФЯ как внутри ИЯ проектов, так и в самостоятельных проектах, полностью написанных на ФЯ.


и желательно не очень большие примеры.
Re[18]: ФП: вводная статья
От: INTP_mihoshi Россия  
Дата: 30.09.04 06:49
Оценка: :)
Здравствуйте, FR, Вы писали:

N_>>Ну во первых, наверное не синтаксис требует ломать голову. Синтаксис проще некуда.

Да.

FR>Не синтаксис, а процесс программирования. Мне сейчас функциональные языки в этом отношении кажутся похожими на forth, написание любой программки это тренинг мышления,

Да.

FR>попытка понять через месяц что написал тоже

Нет.

Стиль синтаксиса С++ просто не подходит для ФЯ. Хотя бы потому, что у ФЯ с С++оидами довольно мало общего и для большинства элементов языка просто нет эквивалентов.

FR>По математике, я нормально воспринимаю мат. символику, и раньше немного программировал на Прологе, вот пролог почем-то у меня не вызвал никакого оторжения было сначало непривычно а потом наооборот легко.


С ФЯ будет точно так же Меня поначалу Хаскелевские конструкции вроде [ x | xs <- [ [(1,2),(3,4)], [(5,4),(3,2)] ],
(3,x) <- xs ] тоже пугали, а теперь в Ocamlе их очень не хватает.

Позволю себе привести цитату из Капитана Врунгеля

Поразмыслив над этим, я решил было вовсе изгнать все морские термины
из своего лексикона, заменив их теми словами, которые с давних пор су-
ществуют в обычном нашем живом языке.
Результат, однако, получился весьма нежелательный: первая же лекция,
прочитанная мною в соответствии с принятым решением, доставила много не-
нужных огорчений как мне, так и моим слушателям.
Начать с того, что лекция эта продолжалась втрое дольше против обыч-
ной, ибо оказалось, что в морском языке есть немало терминов, вовсе не
имеющих замены. Я же, не желая отступать от принятого решения, каждый
раз пытался заменить эти термины их пространными толкованиями. Так, к
примеру, вместо слова рея я каждый раз говорил: "Круглая деревянная бал-
ка, несколько утолщенная в средней части, горизонтально подвешенная на
высоком тонком столбе, вертикально установленном на судне..." Вместо
слова руль я принужден был повторять: "Вертикальная пластина, с помощью
рычага или нового специального привода поворачивающаяся на вертикальной
оси, укрепленной на подводной части задней оконечности судна, служащая
для изменения направления движения последнего..."
Сожалея при этом о напрасной трате времени, потребного для неоднок-
ратного произнесения этих определений, я старался выговаривать их одним
духом, скороговоркою. А так как слов, требующих подобных разъяснений,
попадалось немало, лекция моя стала походить на заклинание волшебника
или на камлание шамана. И вполне естественно, что слушатели мои, несмот-
ря на все старание, в котором я не имею оснований сомневаться, ничего из
моих объяснений не усвоили и, более того, не поняли.
Огорченный неудачей, я тем не менее не пал духом. Терпеливо и внима-
тельно я снова проработал этот вопрос, и после всестороннего изучения
имеющихся на эту тему трудов и литературных источников, сопоставив их с
собственными наблюдениями, я пришел к выводу, что: морская терминология
есть не что иное, как специальный морской инструмент, которым каждый мо-
ряк обязан владеть столь же уверенно и искусно, сколь уверенно плотник
владеет топором, врач — ланцетом, а слесарь — отмычкой.
Re[3]: Вопрос о конкретных примерах
От: INTP_mihoshi Россия  
Дата: 30.09.04 07:24
Оценка:
Здравствуйте, FR, Вы писали:

B>>У меня вопрос следующий.


B>>Я изучал ФЯ главным образом по языку Clean. Как работвют основные конструкции, что почем, я понял. Однако куда реально это применить — не знаю.


FR>Вот у меня тоже самое, правда только с ocaml.

FR>Правда на ocaml можно и императивно писать, но бессмысленно C++ лучше приспособлен для этого.

Императивно — это без темплейтов, функций высшего порядка, строгой типизации, автоматической сборки мусора и модульности? Для этого лучше приспособлен простой С.
Re[19]: ФП: вводная статья
От: FR  
Дата: 30.09.04 07:39
Оценка:
Здравствуйте, INTP_mihoshi, Вы писали:

INT>Здравствуйте, FR, Вы писали:


N_>>>Ну во первых, наверное не синтаксис требует ломать голову. Синтаксис проще некуда.

INT>Да.

FR>>Не синтаксис, а процесс программирования. Мне сейчас функциональные языки в этом отношении кажутся похожими на forth, написание любой программки это тренинг мышления,

INT>Да.

Это плохо, это значит что язык мешает работать.


FR>>По математике, я нормально воспринимаю мат. символику, и раньше немного программировал на Прологе, вот пролог почем-то у меня не вызвал никакого оторжения было сначало непривычно а потом наооборот легко.


INT>С ФЯ будет точно так же Меня поначалу Хаскелевские конструкции вроде [ x | xs <- [ [(1,2),(3,4)], [(5,4),(3,2)] ],

INT>(3,x) <- xs ] тоже пугали, а теперь в Ocamlе их очень не хватает.

ладно видно будет может и привыкну.

INT>Позволю себе привести цитату из Капитана Врунгеля


Врунгель это хорошо но не к месту, и ИЯ и ФЯ не повседневные языки.
Re[4]: Вопрос о конкретных примерах
От: FR  
Дата: 30.09.04 07:39
Оценка:
Здравствуйте, INTP_mihoshi, Вы писали:


INT>Императивно — это без темплейтов, функций высшего порядка, строгой типизации, автоматической сборки мусора и модульности? Для этого лучше приспособлен простой С.


Ну не надо ИЯ сводить только к процедурному программированию, есть еще и ООП, тоже насквозь императивный.
А С++ на самом деле лучше приспособлен для исперативного стиля просто потому что на Ocaml не удобно писать в императивном стиле.
Re[5]: Вопрос о конкретных примерах
От: INTP_mihoshi Россия  
Дата: 30.09.04 08:44
Оценка:
Здравствуйте, FR, Вы писали:

FR>Ну не надо ИЯ сводить только к процедурному программированию, есть еще и ООП, тоже насквозь императивный.

ООП, как ни странно, работает лучше, если использовать его только там, где оно действительно необходимо.

FR>А С++ на самом деле лучше приспособлен для исперативного стиля просто потому что на Ocaml не удобно писать в императивном стиле.

Нет. Я приводил пример Эратосфена.
Re[6]: Вопрос о конкретных примерах
От: FR  
Дата: 30.09.04 09:15
Оценка:
Здравствуйте, INTP_mihoshi, Вы писали:

INT>Здравствуйте, FR, Вы писали:


FR>>Ну не надо ИЯ сводить только к процедурному программированию, есть еще и ООП, тоже насквозь императивный.

INT>ООП, как ни странно, работает лучше, если использовать его только там, где оно действительно необходимо.

Это верно не только для ООП.

FR>>А С++ на самом деле лучше приспособлен для исперативного стиля просто потому что на Ocaml не удобно писать в императивном стиле.

INT>Нет. Я приводил пример Эратосфена.

Я ничего кроме вот этой страшной конструкции ни нашел:
let addprime arr n size = fold (fun a i -> set a (i*n)) [2..(size/n)] arr
let sieve size = fold (fun a i -> if get a i then addprime a i size else a) [2..size] (make size true)


и мой компилятор ocaml'а не знает что такое fold.
Re[7]: Вопрос о конкретных примерах
От: INTP_mihoshi Россия  
Дата: 30.09.04 09:49
Оценка:
Здравствуйте, FR, Вы писали:

FR>Я ничего кроме вот этой страшной конструкции ни нашел:

FR>
FR>let addprime arr n size = fold (fun a i -> set a (i*n)) [2..(size/n)] arr
FR>let sieve size = fold (fun a i -> if get a i then addprime a i size else a) [2..size] (make size true)
FR>


Упс. Это был не Ocaml. Это был как раз пример чисто функционального решета.

Вот работающий код на Ocaml.


open Array

let sieve size = 
    let arr = make (size+1) true in
    for i = 2 to size do
        if arr.(i) then     
            for j = 2 to (size)/i do
                arr.(j * i) <- false
            done
    done;
    arr
        
let show_last n = 
    let arr = sieve n in
    let i = ref n in
    while not arr.(!i) do i := !i - 1 done;
    print_int !i;;
    
    
show_last 3000000;;    

(*
Если нужно вывести все простые...
let show n = 
    let arr = sieve n in
    for i = 2 to n do
        if arr.(i) then Printf.printf "%d " i
    done;;
*)


Считает до 3000000 в native-code около секунды. Большие размерности надо уже реализовывать черз модуль Bigarray.
Re[4]: Вопрос о конкретных примерах
От: WolfHound  
Дата: 30.09.04 10:05
Оценка:
Здравствуйте, INTP_mihoshi, Вы писали:

INT>Императивно — это без темплейтов, функций высшего порядка, строгой типизации, автоматической сборки мусора и модульности?

И чем все это мешает императивности? В C#2 в той или иной степени есть все что ты перечислил. В С++ из этого списка не хватает только сборки мусора.
... << RSDN@Home 1.1.4 rev. 185 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[5]: Вопрос о конкретных примерах
От: INTP_mihoshi Россия  
Дата: 30.09.04 10:13
Оценка: -1 :)
Здравствуйте, WolfHound, Вы писали:

INT>>Императивно — это без темплейтов, функций высшего порядка, строгой типизации, автоматической сборки мусора и модульности?

WH>И чем все это мешает императивности? В C#2 в той или иной степени есть все что ты перечислил. В С++ из этого списка не хватает только сборки мусора.

В С++ не работает нормально ничего из перечисленного. Все сделано на уровне макросообразных конструкций.
В С# есть сборка мусора и модульность. Строгой типизации — нет, делегаты какие-то мутные, темплейтов нет.
Re[9]: ФП: вводная статья
От: Quintanar Россия  
Дата: 30.09.04 10:17
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Там все еще забавнее. В ОКамле алгоритмы в императивном стиле. Возми к примеру хип-сорт. Так что... Да и редко когда код на функциональном языке оказывается сильно короче того же С. И частенько хваленый хаскель сливает по черному (например, в Spell Checker или в Word Frequency).


Причем тут вообще Haskell? Никто никогда нигде не утверждал, что он работает быстро, тем более на задачах связанных с интенсивной работой с массивами. Его прелесть совсем в другом.
Re[8]: Вопрос о конкретных примерах
От: FR  
Дата: 30.09.04 10:29
Оценка:
Здравствуйте, INTP_mihoshi, Вы писали:


INT>Вот работающий код на Ocaml.


Это уже вполне понятно
Но все равно не вижу смысла писать в таком стиле на ocaml.
Re[9]: Вопрос о конкретных примерах
От: Quintanar Россия  
Дата: 30.09.04 11:25
Оценка: +1
Здравствуйте, FR, Вы писали:

FR>Здравствуйте, INTP_mihoshi, Вы писали:



INT>>Вот работающий код на Ocaml.


FR>Это уже вполне понятно

FR>Но все равно не вижу смысла писать в таком стиле на ocaml.

Задача сугубо императивная, поэтому и стиль такой. Блин, нашли что обсуждать, ей богу, еще бы перемножение матриц сравнивали. Если на то пошло, нужно смотреть более функциональные задачи. У меня, например, есть пара парсеров на OCaml. Один интерпретор примитивного языка, а другой конвертатор из bnf в sml yacc. Могу их выложить, хотя я ими не очень доволен, писал их когда еще слабо разбирался в функциональном стиле.
Re[10]: Вопрос о конкретных примерах
От: INTP_mihoshi Россия  
Дата: 30.09.04 12:14
Оценка:
Здравствуйте, Quintanar, Вы писали:

FR>>Это уже вполне понятно

FR>>Но все равно не вижу смысла писать в таком стиле на ocaml.

Q>Задача сугубо императивная, поэтому и стиль такой. Блин, нашли что обсуждать, ей богу, еще бы перемножение матриц сравнивали.


Странно, что ты про это сказал Вот здесь как раз лежит модуль работы с матрицами. Перемножение, конечно, фигня, а вот нахождение обратной можно и посравнивать...

Ocaml — язык общего назначения. ИО и ОО в нем, как минимум, не хуже, чем в С++.
Re[11]: Вопрос о конкретных примерах
От: Quintanar Россия  
Дата: 30.09.04 13:53
Оценка: +1
Здравствуйте, INTP_mihoshi, Вы писали:

INT>Ocaml — язык общего назначения. ИО и ОО в нем, как минимум, не хуже, чем в С++.


Да, но нет никакого смысла городить огород из-за еще одного императивного языка. На таких примерах совершенно не понять, в чем ФЯ-ки лучше императивных.
Re[6]: Вопрос о конкретных примерах
От: WolfHound  
Дата: 30.09.04 14:31
Оценка:
Здравствуйте, INTP_mihoshi, Вы писали:

INT>В С++ не работает нормально ничего из перечисленного. Все сделано на уровне макросообразных конструкций.

Правда чтоли?

INT>В С# есть сборка мусора и модульность.

INT>Строгой типизации — нет,
Это как это нет? Есть! Причем как компаилтайм так и рантайм.
INT>делегаты какие-то мутные,
Делегаты как делегаты в чем проблема то?
INT>темплейтов нет.
Я про C#2 говорил.
... << RSDN@Home 1.1.4 rev. 185 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[7]: Вопрос о конкретных примерах
От: INTP_mihoshi Россия  
Дата: 30.09.04 15:44
Оценка:
Здравствуйте, WolfHound, Вы писали:

INT>>В С++ не работает нормально ничего из перечисленного. Все сделано на уровне макросообразных конструкций.

WH>Правда чтоли?

#ifdef stuff_h
#define stuff_h
...
#endif
Это не макросообразная конструкция?

Темплейты — почему они не могут определяться только в хедерах? Не потому ли, что ониявляются просто замаскированными макросами? Не говоря уж о других их "приятных" особенностях...

INT>>В С# есть сборка мусора и модульность.

INT>>Строгой типизации — нет,
WH> Это как это нет? Есть! Причем как компаилтайм так и рантайм.
Была бы строгая — не были бы возможны контейнеры.

INT>>делегаты какие-то мутные,

WH>Делегаты как делегаты в чем проблема то?
Когда я ими пользовался, мне они показались неудобными и неинтуитивными. Может, с непривычки.

INT>>темплейтов нет.

WH>Я про C#2 говорил.
Он уже вышел? Я просто не в курсе. Может, дашь ссылку?
Re[17]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 30.09.04 16:31
Оценка:
Здравствуйте, Nick_, Вы писали:

N_>Ну во первых, наверное не синтаксис требует ломать голову. Синтаксис проще некуда.

N_>Во вторых, любые нетривиальные задачи, которые стоят перед программистами требуют "ломать голову". И от этого по словам Брукса (Мифический человеко-месяц) никуда не деться.

И все же многие мысли могут быть изложены проще.

N_>Ну и в третих, то, что функциональный стиль труднее воспринимается — это не правда.


Ну, значит огромная толпа программистов тебе врет. Понятно, что к такому стилю тоже можно привыкнуть, но привыкание дается крайне болезненно. Это как с слепым методом письма. Понятно, что после привычки писать им проще и быстрее, но вот чтобы привыкнуть нужно долго издеваться над собой и без специальных тренажеров и тренировок сделать это не просто.

N_> Часто рекурсивные программы проще.


Проще она в исконно рекусивных алгоритмах. То есть там где она есть по логике программы. В том же QuickSort-е, например. А вот когда ею заменяют циклы, то все уже не так просто. Оно даже может оказаться короче, но вот для восприятия получается даже сложнее.

N_> А на императивных языках, из-за того, что рекурсия неэффективно компилируется тот же алгоритм начинает напоминать грамматику в форме Грейбах (как говорите "A +B C"). Хуже от этого может и не становится, но изящность теряется.


С эффективностью сейчас проблем нет. Пролемы есть в излишней информации которую требуется вносить программисту для решения задачи в импиративном стиле. А рекурсия уже давно оптимизируется современными компиляторами.

N_>Если бы у вас было бы математическое образование (а похоже, что оно у вас не математическое), то вы бы когда-то изучали логику и вам было бы проще "переключать мозг" в "нужную" сторону.


Образование у меня не математическое, но логику я изучал. Требование же переключения мозга плохо в принципе. Это резко сокращает круг тех кто сможет освоить и применять подобный подход на практике.

Кстати, здесь принято общаться на ты. Да и "вы" с маленькой буквы выглядит нехорошо.

N_> А пока, вы мне напоминаете того, кто всю жизнь работает с грамматиками "A +B C" и так привык к этому, что "A + B" кажентся непривычным.


То есть я путаю черное с белым? А может быть все же это поклонники функционального стиля привыкнув к непривычному пытаются объяснить что только так и надо, и что это совсем привычно? Еще раз проведу аналогию со слепым методом печати. Да освоив его писать становится просто, но утверждение, что осваивать там нечего, и что это самый естественный стиль печатанья мягко говоря долеки от релий мира.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[18]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 30.09.04 16:31
Оценка:
Здравствуйте, FR, Вы писали:

FR>Не синтаксис, а процесс программирования. Мне сейчас функциональные языки в этом отношении кажутся похожими на forth, написание любой программки это тренинг мышления, попытка понять через месяц что написал тоже


По-моему, на самом деле все несовсем так. Тут именно проблема переключения мозга. Переключив мозг однажды далее все становится более менее просто. Начинаешь думать в нужном русле и решать задачи нужным методом. Но вот сам процесс переключения крайне болезненный. И не многие обладают нужным упорством, чтобы перебороть себя. Nick_ в том, что если мозг с молодых лет подвергался закалке (другими словами был изнасилован ) матиматикой, то переключение проходит куда проще. Но математика сама по себе требует нехилого переключения мозгов и является форменным изнасилованием. Мыслительный же процесс обычного человека все же отличается от математических канонов. Обычный человек скорее пользуется примитивными правилами логики: последовательность, непротиворечивость, полнота, нежели мыслит в рамках абстрактных формул.

FR>По математике, я нормально воспринимаю мат. символику, и раньше немного программировал на Прологе, вот пролог почем-то у меня не вызвал никакого оторжения было сначало непривычно а потом наооборот легко.


Как видишь все равно с начала не привычно. То есть само человеческое естество не очень то принимает подобные подходы.

Вот мне и кажется, что дело не в абстрактности, а в форме выражения. Я назвал это синтаксисом, но возможно это не подходящее слово.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 30.09.04 16:31
Оценка:
Здравствуйте, FR, Вы писали:

FR>При желании наверно можно, но питон как и C++ мультипарадигменный. Хотя так и ocaml можно отнести к императивным


Согласен, относить язык к типу парадигмы на основании поддержки фич в корне не верно. При такой формализации можно развать ФЯ языки вроде ОКамла императивными, а С++ и C# функциональными, только по тому что они обладают возможностями писать в разных стилях.

Но все же нет дыма без огня... Раз вроде как авторитетный в этом вопросе человек отнес Питон к ФЯ, значит Питон действительно обладает реальными фичами позволяющими писать на нем в функциональном стиле.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 30.09.04 16:31
Оценка:
Здравствуйте, Quintanar, Вы писали:

Q>Причем тут вообще Haskell? Никто никогда нигде не утверждал, что он работает быстро, тем более на задачах связанных с интенсивной работой с массивами. Его прелесть совсем в другом.


Дык теоретическая прелесть интересна только эстетам. Всем нужна практическая прелесть.

К сожалению, красота резко меркнет когда встают вопросы производительности.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 30.09.04 16:31
Оценка:
Здравствуйте, INTP_mihoshi, Вы писали:

INT>Дополню.

INT>Препроцессор P4 в Ocaml — это не макроподстановки. Это инструмент, который работает непосредственно с синтаксисом языка. Например, он позволяет не только добавлять, но и убирать правила из грамматики.
INT>Пример с удаленями правил можно посмотреть в туториале.
INT>Вот простой пример добавления правил — добавление конструкции repeat/until.

INT>
INT>       open Pcaml;;
INT>       EXTEND
INT>         expr: LEVEL "expr1"
INT>           [[ "repeat"; e1 = expr; "until"; e2 = expr ->
INT>                 <:expr< do { $e1$; while not $e2$ do { $e1$; } } >> ]];
INT>       END;;
INT>


Кстати, отдельная тема очень интересная лично мне в разрезе R#.

ЗЫ

Может не кстати, но все же... Прошу господ приверженцов ФЯ высказаться по поводу названия для нового форума: Название нового форума (того что по ФЯ)
Автор: VladD2
Дата: 28.09.04
. А то время то идет...
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Вопрос о конкретных примерах
От: WolfHound  
Дата: 30.09.04 17:17
Оценка:
Здравствуйте, INTP_mihoshi, Вы писали:

INT>Это не макросообразная конструкция?

Это да но это печальное наследие С.
Многие С++ компиляторы понимают #pragma once

INT>Темплейты — почему они не могут определяться только в хедерах?

В доступных тебе реализациях. Есть реализации где это не так.
INT>Не потому ли, что ониявляются просто замаскированными макросами?
Нет. Это не так. Шаблоны не болие макросы чем функции в функциональных языках.
INT>Не говоря уж о других их "приятных" особенностях...
А именно?

INT>Была бы строгая — не были бы возможны контейнеры.

1)Полиморфные контейнеры не отменяют типизированые контейнеры.
2)Динамическую типизацию ни кто не отменял.
3)В C#2 есть генерик коллекции.

INT>Он уже вышел? Я просто не в курсе. Может, дашь ссылку?

Релиз нет. А бета дано гуляет.
... << RSDN@Home 1.1.4 rev. 185 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[6]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 30.09.04 21:25
Оценка:
Здравствуйте, INTP_mihoshi, Вы писали:

INT>Здравствуйте, FR, Вы писали:


FR>>Ну не надо ИЯ сводить только к процедурному программированию, есть еще и ООП, тоже насквозь императивный.

INT>ООП, как ни странно, работает лучше, если использовать его только там, где оно действительно необходимо.
То есть где?
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[19]: ФП: вводная статья
От: Блудов Павел Россия  
Дата: 01.10.04 02:27
Оценка: 4 (1) +1
Здравствуйте, VladD2, Вы писали:

FR>>По математике, я нормально воспринимаю мат. символику, и раньше немного программировал на Прологе, вот пролог почем-то у меня не вызвал никакого оторжения было сначало непривычно а потом наооборот легко.


VD>Как видишь все равно с начала не привычно. То есть само человеческое естество не очень то принимает подобные подходы.

VD>Вот мне и кажется, что дело не в абстрактности, а в форме выражения. Я назвал это синтаксисом, но возможно это не подходящее слово.

ИМХО, не в естестве дело. Костность мышления да, имеет место.
Я знаю много людей, хорошо владещих процедурным программированием. Но при попытке пересадить их за ООП получается ПООП (псевдо ООП).
Люди все равно думают строчками кода, а не сущностями, которые за ними стоят.
Трудно переучиваться. Особенно если учишь процедурные языки со школы.
А вот если бы в школах учили не паскалю, а смолтеку — щас бы грамотных С++шников было пруд пруди (это я так, наболело).

С декларативными языками примерно тоже самое.
... << RSDN@Home 1.1.4 beta 2 >>
Re[9]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 01.10.04 02:29
Оценка:
Здравствуйте, WolfHound, Вы писали:

INT>>Не потому ли, что ониявляются просто замаскированными макросами?

WH>Нет. Это не так. Шаблоны не болие макросы чем функции в функциональных языках.

Ну уж... Это конечно тут офтопик, но приведу пример.

template<class T>
class A
{
    int x = (int)(T::x)+1;
};


Когда компилятор С++ видит такое, как ему распознать строку в классе? Ведь T::x может быть или типом, или идентификатором.
В зависимости от этого, семантика строки будет совсем разная. Так как такие вещи вляиют на синтаксический анализ, компиляторам приходится пропускать весь код между { и }. А потом при каждой инстанциации возвращаться к шаблону и компилировать его. Это ли не макроподстановка?
Re[7]: Вопрос о конкретных примерах
От: INTP_mihoshi Россия  
Дата: 01.10.04 05:26
Оценка: 6 (1)
Здравствуйте, prVovik, Вы писали:

FR>>>Ну не надо ИЯ сводить только к процедурному программированию, есть еще и ООП, тоже насквозь императивный.

INT>>ООП, как ни странно, работает лучше, если использовать его только там, где оно действительно необходимо.
V>То есть где?

Там, где необходима инкапсуляция состояний. Там, где необходим интерфейс к какой-то физической сущности — устройству, окну, удаленной машине. Там, где необходима обработка удаления объекта.

Обычно же в С++ в классы заворачивают все, что можно, а потом еще внутрь классов набивают методов от души. Так как кроме классов средств модульности нет и функциональные средства (которые позволили бы эффективно использовать функции вместо методов) слабые и неудобные.
Re[20]: ФП: вводная статья
От: INTP_mihoshi Россия  
Дата: 01.10.04 05:53
Оценка: +1
Здравствуйте, FR, Вы писали:

FR>>>Не синтаксис, а процесс программирования. Мне сейчас функциональные языки в этом отношении кажутся похожими на forth, написание любой программки это тренинг мышления,

INT>>Да.

FR>Это плохо, это значит что язык мешает работать.


Тут даже не в синтаксисе дело. В ИЯ оснвной объект мышления — данные. Переменные, объекты, etc. В ФЯ основноя объект — действие. В ИЯ функции высшего порядка и темплейты — advanced issues. В ФЯ — основа языка. И синтаксис заточен соответственно. И нужно время, чтобы к нему привыкнуть.
Re[9]: Вопрос о конкретных примерах
От: INTP_mihoshi Россия  
Дата: 01.10.04 06:43
Оценка:
Здравствуйте, WolfHound, Вы писали:

INT>>Не говоря уж о других их "приятных" особенностях...

WH>А именно?
То, что говорил _Nick. И то, о чем писал Страуструп. Почитай "Design & Evolution of C++". Каждая из проблем темплейтов, упонмянутая Страуструпом, в Ocaml решена.

INT>>Была бы строгая — не были бы возможны контейнеры.

WH>1)Полиморфные контейнеры не отменяют типизированые контейнеры.
WH>2)Динамическую типизацию ни кто не отменял.
WH>3)В C#2 есть генерик коллекции.
Ок, в C# есть почти строгая типизация
Re[21]: ФП: вводная статья
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.10.04 07:40
Оценка: 38 (6) +1
Здравствуйте, INTP_mihoshi, Вы писали:

INT>Тут даже не в синтаксисе дело. В ИЯ оснвной объект мышления — данные. Переменные, объекты, etc.

Интересный поинт. По-моему, в ия основной объект мышления — абстрактная машина. И собственно инструкции машине, как менять ее состояние, включая instruction pointer. Гранулярность состояния машины зависит от языка. Это может быть стек для форта, регистры для асм, переменные для С, объекты для С++...
INT>В ФЯ основноя объект — действие.
Я твк понял, что все же именно зависимости. Действий в "активном" смысле в ФП не должно быть. Это скорее математика, ФП очень созерцательно по своей сути. Функциональная программа как бы отражает взгляд разработчика на предметную область. Он замечает, что очередное число Фибоначчи равно сумме двух предыдущих, и констатирует этот факт в своей программе. При этом он не только не говорит потенциальному собеседнику "складывай два числа, затем прибавляй к сумме второе и.т.д.". Он избегает говорить даже "для получения очередного числа Фибоначчи надо сложить два предыдущих". Чего, для чего и кому надо — не его забота.

Функциональное программирование такого уровня осваивается людьми гораздо проще любого императива. Потому как имеет дело с "незыблемыми фактами", истинность которых независит от предыстории. Справедливость моего смелого утверждения косвенно подтвердят миллионы людей учетных специальностей, прекрасно справляющихся с Excel. Именно из-за того, что в нем достаточно указать зависимости между данными.
INT>В ИЯ функции высшего порядка и темплейты — advanced issues. В ФЯ — основа языка. И синтаксис заточен соответственно. И нужно время, чтобы к нему привыкнуть.
Ага. Трудно сказать, основа ли оно . Вон как теоретики называют объектными языки, которые предоставляют базовые концепции ООП, и отличают их от объектно-ориентированных, где обязаны поддерживаться такие концепции, как классификация, наследование и т.д, которые с точки зрения абстрактной теории выглядят лишь не столь уж интересным частным случаем гораздо более всеобъемлющей модели сущностей и сообщений
Если мы возьмем даже старое доброе ИП безо всяких объектов, то окажется, что базовые концепции ИП легко осваиваются людьми. Нарисовать домик на Лого после получаса тренировки может даже подросток с нарушениями в развитии. Но потом мы увидим, что в ИП непременно нужны такие управляющие конструкции, как ветвление, циклы, подпрограммы и т.д. Есть переменные, области видимости, ссылки и указатели. Освоение этого материала занимает весьма значительное время. Просто мы все настолько рано обучаемся этому, что трудно вспомнить тот момент, когда простейшие вещи казались непостижимыми.
Это я даже не начал еще пугать вас действительно сложными концепциями ИП, типа исключений с их великолепной раскруткой стека и параллельным программированием.

Так вот я к чему — к тому, что функции высшего порядка точно так же используются для констатации фактов из предметной области, как и функции первого порядка. Вот только теперь эти факты касаются не значений, а самих функций. Математику этот шаг кажется совершенно очевидным и простым — "преобразование Фурье — это всего лишь смена базиса, в котором представлена ваша функция". Однако я бы назвал такие возможности все же "функционально-ориентированными", по аналогии с ООП. Поскольку они точно так же не являются чем-то существенно новым с точки зрения модели, тем не менее для успешного программирования в функциональном стиле они просто необходимы.

Так вот на мой взгляд, основное, на что требуется время — это на понимание именно созерцательности функционального программирования, и обучение наблюдательности, умению подмечать те самые факты и взаимосвязи, констатация которых и составит собственно программу.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[22]: ФП: вводная статья
От: Дм.Григорьев  
Дата: 01.10.04 07:57
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Это я даже не начал еще пугать вас действительно сложными концепциями ИП, типа исключений с их великолепной раскруткой стека и параллельным программированием.


А кстати, каковы методы обработки ошибок в ФЯ? Наверное, там вся идеология на корню другая?
http://dimgel.ru/lib.web — thin, stateless, strictly typed Scala web framework.
Re[23]: ФП: вводная статья
От: INTP_mihoshi Россия  
Дата: 01.10.04 08:15
Оценка:
Здравствуйте, Дм.Григорьев, Вы писали:

S>>Это я даже не начал еще пугать вас действительно сложными концепциями ИП, типа исключений с их великолепной раскруткой стека и параллельным программированием.


ДГ>А кстати, каковы методы обработки ошибок в ФЯ? Наверное, там вся идеология на корню другая?


Как раз нет. Те же исключения. Причем они используются гораздо активнее — не только для ошибок, но и просто для крайних случаев. Например, искать в массиве и возвращать найденный элемент в исключении — нормальное дело, ибо breakов нет
Re[10]: Вопрос о конкретных примерах
От: WolfHound  
Дата: 01.10.04 08:35
Оценка: +1
Здравствуйте, Nick_, Вы писали:

N_>Ну уж... Это конечно тут офтопик, но приведу пример.


В данном случае это не тип.
template<class T>
class A
{
    int x = (int)(T::x)+1;
};

Если написать так
template<class T>
class A
{
    int x = (int)(typename T::x)+1;
};

то это будет тип.
... << RSDN@Home 1.1.4 rev. 185 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[10]: Вопрос о конкретных примерах
От: WolfHound  
Дата: 01.10.04 08:35
Оценка:
Здравствуйте, INTP_mihoshi, Вы писали:

INT>То, что говорил _Nick.


INT>И то, о чем писал Страуструп. Почитай "Design & Evolution of C++". Каждая из проблем темплейтов, упонмянутая Страуструпом, в Ocaml решена.
Не ну ты давай конкретно по пунктам.

INT>Ок, в C# есть почти строгая типизация

Ну печему же почти?
Ты про рантайм не забывай. Там работать с объектом можно только если он будет того типа какой требуется в данном месте.
... << RSDN@Home 1.1.4 rev. 185 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[11]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 01.10.04 09:00
Оценка: +1
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, Nick_, Вы писали:


WH>


Это была шутка?

Назови мне хоть один компилятор, который не скомпилирует этот код. И попробуй доказать, что T::x в шаблоне — это не тип.

$ cat template.cpp
template<class T>
class A
{
        static const int x = (int)(T::x)+1;
};

class B
{
public:
        typedef int x;
};

int main()
{
        A<B> x;
}
Re[23]: ФП: вводная статья
От: Quintanar Россия  
Дата: 01.10.04 09:17
Оценка:
Здравствуйте, Дм.Григорьев, Вы писали:

ДГ>Здравствуйте, Sinclair, Вы писали:


S>>Это я даже не начал еще пугать вас действительно сложными концепциями ИП, типа исключений с их великолепной раскруткой стека и параллельным программированием.


ДГ>А кстати, каковы методы обработки ошибок в ФЯ? Наверное, там вся идеология на корню другая?


Смотря где. В SML, OCaml это делается с помощью исключений, которые почти ничем не отличаются от исключений в C#.
В Haskell исключений нет, поскольку они не укладываются в идеологию ленивого языка. Но можно их эмулировать с помощью монад. Это накладываем определенные ограничения, но что делать. Есть еще возможность использовать CPS или возвращать тип-вариант — либо результат, либо ошибка.
search_list [] = Right []
search_list h:t =
  case search_list t of
    Right l -> if something_wrong_with h then Left "error" else Right h:l
    Left err -> Left err -- передать ошибку дальше

Этот вариант геморойный, лучше использовать соответствующую монаду.
CPS вариант:
search_list l = search_list_cont l (\x -> Right x)

search_list_cont [] cont = cont []
search_list_cont (h:t) cont = 
  if something_wrong_with h then Left "error"
  else search_list_cont t (\x -> cont (h:x))
Re[12]: Вопрос о конкретных примерах
От: WolfHound  
Дата: 01.10.04 11:09
Оценка:
Здравствуйте, Nick_, Вы писали:

N_>Назови мне хоть один компилятор, который не скомпилирует этот код.

Странно. Буду разбираться какого это компилится...
N_>И попробуй доказать, что T::x в шаблоне — это не тип.
Тут доказывать нечего
14.6/2

A name used in a template declaration or definition and that is dependent on a template-parameter is assumed not to name a type unless the applicable name lookup finds a type name or the name is qualified by the keyword typename.


ЗЫ А ты попробуй откомпилить это(без typename)
template<class T>
struct A
{
    typename T::x x;
};

struct B
{
    typedef int x;
};

int main()
{
    A<B> x;
}

Только на нормальном компиляторе.
VC++7.1
------ Build started: Project: idkfa, Configuration: Release Win32 ------

Compiling...
idkfa.cpp
idkfa.cpp(501) : warning C4346: 'T::x' : dependent name is not a type
        prefix with 'typename' to indicate a type
        idkfa.cpp(502) : see reference to class template instantiation 'A<T>' being compiled
idkfa.cpp(501) : error C2146: syntax error : missing ';' before identifier 'x'
idkfa.cpp(501) : error C2501: 'A<T>::x' : missing storage-class or type specifiers

Build Time 0:00
Build log was saved at "file://e:\work\idkfa\Release\BuildLog.htm"
idkfa - 2 error(s), 1 warning(s)


---------------------- Done ----------------------

    Build: 0 succeeded, 1 failed, 0 skipped
... << RSDN@Home 1.1.4 rev. 185 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[13]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 01.10.04 11:39
Оценка: -1
Здравствуйте, WolfHound, Вы писали:

WH>Только на нормальном компиляторе.

WH>VC++7.1

Да?

C:\>cl template.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

template.cpp
Microsoft (R) Incremental Linker Version 7.10.3077
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:template.exe
template.obj


Все, что ты говоришь, это конечно суперкруто. Но реально ни один компилятор не делает синтаксический анализ шаблона до его инстанциации, потому, что иначе никак не сделать обратную совместимость со старым кодом.
Re[13]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 01.10.04 11:52
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Тут доказывать нечего

WH>14.6/2
WH>

WH>A name used in a template declaration or definition and that is dependent on a template-parameter is assumed not to name a type unless the applicable name lookup finds a type name or the name is qualified by the keyword typename.


Hint: почитай порядок name lookup'а для идентификаторов зависящих от параметра шаблона. Поиск делается как в контексте определения шаблона, так и в контексте инстанциации. Синтаксический анализ невозможно сделать до лукапа, а лукап до инстанциации.

WH>ЗЫ А ты попробуй откомпилить это(без typename)

WH>
WH>template<class T>
WH>struct A
WH>{
WH>    typename T::x x;
WH>};

WH>struct B
WH>{
WH>    typedef int x;
WH>};

WH>int main()
WH>{
WH>    A<B> x;
WH>}
WH>


В данном случае строка в шаблоне не может быть двусмысленно интерпретирована. Если T::x будет не типом — возникнет ошибка. Тут как раз ничего удивительного и нет.
Re[14]: Вопрос о конкретных примерах
От: WolfHound  
Дата: 01.10.04 11:58
Оценка:
Здравствуйте, Nick_, Вы писали:

N_>Да?

А ты typename убрать не забыл? Похоже что забыл.

N_>Все, что ты говоришь, это конечно суперкруто. Но реально ни один компилятор не делает синтаксический анализ шаблона до его инстанциации, потому, что иначе никак не сделать обратную совместимость со старым кодом.

А! Ну-ну. Вот только компиляторы с фронтендом от EDG с тобой не согласны...

ЗЫ Re: ??? Какого оно компилится???
Автор: 0xDEADBEEF
Дата: 01.10.04
... << RSDN@Home 1.1.4 rev. 185 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[8]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 01.10.04 12:01
Оценка:
Здравствуйте, INTP_mihoshi, Вы писали:

V>>То есть где?

INT>Там, где необходима инкапсуляция состояний.
Стажи, а, например, структуру "стек" можно описать, как объект, инкапсулирующий состояние?

INT>Там, где необходим интерфейс к какой-то физической сущности — устройству, окну, удаленной машине.

1) Разве бывают в реальной жизни программы, которые совсем не взаимодействуют с физическими сущносями?
2) А если сущность виртуальная? С ней не надо взаимодействовать?
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[15]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 01.10.04 12:08
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>А ты typename убрать не забыл? Похоже что забыл.


Я свой пример скомпилял. Собственно я про него тебя и спрашивал, а ты сказал что его не скомпилирует "нормальный компилятор".

WH>А! Ну-ну. Вот только компиляторы с фронтендом от EDG с тобой не согласны...

Это какие? Intel C++?

C:\Documents and Settings\nildugan>icl template.cpp
Intel(R) C++ Compiler for 32-bit applications, Version 8.0   Build 20031017Z Pac
kage ID: W_CC_P_8.0.037
Copyright (C) 1985-2003 Intel Corporation.  All rights reserved.

template.cpp
Microsoft (R) Incremental Linker Version 7.10.3077
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:template.exe
template.obj


WH>ЗЫ Re: ??? Какого оно компилится???
Автор: 0xDEADBEEF
Дата: 01.10.04


Может тогда не майкрософтовский компилятор "нормальный", а gcc?
Re[16]: Вопрос о конкретных примерах
От: WolfHound  
Дата: 01.10.04 13:07
Оценка:
Здравствуйте, Nick_, Вы писали:

А можно вопрос? Спасибо. Ты вобще читаешь что я пишу?
... << RSDN@Home 1.1.4 rev. 185 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[9]: Вопрос о конкретных примерах
От: INTP_mihoshi Россия  
Дата: 01.10.04 13:08
Оценка:
Здравствуйте, prVovik, Вы писали:

V>Здравствуйте, INTP_mihoshi, Вы писали:


V>>>То есть где?

INT>>Там, где необходима инкапсуляция состояний.
V>Стажи, а, например, структуру "стек" можно описать, как объект, инкапсулирующий состояние?
Стек — не состояние, а данное.

INT>>Там, где необходим интерфейс к какой-то физической сущности — устройству, окну, удаленной машине.

V>1) Разве бывают в реальной жизни программы, которые совсем не взаимодействуют с физическими сущносями?
В объект надо оброачивать только собственно эти сущностями.

V>2) А если сущность виртуальная? С ней не надо взаимодействовать?

Давай пример виртуальной сущности, которая не является состоянием и которую стоит реализовать именно через класс.
Re[17]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 01.10.04 13:13
Оценка: :)
Здравствуйте, WolfHound, Вы писали:

WH>А можно вопрос? Спасибо. Ты вобще читаешь что я пишу?


Твой пример я тоже посмотрел. Ошибку на нем выдает только VC++ 7.

Пора бы уже согласиться, что в текущем стандарте С++ шаблоны это не более чем продвинутые макросы с возможностью их рекурсивного определения и проверкой на типы.
Re[18]: Вопрос о конкретных примерах
От: WolfHound  
Дата: 01.10.04 14:07
Оценка: +1
Здравствуйте, Nick_, Вы писали:

N_>Пора бы уже согласиться, что в текущем стандарте С++ шаблоны это не более чем продвинутые макросы с возможностью их рекурсивного определения и проверкой на типы.

... << RSDN@Home 1.1.4 rev. 185 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[16]: ФП: вводная статья
От: Gaperton http://gaperton.livejournal.com
Дата: 01.10.04 16:04
Оценка:
Здравствуйте, Quintanar, Вы писали:

Q>Здравствуйте, Gaperton, Вы писали:


G>>1) Попробуй пометить аргументы функций как strict. Насколько я помню, это делается так же как в Clean (!). Strictness analyzer не способен определить все strict вызовы, ему надо помочь.

G>>2) Попробуй использовать STUArray c типом Bool(Data.Array.ST).


Q>strict аргументов там нет, да и так там ничего ленивого в сущности нет.

"$!" — strict application (http://www.haskell.org/onlinereport/basic.html#sect6.2)
Проблема в том, что компилятор не всегда может определить, когда можно использовать strict вычисления. Он пытается это сделать (иначе было бы все очень медленно), но полный strictness-analyzis это NP-полная задача, так что компилятору надо помогать.

Q>STUArray работает буквально на пару секунд побыстрее. С Bool оба массива тормозят — 1м30 и 1м28 соответственно.

Плохо. Все-таки, нельзя настолько затруднять эффективный доступ к массивам и strict-evaluation, как это сделано в Haskell. От его массивов несет императивщиной за версту (монады!), а толку все равно никакого. Clean рулит. Тот же Haskell, но все по уму.
Re[20]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.10.04 17:40
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>ИМХО, не в естестве дело. Костность мышления да, имеет место.

БП>Я знаю много людей, хорошо владещих процедурным программированием. Но при попытке пересадить их за ООП получается ПООП (псевдо ООП).
БП>Люди все равно думают строчками кода, а не сущностями, которые за ними стоят.
БП>Трудно переучиваться. Особенно если учишь процедурные языки со школы.
БП>А вот если бы в школах учили не паскалю, а смолтеку — щас бы грамотных С++шников было пруд пруди (это я так, наболело).

БП>С декларативными языками примерно тоже самое.


А я вот являюсь представителем обратного оптыа. Начинал я писать на С и потом очень просто и с радостью пересел за С++. Я уже на С думал объектами. Но восприятие функционального стиля, если сам алгоритм не рекурсивен мною воспринимается с трудом.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.10.04 17:40
Оценка:
Здравствуйте, INTP_mihoshi, Вы писали:

INT>В С# есть сборка мусора и модульность. Строгой типизации — нет,


Это с чего же это нет?

INT> делегаты какие-то мутные,


Что в них мутного то? Медленные — да. Но мутные... Они как раз очень даже ясные и концептуально чистые. Единственная проблема — их параметры нельзя задавать частично. Но это решается анонимными методами.

INT> темплейтов нет.


Дженерики есть. Для задач обобщенного программирования более чем достаточно. Да я тут вам уже как-то приводил вариант функционального АндиКвикСорта на втором шарпе.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.10.04 17:40
Оценка:
Здравствуйте, INTP_mihoshi, Вы писали:

WH>> Это как это нет? Есть! Причем как компаилтайм так и рантайм.

INT>Была бы строгая — не были бы возможны контейнеры.

Ошибашся. Строгая типизация требует только невозможность неверного привдения типов. Оно не требует чтобы все проверки делались в компайл-тайме (были статическими). Приведение в Шарпе полностью безопасны (если не используется ансэйф-режим). Для up-cast-ов делаются рантайм-проврки.

Но C# — это строго-типизированный язык. Об этом даже в спецификации наисано. Так что ты ошибашся.

INT>Когда я ими пользовался, мне они показались неудобными и неинтуитивными. Может, с непривычки.


Именно что. И вообще твое отвращение к Шарпу явно основано на том, что ты в него не вник.

WH>>Я про C#2 говорил.

INT>Он уже вышел? Я просто не в курсе. Может, дашь ссылку?

Он в бата-стадии, но работает и доступн.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: ФП: вводная статья
От: Gaperton http://gaperton.livejournal.com
Дата: 01.10.04 19:15
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, prVovik, Вы писали:


V>>Если уж и начали мерятся скоростями, то со стороны С++ должен выступать ICC. Ибо он рулит.

WH>Ну выступи. Ибо ICC у меня нет. К томуже на таких расчетах VC++ тоже рулит.
И Clean тоже, как выяснилось . Ну что, "не посчитать ли нам, уважаемые кроты?" Может, матрицы поперемножаем?
Re[15]: ФП: вводная статья
От: WolfHound  
Дата: 01.10.04 19:51
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>И Clean тоже, как выяснилось . Ну что, "не посчитать ли нам, уважаемые кроты?" Может, матрицы поперемножаем?

Не. Матрици перемножать это ICC надо. В этом деле он рулит просто не по децки.
... << RSDN@Home 1.1.4 rev. 185 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[15]: ФП: вводная статья
От: FR  
Дата: 01.10.04 20:07
Оценка: :)
Здравствуйте, Gaperton, Вы писали:

G>Здравствуйте, WolfHound, Вы писали:


WH>>Здравствуйте, prVovik, Вы писали:


V>>>Если уж и начали мерятся скоростями, то со стороны С++ должен выступать ICC. Ибо он рулит.

WH>>Ну выступи. Ибо ICC у меня нет. К томуже на таких расчетах VC++ тоже рулит.
G>И Clean тоже, как выяснилось . Ну что, "не посчитать ли нам, уважаемые кроты?" Может, матрицы поперемножаем?

пока вы меряли (на эротосфене) только скорость работы озу
Re[10]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 01.10.04 22:41
Оценка: +1 -3
Здравствуйте, INTP_mihoshi, Вы писали:

V>>Стажи, а, например, структуру "стек" можно описать, как объект, инкапсулирующий состояние?

INT>Стек — не состояние, а данное.
Ну так можно абсолютно обо всем сказать.

V>>1) Разве бывают в реальной жизни программы, которые совсем не взаимодействуют с физическими сущносями?

INT>В объект надо оброачивать только собственно эти сущностями.
А остальное куда девать?

V>>2) А если сущность виртуальная? С ней не надо взаимодействовать?

INT>Давай пример виртуальной сущности, которая не является состоянием и которую стоит реализовать именно через класс.
Объясню на пальцах...
Вооружимся функциональным подходом и рассмотрим некоторую сущность, которая существует в пределах своей среды окружения. Например, среда окружения — это предприятие П1, а сущность — сотрудник Иванов, которому 35 лет. В один прекрасный день, этот сотрудник справляет себе день рождения, в результате чего Иванов(35) умирает, и на его месте появляется Иванов(36). Посмотрим на предприятие: раньше было предприятие П1, в котором работал сотрудник Иванов(35), теперь Иванов(35) умер, следовательно должно также умереть и предприятие, вместе с остальными сотрудниками. На месте этих трупов появится новое предприятие П2, в котором теперь работает сотрудник Иванов(36). Предприятие П1 также существовало в пределах своей среды окружения, например, множества других предприятий, с которыми оно взаимодействовало. И этим предприятиям также придется помереть со всеми своими сотрудниками после того, как на предприятии П1 сотрудник Иванов отпразнует свой день рождения.

Понятно, что этот процесс регенерации сущностей теоретически должен продолжаться бесконечно: поменяется страна, планета, галлактика и т.д. Но также понятно, что рано или поздно необходимо явно зафиксировать границу регенерации сущностей, обусловленную конечностью вычислительных ресурсов, и как следствие, тем, что эти ресурсы следует расходовать экономно. Таким образом, рано или поздно(скорее, рано), у нас появится сущность, которая не регенерируется при изменении своих составных частей. Эту сущность НЕВОЗМОЖНО реализовать в виде детерминированного состояния (чтобы не превысить ресурсную границу), она и будет называться объектом. Это и есть ответ на твой вопрос

Еще хочу обратить внимание, что любая другая сущность, взаимодействующая с изменяемой, также обязана быть изменяемой, то есть начиная с некоторого уровня абстракции, функциональное программирование исчезает полностью!!! Отсюда следует, что функциональные языки в целом не могут заменить итеративные. Ну разве что их гибриды в некоторых областях применения...

ЗЫ: все ИМХО
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[11]: Вопрос о конкретных примерах
От: Quintanar Россия  
Дата: 02.10.04 07:43
Оценка:
Здравствуйте, prVovik, Вы писали:

V>Объясню на пальцах...

V>Вооружимся функциональным подходом и рассмотрим некоторую сущность, которая существует в пределах своей среды окружения. Например, среда окружения — это предприятие П1, а сущность — сотрудник Иванов, которому 35 лет. В один прекрасный день, этот сотрудник справляет себе день рождения, в результате чего Иванов(35) умирает, и на его месте появляется Иванов(36). Посмотрим на предприятие: раньше было предприятие П1, в котором работал сотрудник Иванов(35), теперь Иванов(35) умер, следовательно должно также умереть и предприятие, вместе с остальными сотрудниками. На месте этих трупов появится новое предприятие П2, в котором теперь работает сотрудник Иванов(36). Предприятие П1 также существовало в пределах своей среды окружения, например, множества других предприятий, с которыми оно взаимодействовало. И этим предприятиям также придется помереть со всеми своими сотрудниками после того, как на предприятии П1 сотрудник Иванов отпразнует свой день рождения.

Чего-то я не понял, что ты этим хочешь доказать. С теоретической точки зрения императивные языки ничем не отличаются от функциональных — любой алгоритм реализованный на одном можно реализовать на другом. С практической
точки зрения у функциональных языков есть проблема — они работают на императивной машине и следовательно должны
уметь с ней как-то общаться минимизируя возникающий урон. Эти задачи решаются, в Haskell'е даже строго
функционально, моделируя состояние внешнего мира. В чем проблема я не вижу. Зачем кого-то убивать

V>Понятно, что этот процесс регенерации сущностей теоретически должен продолжаться бесконечно: поменяется страна, планета, галлактика и т.д. Но также понятно, что рано или поздно необходимо явно зафиксировать границу регенерации сущностей, обусловленную конечностью вычислительных ресурсов, и как следствие, тем, что эти ресурсы следует расходовать экономно. Таким образом, рано или поздно(скорее, рано), у нас появится сущность, которая не регенерируется при изменении своих составных частей. Эту сущность НЕВОЗМОЖНО реализовать в виде детерминированного состояния (чтобы не превысить ресурсную границу), она и будет называться объектом. Это и есть ответ на твой вопрос


Ты что-то путаешь. Зачем что-то регенерировать, есть вполне строгие методы позволяющие заменить один элемент в
массиве на другой без копирования всего массива.

V>Еще хочу обратить внимание, что любая другая сущность, взаимодействующая с изменяемой, также обязана быть изменяемой, то есть начиная с некоторого уровня абстракции, функциональное программирование исчезает полностью!!! Отсюда следует, что функциональные языки в целом не могут заменить итеративные. Ну разве что их гибриды в некоторых областях применения...


Странный и бездоказательный вывод. Функциональное программирование исчезает только при вводе-выводе, поскольку
внешний мир невозможно проконтролировать ну и что?
Re[12]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 02.10.04 08:53
Оценка:
Здравствуйте, Quintanar, Вы писали:


Q>Чего-то я не понял, что ты этим хочешь доказать. С теоретической точки зрения императивные языки ничем не отличаются от функциональных — любой алгоритм реализованный на одном можно реализовать на другом.

А кто срорит? Вопрос в цене.

Q>С практической точки зрения у функциональных языков есть проблема — они работают на императивной машине и следовательно должны

Q>уметь с ней как-то общаться минимизируя возникающий урон. Эти задачи решаются, в Haskell'е даже строго
Q>функционально, моделируя состояние внешнего мира. В чем проблема я не вижу. Зачем кого-то убивать
см. далее

V>>Понятно, что этот процесс регенерации сущностей теоретически должен продолжаться бесконечно: поменяется страна, планета, галлактика и т.д. Но также понятно, что рано или поздно необходимо явно зафиксировать границу регенерации сущностей, обусловленную конечностью вычислительных ресурсов, и как следствие, тем, что эти ресурсы следует расходовать экономно. Таким образом, рано или поздно(скорее, рано), у нас появится сущность, которая не регенерируется при изменении своих составных частей. Эту сущность НЕВОЗМОЖНО реализовать в виде детерминированного состояния (чтобы не превысить ресурсную границу), она и будет называться объектом. Это и есть ответ на твой вопрос


Q>Ты что-то путаешь. Зачем что-то регенерировать, есть вполне строгие методы позволяющие заменить один элемент в

Q>массиве на другой без копирования всего массива.
Это как раз то, о чем я говорю. Если мы изменим элемент массива без его регенерации, то получим функцию с побочным эффектом. Массив теперь станет изменяемой сущностью, т.е. объектом, инкипсулирующим свое сотояние. Манипулировать такими изменяемыми сущностями, применяя чистый функциональный подход в общем случае невозможно, и хотим мы того, или нет, придется прсать итеративную программу. То есть на определенном уровне абстракции функциональный подход изчезает.


V>>Еще хочу обратить внимание, что любая другая сущность, взаимодействующая с изменяемой, также обязана быть изменяемой, то есть начиная с некоторого уровня абстракции, функциональное программирование исчезает полностью!!! Отсюда следует, что функциональные языки в целом не могут заменить итеративные. Ну разве что их гибриды в некоторых областях применения...


Q>Странный и бездоказательный вывод.

С чем именно ты не согласен? С тем, что побочные эффекты, возникающие в изменяемой сущности приведут к появлению побочных эффектов в других сущностях, взаимодействующих с данной?

Q>Функциональное программирование исчезает только при вводе-выводе, поскольку

Q>внешний мир невозможно проконтролировать ну и что?
Часто и внутренний мир контролировать очень накладно. Пример тому — те же массивы.
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[13]: Вопрос о конкретных примерах
От: INTP_mihoshi Россия  
Дата: 02.10.04 12:15
Оценка:
Здравствуйте, prVovik, Вы писали:

V>Это как раз то, о чем я говорю. Если мы изменим элемент массива без его регенерации, то получим функцию с побочным эффектом. Массив теперь станет изменяемой сущностью, т.е. объектом, инкипсулирующим свое сотояние. Манипулировать такими изменяемыми сущностями, применяя чистый функциональный подход в общем случае невозможно, и хотим мы того, или нет, придется прсать итеративную программу. То есть на определенном уровне абстракции функциональный подход изчезает.


Haskell — чисто функциональный язык. В программах на нем функциональный подход никуда нее исчезает.

Массив до изменения — это одна сущность/значение. Массив после изменения — другая. Можно рассмотреть сущность, объединяющую все состояния массива во все единицы времени.

Любой изменяющийся объект можно представить в виде значения функции двуэ переменных — времени и "указателя" на объект. Значение этой функции от аргументов ("Возраст Иванова", "сейчас") и ("Возраст Иванова", "год назад") имеет различные аргументы, чледовательно, имеет различные значения.

Так что, изменяемость не противоречит функциональному подходу. Хотя и может вносить трудности в реализации.

Q>>Функциональное программирование исчезает только при вводе-выводе, поскольку

Q>>внешний мир невозможно проконтролировать ну и что?
V>Часто и внутренний мир контролировать очень накладно. Пример тому — те же массивы.
Это тоже вопрос реализации. В функциональной программе можно на этапе компиляции проверить, требуется ли где-то одновременно значение массива в разные моменты времени. И подобрать наиболее подходяшую реализацию массива.

Кстати, гибридный OCaml как раз тем и хорош, что можно императивную реализацию обернуть в чисто функциональный интерфейс не выходя, за пределы языка.
Re[14]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 02.10.04 13:25
Оценка:
Здравствуйте, INTP_mihoshi, Вы писали:

INT>Массив до изменения — это одна сущность/значение. Массив после изменения — другая.

А если на этот массив уже существуют ссылки?
После изменения массива, сущности, ссылающиеся на него могут начать работать иначе. То есть появится побочный эффект от изменения. После чего о функциональном программировании можно будет благополучно забыть...

INT>Можно рассмотреть сущность, объединяющую все состояния массива во все единицы времени.

И что это даст?

INT>Любой изменяющийся объект можно представить в виде значения функции двуэ переменных — времени и "указателя" на объект. Значение этой функции от аргументов ("Возраст Иванова", "сейчас") и ("Возраст Иванова", "год назад") имеет различные аргументы, чледовательно, имеет различные значения.

Во-первых, проблема не решена. Побочные эффекты будут проявляться при изменении времени.
Во-вторых, это простой случай. Что, если бы пришлось учитывать не возраст, а, например, количество волос на голове? Пришлось бы каждый момент времени сохранять текущее значение?

INT>Так что, изменяемость не противоречит функциональному подходу. Хотя и может вносить трудности в реализации.

Увы, но изменяемость ставит крест на функциональном подходе

V>>Часто и внутренний мир контролировать очень накладно. Пример тому — те же массивы.

INT>Это тоже вопрос реализации. В функциональной программе можно на этапе компиляции проверить, требуется ли где-то одновременно значение массива в разные моменты времени. И подобрать наиболее подходяшую реализацию массива.
Совершенно верно. Но проблему это всеравно не решает.

INT>Кстати, гибридный OCaml как раз тем и хорош, что можно императивную реализацию обернуть в чисто функциональный интерфейс не выходя, за пределы языка.

Хрчу заметить, что построить функциональный интерфейс к императивной резализации можно, если передавать в качестве параметра всю необходимую для выполнения алгоритма информацию, причем передавать эту информанию необходимо не по ссылке, а по значению. Отсюда следует, что применять такой подход можно только в простейших случаях, когда объем передаваемой информации достаточно мал, чтобы можо было позволить передавать копию этой информации.
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[15]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 02.10.04 13:31
Оценка:
Здравствуйте, prVovik, Вы писали:

INT>>Кстати, гибридный OCaml как раз тем и хорош, что можно императивную реализацию обернуть в чисто функциональный интерфейс не выходя, за пределы языка.

V>Хрчу заметить, что построить функциональный интерфейс к императивной резализации можно, если передавать в качестве параметра всю необходимую для выполнения алгоритма информацию, причем передавать эту информанию необходимо не по ссылке, а по значению. Отсюда следует, что применять такой подход можно только в простейших случаях, когда объем передаваемой информации достаточно мал, чтобы можо было позволить передавать копию этой информации.

Убс, сначала написал, а потом сам понял, что не прав. Конечно, можно передавать и по ссылке. Не бейте сильно...
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[13]: Вопрос о конкретных примерах
От: Gaperton http://gaperton.livejournal.com
Дата: 02.10.04 16:35
Оценка:
Здравствуйте, prVovik, Вы писали:

VQ>>Ты что-то путаешь. Зачем что-то регенерировать, есть вполне строгие методы позволяющие заменить один элемент в

Q>>массиве на другой без копирования всего массива.
V>Это как раз то, о чем я говорю. Если мы изменим элемент массива без его регенерации, то получим функцию с побочным эффектом. Массив теперь станет изменяемой сущностью, т.е. объектом, инкипсулирующим свое сотояние. Манипулировать такими изменяемыми сущностями, применяя чистый функциональный подход в общем случае невозможно, и хотим мы того, или нет, придется прсать итеративную программу. То есть на определенном уровне абстракции функциональный подход изчезает.

Гхм... Посмотри решето Эратосфена на Clean
Автор: Gaperton
Дата: 28.09.04
, где мы мерялись с С++. Там массив меняется с функциональной семантикой, но деструктивно. При этом Clean не допускает побочных эффектов. Парадокс? Нет, потому что массив single threaded (можешь по этим словам пустить google), т. е. на него не остается ссылок после "изменения", а до "изменения" была только одна. Здесь компилятор может применить (и применяет) деструктивное изменение, что и можно видеть посмотрев результат тестов.

Ну а про Haskell и How To Declare Imperative (Wadler) тебе если еще и не написали, то напишут.
Re[14]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 02.10.04 18:24
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Здравствуйте, prVovik, Вы писали:


G>Гхм... Посмотри решето Эратосфена на Clean
Автор: Gaperton
Дата: 28.09.04
, где мы мерялись с С++. Там массив меняется с функциональной семантикой, но деструктивно.

Для демонстрации сферического коня в вакуумме пример вполне сгодится...

G>При этом Clean не допускает побочных эффектов. Парадокс? Нет, потому что массив single threaded (можешь по этим словам пустить google), т. е. на него не остается ссылок после "изменения", а до "изменения" была только одна. Здесь компилятор может применить (и применяет) деструктивное изменение, что и можно видеть посмотрев результат тестов.

Я и не сомневался в том, что простейшие случаи можно оптимизировать. Но в реальной жизни (в отличии от коней в вакууме), на изменяемый объект очень часто существуют ссылки

G>Ну а про Haskell и How To Declare Imperative (Wadler) тебе если еще и не написали, то напишут.

Все, теперь ночь спать не буду...
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[15]: Вопрос о конкретных примерах
От: FR  
Дата: 02.10.04 19:36
Оценка: 16 (1)
Здравствуйте, prVovik, Вы писали:

V>Здравствуйте, Gaperton, Вы писали:


G>>Здравствуйте, prVovik, Вы писали:


G>>Гхм... Посмотри решето Эратосфена на Clean
Автор: Gaperton
Дата: 28.09.04
, где мы мерялись с С++. Там массив меняется с функциональной семантикой, но деструктивно.

V>Для демонстрации сферического коня в вакуумме пример вполне сгодится...

Я уже три раза писал что меряют скорость работы памяти, но не слышат. Вообще в этом тесте если выбирать те ограничения которые здесь были (~3e6 элементов) то bcc5.4 c отключенной оптимизацией показывает примерно одинаковую скорость с VC7.1 c /O2

>bcc32 -Od Eratosthenes.cpp
Borland C++ 5.4 for Win32 Copyright (c) 1993, 1999 Inprise Corporation
Eratosthenes.cpp:
Turbo Incremental Link 4.00 Copyright (c) 1997, 1999 Inprise Corporation

>Eratosthenes.exe
Count: 216816
Time: 1321

>cl /O2 Eratosthenes.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

Eratosthenes.cpp
Microsoft (R) Incremental Linker Version 7.10.3077
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:Eratosthenes.exe
Eratosthenes.obj

>Eratosthenes.exe
Count: 216816
Time: 1281

>
Re[13]: Вопрос о конкретных примерах
От: Quintanar Россия  
Дата: 02.10.04 19:59
Оценка: +1
дравствуйте, prVovik, Вы писали:

Q>>Ты что-то путаешь. Зачем что-то регенерировать, есть вполне строгие методы позволяющие заменить один элемент в

Q>>массиве на другой без копирования всего массива.
V>Это как раз то, о чем я говорю. Если мы изменим элемент массива без его регенерации, то получим функцию с побочным эффектом. Массив теперь станет изменяемой сущностью, т.е. объектом, инкипсулирующим свое сотояние. Манипулировать такими изменяемыми сущностями, применяя чистый функциональный подход в общем случае невозможно, и хотим мы того, или нет, придется прсать итеративную программу. То есть на определенном уровне абстракции функциональный подход изчезает.

Из локального изменения массива не следует возникновение строннего эффекта. Для того, чтобы этого добиться в чистых функциональных языках применяют разные методы, про Clean тебе ответил Gaperton, а в Haskell'e это решается с помощью монад — они позволяют упорядочить вычисления, добиться того, чтобы перед вычислением Б обязательно вычислялось А. Это продемонстрировано в моей версии решета, но если ты не знаешь языка, вряд ли ее поймешь. Если ты считаешь, что такие ограничения сильно стесняют и нормальную программу не напишешь, твое дело. Однако на Haskell'e написана большая часть его компилятора, а это немаленькая программа и она работает.
Дело в том, что реально такие сугубо императивные куски типа работы с массивами встречаются достаточно редко, их можно изолировать и обрабатывать отдельно в монадном-императивном стиле. Потом массив можно банально перевести в read-only форму и работать с ссылкой на него, не заморачиваясь проблемой копирования его целиком. Ты просто привык к императивщине и тебе кажется, что она везде и без нее и пару чисел не сложить. На самом деле ее мало, просто надо привыкнуть думать по другому.
Re[10]: Вопрос о конкретных примерах
От: EKSoft Беларусь  
Дата: 02.10.04 22:32
Оценка:
Здравствуйте, Quintanar, Вы писали:

Q>Задача сугубо императивная, поэтому и стиль такой. Блин, нашли что обсуждать, ей богу, еще бы перемножение матриц сравнивали. Если на то пошло, нужно смотреть более функциональные задачи. У меня, например, есть пара парсеров на OCaml. Один интерпретор примитивного языка, а другой конвертатор из bnf в sml yacc. Могу их выложить, хотя я ими не очень доволен, писал их когда еще слабо разбирался в функциональном стиле.


Интересно было бы взглянуть.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re[15]: Вопрос о конкретных примерах
От: INTP_mihoshi Россия  
Дата: 03.10.04 11:52
Оценка:
Здравствуйте, prVovik, Вы писали:

V>Здравствуйте, INTP_mihoshi, Вы писали:



INT>>Любой изменяющийся объект можно представить в виде значения функции двуэ переменных — времени и "указателя" на объект. Значение этой функции от аргументов ("Возраст Иванова", "сейчас") и ("Возраст Иванова", "год назад") имеет различные аргументы, чледовательно, имеет различные значения.

V>Во-первых, проблема не решена. Побочные эффекты будут проявляться при изменении времени.
Какие побочные эффекты?

V>Во-вторых, это простой случай. Что, если бы пришлось учитывать не возраст, а, например, количество волос на голове? Пришлось бы каждый момент времени сохранять текущее значение?

Это уже вопросы реализации.

V>Совершенно верно. Но проблему это всеравно не решает.

Какую проблему?

Любую задачу, любой алгоритм, который можно выразить с помощью ыормальной логики, можно описать в чисто функциональном стиле. Это доказывается. Если ты хочешь доказать обратное — не трудись, это невозможно. Если хочешь понять, как это делается, почитай про монады. Хотя бы на этом же форуме. Если тебе не понятны какие-то детали — задавай конкретный вопрос, я отвечу. Если тебе не понятно как решается в функциональном стиле какая-то конкретная задача — давай пример, покажу.
Re[9]: Вопрос о конкретных примерах
От: INTP_mihoshi Россия  
Дата: 03.10.04 11:59
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Но C# — это строго-типизированный язык. Об этом даже в спецификации наисано. Так что ты ошибашся.

INT>>Когда я ими пользовался, мне они показались неудобными и неинтуитивными. Может, с непривычки.

VD>Именно что. И вообще твое отвращение к Шарпу явно основано на том, что ты в него не вник.

Зачем же сразу отвращение. Бытовые задачи на нем писать приятнее, чем на С++ или яве. И вообще чем бы то ни было. Просто я не считаю его подходящим для cutting edge вещей
Re[11]: Вопрос о конкретных примерах
От: Sinclair Россия https://github.com/evilguest/
Дата: 04.10.04 04:40
Оценка: +1
Здравствуйте, prVovik, Вы писали:

V>Объясню на пальцах...

V>Вооружимся функциональным подходом и рассмотрим некоторую сущность, которая существует в пределах своей среды окружения. Например, среда окружения — это предприятие П1, а сущность — сотрудник Иванов, которому 35 лет. В один прекрасный день, этот сотрудник справляет себе день рождения, в результате чего Иванов(35) умирает, и на его месте появляется Иванов(36). Посмотрим на предприятие: раньше было предприятие П1, в котором работал сотрудник Иванов(35), теперь Иванов(35) умер, следовательно должно также умереть и предприятие, вместе с остальными сотрудниками. На месте этих трупов появится новое предприятие П2, в котором теперь работает сотрудник Иванов(36). Предприятие П1 также существовало в пределах своей среды окружения, например, множества других предприятий, с которыми оно взаимодействовало. И этим предприятиям также придется помереть со всеми своими сотрудниками после того, как на предприятии П1 сотрудник Иванов отпразнует свой день рождения.

Абсолютно верно. С философской точки зрения, ФП исповедует принцип "нельзя дважды войти в одну и ту же реку". Поскольку математики работают с абстрактными объектами произвольного масштаба, их никак не смущает ежесекундная смерть и возрождение вселенной.
Отличие между ФП и ИП — только в том, что в ИП четко фиксируется набор возможных изменений состояния. Предположим, что нашей вселенной является бесконечный одномерный массив целых чисел. С точки зрения ФП нам никто не запрещает ввести функцию F, которая отображает этот массив в развернутый на 180. Что-то типа F: (Universe' <- Universe[-i]). И эта функция ничуть не хуже такой, которая меняет местами ровно два элемента этого массива. В любом случае Universe умирает, и возникает Universe'.
С точки зрения ИП, мы располагаем очень ограниченным набором функций смены состояния вселенной. Наша вселенная от рождения умеет менять два элемента местами. Но любую "большую" функцию мы обязаны представить как суперпозицию этих более маленьких. Вот это представление и является императивной программой.
К сожалению, большинство макрофункций допускают [бесконечно] большое количество вариантов такого разложения. Именно за это нам платят деньги.

В итоге, императивное программирование предоставляет программисту возможность формулировать эти представления вручную. Функциональное программирование больше сосредотачивается на результате, чем на процессе. Это фактически попытка передать больше обязанностей по выполнению [i]той же
задачи компилятору.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: ФП: вводная статья
От: faulx  
Дата: 04.10.04 05:27
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Lloyd, Вы писали:


L>>Удивительно, но у Кнута тогда он тоже перевран.


VD>На память говорить не хорошо, но вроде бы был верным. Уж точно сортировка была по месту. К тмоу же у алгоритма есть автор. И кнут к нему не имеет ни малейшего отношения. Так что классический, есть классический.


"По месту" — это деталь реализации. К алгоритму сортировки как таковому имеет отдаленное отношение. Если завтра изобретут новую, более эффективную реализацию — что, окажется, что Хоар тоже все переврал?

Еще такое соображение. Когда вы думаете об алгоритме быстрой сортировки, что вы вспоминаете — его математическое описание (а оно очень близко к программе на Haskell'е) или реализацию на C?

А вообще, конечно, на идеальном декларативном языке (синтаксис придумал сам, на ходу) алгоритм сортировки записывается примерно так:

sort (in Sequence seq, out Sequence sorted)
PRE{
   // Предусловие - вероятно, пустое
}
POST{
   // Постусловие - описание отсортированности последовательности sorted
}


А уж компилятор должен по этому описанию изобрести алгоритм быстрой сортировки, а заодно и его эффективную реализацию. Вот жизнь-то начнется, когда напишут такой компилятор
Re[2]: ФП: вводная статья
От: faulx  
Дата: 04.10.04 06:12
Оценка:
Здравствуйте, Banch, Вы писали:

Q>>Имея эту функцию мы можем создать новые функции типа

Q>>
Q>>inc x = add 1 x
Q>>add10 x = add 10 x
Q>>

Q>>первая из которых увеличивает свой аргумент на 1, а вторая на 10. Разница с обычным вызовом более
Q>>общей подфункции с некоторыми фиксированными аргументами заключается в том, что функция add 1 будет
Q>>частично вычислена один раз и при дальнейших вызовах перевычислятся не будет.

B>не понял что там можно частично вычислить в выражении add 1 ?? заранее вычислить что 1 это 1 ?!

B>даже допустим там стоит не 1, а sqrt(2), ну и что — я могу положить это один раз в статическую переменную

Может, не совсем ответ, но просто вспомнилось. Когда я еще учился в институте, мы часто писали алгоритмы оптимизации функций (градиентный метод и т.п.) Всегда стояла проблема — скажем, оптимизируется функция f(a1, a2, x1, x2, x3) по аргументам x1, x2, x3 с какими-то значениями параметров a1, a2. Были мы студентами и делали все по-студенчески — забивали конкретные значения a1, a2 в код (и перекомпилировали при каждом изменении), или передавали через глобальные переменные. Сейчас, глядя на математические библиотеки, написанные на C, я вижу, что в них принято передавать в оптимизируемую (или интегрируемую, дифференцируемую и т.п.) функцию дополнительный параметр void *data, в котором содержится голый указатель на пользовательские параметры (соотвественно, возникает куча приведений типов).

В студенческие годы я изобрел велосипед в виде объектно-ориентированного подхода к решению этой задачи — создавал объект с виртуальной функцией f(x1, x2, x3), который и передавал в функцию оптимизации (параметры a1, a2 лежали в объекте и задавались конструктором). Сейчас я бы, наверное, воспользовался каррингом.

Теперь, в свете этой истории, ответ. В выражении add 1 вычисляется функция. Она не имеет имени, а действие ее заключается в прибавлении 1 к аргументу. Это простейший пример. f a1 a2 — это функция от трех аргументов x1, x2, x3, которую можно смело передавать в другую функцию трехмерной оптимизации.

Если говорить чуть точнее, выражения add 1 и f a1 a2 создают так называемые замыкания (closures) — функции + ассоциированные с ними данные. Это понятие довольно базовое, но относится скорее к реализации. А вообще, сходство замыканий с объектами в ООП позволяет формализовать ООП в рамках функционального программирования, и даже реализовать объектные возможности.
Re[3]: ФП: F#
От: Alexey Chen Чили  
Дата: 04.10.04 06:14
Оценка: +1
Здравствуйте, gloomy rocker, Вы писали:

GR>Посмотри на F#

GR>На нем можно писать код, используя FCL, в которой собрано огромное количество велосипедов.

Вот написал бы кто-нибудь вводную статью по F# и с примерами применения.... было бы реально полезно.
Re[4]: ФП: F#
От: gloomy rocker Россия  
Дата: 04.10.04 06:45
Оценка:
Здравствуйте, Alexey Chen, Вы писали:

AC>Здравствуйте, gloomy rocker, Вы писали:


GR>>Посмотри на F#

GR>>На нем можно писать код, используя FCL, в которой собрано огромное количество велосипедов.

AC>Вот написал бы кто-нибудь вводную статью по F# и с примерами применения.... было бы реально полезно.


Честно говоря у меня дальше беглого взгляда на примеры, идущие в комплекте с F#, дело не пошло.
Так что вводную статью я тоже не против почитать.
Скука — двигатель прогресса.
Re: ФП: вводная статья
От: faulx  
Дата: 04.10.04 08:29
Оценка: 74 (6)
Q>Строгая типизация

Предлагаю добавить пару слов о значении типизации.

Сама по себе типизация не имеет отношения к функциональности того или иного языка. Но так уж сложилось, что когда говорят о типизированных функциональных языках, речь обычно идет о так называемой системе типов Хиндли-Милнера, использующейся в Haskell и Ocaml (или SML).

Система типов Хиндли-Милнера — конструкция, ортогональная свойству функциональности языка. Бывают функциональные языки, не использующие эту систему (правда, императивные языки с этой системой типов мне неизвестны). Давать формальное определение этой системы мне сейчас не хочется, да это и не нужно. Следует обратить внимание прежде всего на то, как правильное использование типов повышает надежность программ. (В этой фразе ключевое слово — "правильное".)

Начнем с простого примера (буду приводить примеры на Haskell). В какую-либо функцию нам нужно передать день недели и в зависимости от него что-нибудь в ней сделать. Самое простое решение — закодировать дни недели числами от 1 до 7, и писать что-нибудь вроде:

case day_of_week of
  1 -> Делаем что-то для понедельника
  2 -> Для вторника
  ...
  7 -> Ура! Воскресенье!


К сожалению, в этом коде есть проблема: что произойдет, если day_of_week по какой-либо причине станет равным другому числу, отличному от 1...7? Другой недостаток — "магические числа" в коде. В С мы бы ввели enum и писали бы:

switch(day_of_week){
  MONDAY: ...; break;
  ...
  SUNDAY: ...; break;
}

Читаемость повысилась. Однако в С нет особых трудностей создать ситуацию, когда day_of_week принимает значения, отличные от диапазона enum'а. Необходимо делать проверку (вводить default) и засорять код.

В Haskell'e (или любом другом языке с той же системой типов) мы вводим новый тип, аналогичный C-шному enum'у следующей конструкцией:

data Weekday = Monday | Tuesday | ... |Sunday

Пояснения:
  1. Многоточие — не элемент синтаксиса, а следствие лени
  2. Новый тип называется Weekday, data — ключевое слово, означающее, что мы вводим новый тип
  3. Вертикальная черта читается как "или" и разделяет варианты значений, которые может принимать переменная нового типа
Таким образом читается запись следующим образом: "введем новый тип Weekday, переменные которого могут принимать значения Monday или Tuesday и т.д."
Заметим, что здесь ничего не говорится о том, что такое Monday, Tuesday и т.д. — это неделимые конструкции, называемые "конструкторами данных". Никакое приведение типов к ним от целых или от строк невозможно, и если установлено, что переменная day_of_week имеет тип Weekday, можно спать спокойно: никаких других значений, отличных от указанных, она не примет не при каких обстоятельствах. В соответствующем коде:
case day_of_week of
  Monday  -> Делаем что-то для понедельника
  Tuesday -> Для вторника
  ...
  Sunday  -> Ура! Воскресенье!

никаких дополнительных проверок делать не надо. Более того, если мы пропустим какой-либо день недели, компилятор выдаст нам предупреждение и даже укажет, какой именно день мы пропустили!

Конструкторы типов и сам тип могут иметь в качестве параметра другой тип — нечто вроде шаблонов С++. Скажем, рассмотрим следующий (стандартный) тип:
data Maybe a = Nothing | Just a

Что мы здесь видим? Определяется новый тип Maybe, параметризованный тИповой переменной a, в качестве которой можно использовать любой другой тип (конструкция аналогична template<class A> class Maybe). (Заметим в скобках, что в Haskell'e конкретные типы и типовые переменные различаются тем, что имя типа может начинаться только с заглавной буквы.) У нашего типа два конструктора — один (Nothing) без параметров, другой (Just) — с параметром. Таким образом, например, переменные типа Maybe Int могут принимать значения Nothing, Just 1, Just 2 и т. п.

Зачем это нужно? Вспомним старые добрые времена, язык С и функцию fopen. В случае успешного открытия файла она возвращает указатель на некоторую структуру, в случае ошибки — NULL. Огромное количество других функций так или иначе используют какие-либо выделенные значения возвращаемого типа функции для сигнализации об ошибках в них, причем делают это совершенно вразнобой: кто использует 0, кто 1, кто -1. Зачастую в возвращаемом типе не остается места для "ошибочных" значений, и приходится идти на ухищрения вроде глобальной переменной errno и т.п. И, что хуже всего, никто, кроме совести программиста, не может проконтролировать, что обработка ошибочных значений присутствует в программе.

В языке с системой типов Хиндли-Милнера функция fopen возвращала бы тип Maybe File, где File — тип, описывающий правильно открытый файл, а значение Nothing сигнализировало бы, что файл не открылся. Код, обрабатывающий эту ситуацию, выглядит примерно так:
case fopen(file_name, flags) of
  Just file -> do_something(file)
  Nothing   -> Обрабатываем ошибочную ситуацию.

Здесь мы использовали сопоставление с образцом, что может служить темой отдельного разговора, но в данном случае должно быть понятно и так. Если возвращаемое значение функции fopen имеет вид Just file, где file — переменная типа File, соответствующая корректно открытому файлу, то мы вызываем функцию do_something. Если же файл не открыт, обрабатываем эту ситуацию.

Заметим, что функция do_somtheing принимает параметры типа File, т.е. предполагает, что в нее передаются только правильно открытые файлы. Мы не можем проигнорировать этот факт и написать do_something(fopen(file_name, flags)) — этот код не скомпилируется, поскольку не пройдет проверку по типам. Если мы забудем написать вариант для Nothing, компилятор выдаст нам предупреждение. Таким образом, компилятор помогает нам контролировать проверку возвращаемых значений функций!

PS. Несколько замечаний:

  1. Пример с fopen можно улучшить. Так, вместо констатации простого факта, что файл не открылся, можно добавить информацию о том, по каким причинам это произошло. Для этого надо изменить возвращаемый тип функции fopen. Предоставляем это читателю в качестве упражнения (подсказка: тип может иметь несколько параметров)
  2. В самом начале упоминалось важность правильного использования типов. Само по себе наличие системы Хиндли-Милнера в языке не делает программы на нем более надежными, грамотность в ее использовании очень важна. Так, мы могли и не вводить тип Weekday, а для возвращаемых значений функций по-старинке использовать -1 или что-нибудь в этом роде. Тогда все преимущества теряются.
  3. Доказано, что программы на языке с системой типов Хиндли-Милнера не могут "упасть" с ошибками, связанными с доступом по неверному адресу, нулевому указателю.
  4. Из сказанного еще не следует, что динамическая типизация не имеет права на жизнь или что программы на языке с динамической типизацием менее надежны.
Re[7]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.10.04 10:25
Оценка:
Здравствуйте, faulx, Вы писали:

F>"По месту" — это деталь реализации. К алгоритму сортировки как таковому имеет отдаленное отношение. Если завтра изобретут новую, более эффективную реализацию — что, окажется, что Хоар тоже все переврал?


В приведенном виде сортировка уже может трактоваться как сортировка слиянием или даже пиповая. Хор изобрел конкретный алгоритм.

Переврать Хор ничего не мог так как он был изобретателем данного алгоритма.

Кстати, с филосовфской точки зрения реализация быстрой сортировки функциональными средствами невозможно так как это не алгоритмический подход. Вещь суть ФЯ отках от конкретного алгоритма в пользу декларативности. На ФЯ мы скорее выражаем класс алгоритма (логарифмический) нежели его самого. Я конечно понимаю, что это больше похоже на шутку, но это как раз та шутка в которой доля шутки не очень велика.

F>Еще такое соображение. Когда вы думаете об алгоритме быстрой сортировки, что вы вспоминаете — его математическое описание (а оно очень близко к программе на Haskell'е) или реализацию на C?


Алгоритм не может быть описан математически. Матемотически можно только задать принцип. А принцип скорее оностистя к лассу алгоритма. Ведь основной принцип в бустрой сортировке это рекурсивное деление списков на подсписки. Но под это определение начинают попадать и некоторые другие алгоритмы.

Ну, и главное, в рамках современных компьютеров быстрой эта сортировка может быть только если она не ведет к расходу памяти.

К тому, же как я говорил у Хора за "средний" брался то ли элемент массива находящийся посередине, то ли послебний (правый). Если брать не средний элемент, то на сортированном списке алгоритм будет существнно медленнее.

F>А вообще, конечно, на идеальном декларативном языке (синтаксис придумал сам, на ходу) алгоритм сортировки записывается примерно так:


F>
F>sort (in Sequence seq, out Sequence sorted)
F>PRE{
F>   // Предусловие - вероятно, пустое
F>}
F>POST{
F>   // Постусловие - описание отсортированности последовательности sorted
F>}
F>


F>А уж компилятор должен по этому описанию изобрести алгоритм быстрой сортировки, а заодно и его эффективную реализацию.


Это, как я понимаю, называется логическим программированием.

F>Вот жизнь-то начнется, когда напишут такой компилятор


Прологу уже много лет. Кстати, не факт, что такие простые вещи как сортировка не будет проще описать алгоритмически. Ну, а глваная проблема тут в том, что компилятор должен знать конкретные алгоритмы и уметь подбирать наиболее подходящий в конкретном случае, а то и уметь изобретать алгоритмы и выбирать наиболее подходящий. Ну, а это уже искуственный интелект. Да даже не искуственный, а идеальный. Ведь далеко не каждый человек знает все нужные алгоритмы и умеет правильно их выбирать. Но мечат о зеленой факсовй кномке нажатие на ктороую автоматически решает луюбую сложную проблему — это та мечта к которой нужно стремиться всему человечесту.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.10.04 10:25
Оценка: +1 :)
Здравствуйте, INTP_mihoshi, Вы писали:

INT>Зачем же сразу отвращение. Бытовые задачи на нем писать приятнее, чем на С++ или яве. И вообще чем бы то ни было. Просто я не считаю его подходящим для cutting edge вещей


Ну, это смотря чего резать.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: ФП: вводная статья
От: WolfHound  
Дата: 04.10.04 14:07
Оценка:
Здравствуйте, faulx, Вы писали:

F>Зачем это нужно? Вспомним старые добрые времена, язык С и функцию fopen. В случае успешного открытия файла она возвращает указатель на некоторую структуру, в случае ошибки — NULL. Огромное количество других функций так или иначе используют какие-либо выделенные значения возвращаемого типа функции для сигнализации об ошибках в них, причем делают это совершенно вразнобой: кто использует 0, кто 1, кто -1. Зачастую в возвращаемом типе не остается места для "ошибочных" значений, и приходится идти на ухищрения вроде глобальной переменной errno и т.п. И, что хуже всего, никто, кроме совести программиста, не может проконтролировать, что обработка ошибочных значений присутствует в программе.

Тут для полноты картины надо еще и про исключения вспомнить.
... << RSDN@Home 1.1.4 rev. 185 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[15]: Вопрос о конкретных примерах
От: Gaperton http://gaperton.livejournal.com
Дата: 04.10.04 14:31
Оценка:
Здравствуйте, prVovik, Вы писали:

V>Здравствуйте, Gaperton, Вы писали:


G>>Здравствуйте, prVovik, Вы писали:


G>>Гхм... Посмотри решето Эратосфена на Clean
Автор: Gaperton
Дата: 28.09.04
, где мы мерялись с С++. Там массив меняется с функциональной семантикой, но деструктивно.

V>Для демонстрации сферического коня в вакуумме пример вполне сгодится...
Вообще, это была демонстрация элементарной работы с массивами. Ты уверен, что поймешь более сложный пример? А то если тебе конь в вакууме привиделся... Вобщем, не вижу смысла делать это в форуме, заинтересованный человек в состоянии найти более сложные примеры сам.

G>>При этом Clean не допускает побочных эффектов. Парадокс? Нет, потому что массив single threaded (можешь по этим словам пустить google), т. е. на него не остается ссылок после "изменения", а до "изменения" была только одна. Здесь компилятор может применить (и применяет) деструктивное изменение, что и можно видеть посмотрев результат тестов.

V>Я и не сомневался в том, что простейшие случаи можно оптимизировать. Но в реальной жизни (в отличии от коней в вакууме), на изменяемый объект очень часто существуют ссылки
Ой! Правда?

G>>Ну а про Haskell и How To Declare Imperative (Wadler) тебе если еще и не написали, то напишут.

V>Все, теперь ночь спать не буду...
Хочешь — не спи. Я на твою ночь не претендую
Re[3]: ФП: вводная статья
От: INTP_mihoshi Россия  
Дата: 04.10.04 14:40
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Тут для полноты картины надо еще и про исключения вспомнить.


Исключения перпендикулярны и функциональности, и типам. Но замечательно с ними уживаются. Исключение просто можно мыслить как вариант Variant
Re[16]: Вопрос о конкретных примерах
От: Gaperton http://gaperton.livejournal.com
Дата: 04.10.04 14:43
Оценка:
Здравствуйте, FR, Вы писали:

FR>Я уже три раза писал что меряют скорость работы памяти, но не слышат. Вообще в этом тесте если выбирать те ограничения которые здесь были (~3e6 элементов) то bcc5.4 c отключенной оптимизацией показывает примерно одинаковую скорость с VC7.1 c /O2


Ну если ты настаиваешь... Напиши решето эратосфена на Python (без psyco), и померяй им скорость работы памяти. Боюсь, что память почему-то будет работать медленнее , наверно программа на питоне ее сломает.

Мы вообще-то компиляторы сравнивали, на одном алгоритме. Точнее, эффективность работы с массивами в чистом ФЯ сравнительно с С++. А не устанавливали рекорды скорости. Поэтому и не слышим.

То, что С++ и Clean уперлись в память, говорит об эффективной работе с массивами. Haskell не смог "упереться в память". Боюсь у питона тоже не получится.
Re[4]: ФП: вводная статья
От: WolfHound  
Дата: 04.10.04 17:52
Оценка:
Здравствуйте, INTP_mihoshi, Вы писали:

WH>>Тут для полноты картины надо еще и про исключения вспомнить.

INT>Исключения перпендикулярны и функциональности, и типам. Но замечательно с ними уживаются. Исключение просто можно мыслить как вариант Variant
Я к тому что для сигнализации об ошибке еще и исключения используют...
... << RSDN@Home 1.1.4 rev. 185 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[7]: ФП: вводная статья
От: prVovik Россия  
Дата: 04.10.04 21:40
Оценка: :)))
Здравствуйте, faulx, Вы писали:

F>А вообще, конечно, на идеальном декларативном языке (синтаксис придумал сам, на ходу) алгоритм сортировки записывается примерно так:


F>
F>sort (in Sequence seq, out Sequence sorted)
F>PRE{
F>   // Предусловие - вероятно, пустое
F>}
F>POST{
F>   // Постусловие - описание отсортированности последовательности sorted
F>}
F>


F>А уж компилятор должен по этому описанию изобрести алгоритм быстрой сортировки, а заодно и его эффективную реализацию. Вот жизнь-то начнется, когда напишут такой компилятор


И не говори! Я уже даже представляю, какую первую программу для себя напишу:
Buisnes (in Man бедный, out Man богатый )
PRE
{
  мало денег
}
POST
{
  много денег
}


Э-х-х-х, и когда уже, наконец, появится этот компилятор???

... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[17]: Вопрос о конкретных примерах
От: FR  
Дата: 05.10.04 06:17
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Здравствуйте, FR, Вы писали:


FR>>Я уже три раза писал что меряют скорость работы памяти, но не слышат. Вообще в этом тесте если выбирать те ограничения которые здесь были (~3e6 элементов) то bcc5.4 c отключенной оптимизацией показывает примерно одинаковую скорость с VC7.1 c /O2


G>Ну если ты настаиваешь... Напиши решето эратосфена на Python (без psyco), и померяй им скорость работы памяти. Боюсь, что память почему-то будет работать медленнее , наверно программа на питоне ее сломает.


Я лучше на ocaml напишу Он точно не куда не упрется
Питон (c psyco) не может упереся в память, плохие у него массивы(вернее их и нету вовсе), мерять на специальных библиотечных массивах не стал, но скорее всего они уже упрутся в память.

G>Мы вообще-то компиляторы сравнивали, на одном алгоритме. Точнее, эффективность работы с массивами в чистом ФЯ сравнительно с С++. А не устанавливали рекорды скорости. Поэтому и не слышим.


А зря, потому что сравниваете не эффективность, а скорость работы шины памяти. Вообще наверно у меня были глюки когда я читал про хорошие компиляторы.

G>То, что С++ и Clean уперлись в память, говорит об эффективной работе с массивами. Haskell не смог "упереться в память". Боюсь у питона тоже не получится.


ну и что уперется в память могут языки (или компиляторы) производительность которых отличается на порядок, так что говорить об такой же эффективной реализации массивов в CLean как и в C++ очень даже некорректно, а из твоих постов напрашивается именно такой вывод.
Re[16]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 05.10.04 06:55
Оценка:
Здравствуйте, INTP_mihoshi, Вы писали:

INT>Здравствуйте, prVovik, Вы писали:


V>>Здравствуйте, INTP_mihoshi, Вы писали:



V>>Во-вторых, это простой случай. Что, если бы пришлось учитывать не возраст, а, например, количество волос на голове? Пришлось бы каждый момент времени сохранять текущее значение?

INT>Это уже вопросы реализации.
А именно о реализации и речь. Понятно, что в абстрактной теории все хорошо...

V>>Совершенно верно. Но проблему это всеравно не решает.

INT>Какую проблему?
Проблему изменения малого компонента системы без того, чтобы менять всю систему и при этом остаться в рамках функционального стиля.

INT>Любую задачу, любой алгоритм, который можно выразить с помощью ыормальной логики, можно описать в чисто функциональном стиле. Это доказывается. Если ты хочешь доказать обратное — не трудись, это невозможно.

Я уже много раз повторял, что я с этим не спорю. Речь не о математики, а о программировании, которое отличается от матиматики одной малозначительной деталью: вычислительные, увы, не бесконечны.
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[17]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 05.10.04 06:55
Оценка: -1 :)
Здравствуйте, Gaperton, Вы писали:

G>Мы вообще-то компиляторы сравнивали, на одном алгоритме. Точнее, эффективность работы с массивами в чистом ФЯ сравнительно с С++. А не устанавливали рекорды скорости. Поэтому и не слышим.

Ну тогда в качестве задачки предлагаю искать минимальный элемент в массиве. Для простоты элементы массива можно ниоткуда не вводить, а результат никуда не выводить.

void FindMin()
{
    int array[500000000]; // ДВА ГИГАБАЙТА !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    for( int i=0, min=array[0]; i < sizeof(array)/sizeof(int); ++i )
    {
        if( array[i] < min ) min = array[i];
    }
}

int main()
{
    FindMin();
    return 0;
}
Время выполнения: 0.0000000000 сек.


Не правда ли, у С очень эффективная работа с массивами!!!!!
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[14]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 05.10.04 06:55
Оценка:
Здравствуйте, Quintanar, Вы писали:

Q>Из локального изменения массива не следует возникновение строннего эффекта.

Из изменения массива появляется ВОЗМОЖНОСТЬ побочного эффекта. А функциональный стиль требует ГАРАНТИИ их отсутствия. Я понимаю, что в простейших случаях может сработать оптимизатор, но всеже...

Q>Для того, чтобы этого добиться в чистых функциональных языках применяют разные методы, про Clean тебе ответил Gaperton, а в Haskell'e это решается с помощью монад — они позволяют упорядочить вычисления, добиться того, чтобы перед вычислением Б обязательно вычислялось А.

Дак это и есть итеративная программа! То есть ты подтверждаешь мои слова!

Q>Дело в том, что реально такие сугубо императивные куски типа работы с массивами встречаются достаточно редко, их можно изолировать и обрабатывать отдельно в монадном-императивном стиле. Потом массив можно банально перевести в read-only форму и работать с ссылкой на него, не заморачиваясь проблемой копирования его целиком.

Опять таки, я с тобой абсолютно согласен, действительно, часть программы можно написать в функциональном стиле, но от императивного не избавиться. Об этом я писал еще в том посте, за который вы мне понаставили минусов (я, кстати, так и не погял: с чем именно вы не согласны? ).

Вот скажи, если бы тебе пришлось профессионально заняться фотографией, ты бы использовал для телефон со встроенным фотоаппаратом, или отдельный профессиональный фотоаппарат? Есть большое количество классов программ, а именно: программы, ориентированные на конечного пользователя (текстовые редакторы, например), всевозможные АСУ (бухгалтерские программы, документооборот и пр.), компьютерные игры (реальные, а не "академические") в которых будет доминировать именно итеративная составляющая. Дак может быть стоит все-таки использовать для таких задач языки, которые ИЗНАЧАЛЬНО приспособлены для программирования в итеративном стиле, а не "костыли", предоставляемые функциональными языками (это как телефон со встроенным фотоаппаратом ). Читая эту, и некоторые другие ветки, у меня сложилось впечатление, что вы все утверждаете обратное!
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[12]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 05.10.04 06:55
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>В итоге, императивное программирование предоставляет программисту возможность формулировать эти представления вручную. Функциональное программирование больше сосредотачивается на результате, чем на процессе. Это фактически попытка передать больше обязанностей по выполнению той же задачи компилятору.

Да, но, увы, искусственного интеллекта не суествует, а потому в любом случае задачу придется "разжевать" до атомарной алгоритмической кашицы, которую часто практически "один в один" можно перевести на итеративный язык.
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[18]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 05.10.04 07:10
Оценка:
Здравствуйте, prVovik, Вы писали:

V>Не правда ли, у С очень эффективная работа с массивами!!!!!

V>

Еще бы эта программа компилировалась и ченить полезное делала...
Re[15]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 05.10.04 07:18
Оценка:
Здравствуйте, prVovik, Вы писали:

V>Из изменения массива появляется ВОЗМОЖНОСТЬ побочного эффекта. А функциональный стиль требует ГАРАНТИИ их отсутствия. Я понимаю, что в простейших случаях может сработать оптимизатор, но всеже...

Ты не понимаешь. Функциональный стиль не требует гарантии отстутствия побочных эфектов. Функциональный стиль как раз не предоставляет возможностей для возниктовения побочных эффектов.

Q>>Для того, чтобы этого добиться в чистых функциональных языках применяют разные методы, про Clean тебе ответил Gaperton, а в Haskell'e это решается с помощью монад — они позволяют упорядочить вычисления, добиться того, чтобы перед вычислением Б обязательно вычислялось А.

V>Дак это и есть итеративная программа! То есть ты подтверждаешь мои слова!
f3(x,f2(y,f1(z))) — в строгом функциональном языке, функция f1 вычислится раньше чем функция f3. И это не итеративная программа. Монады — лишь синтаксический прием, что бы не писать вложеные вызовы. Заметь, в этой программе нет состояния в определенный момент времени. Тем не менее можно точно сказать что после чего будет вычислено.
Re[19]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 05.10.04 07:22
Оценка:
Здравствуйте, Nick_, Вы писали:

N_>Еще бы эта программа компилировалась и ченить полезное делала...

Во-первых, эта программа компилируется, а во-вторых, она не менее полезна, чем та, о которой идет речь, и в-третьих, если я поставил мало смайликов и надо было специально написать слово "лопата", то извени...
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[13]: Вопрос о конкретных примерах
От: Sinclair Россия https://github.com/evilguest/
Дата: 05.10.04 07:27
Оценка: +1 :)
Здравствуйте, prVovik, Вы писали:
V>Да, но, увы, искусственного интеллекта не суествует,
Это верно
V>а потому в любом случае
Уже спорно
V>задачу придется "разжевать" до атомарной алгоритмической кашицы,
Вопрос в степени этой атомарности
V>которую часто практически "один в один" можно перевести на итеративный язык.
А это уже совсем неправда. Я сходу могу привести N+1 примеров, в которых постановка задачи перед средой исполнения очень и очень далека от императивного (кстати, итеративный!=императивный) представления. И безо всякого интеллекта среда очень неплохо справляется с этой задачей.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[16]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 05.10.04 07:32
Оценка:
Здравствуйте, Nick_, Вы писали:

N_>Ты не понимаешь. Функциональный стиль не требует гарантии отстутствия побочных эфектов. Функциональный стиль как раз не предоставляет возможностей для возниктовения побочных эффектов.

Это не так. См. ниже

Q>>>Для того, чтобы этого добиться в чистых функциональных языках применяют разные методы, про Clean тебе ответил Gaperton, а в Haskell'e это решается с помощью монад — они позволяют упорядочить вычисления, добиться того, чтобы перед вычислением Б обязательно вычислялось А.

V>>Дак это и есть итеративная программа! То есть ты подтверждаешь мои слова!
N_>f3(x,f2(y,f1(z))) — в строгом функциональном языке, функция f1 вычислится раньше чем функция f3. И это не итеративная программа. Монады — лишь синтаксический прием, что бы не писать вложеные вызовы.
Зато ТРЕБУЕТСЯ, чтобы результат вызова f( f1(), f2(), f3() ) был одинаковым вне зависимочти от порядка вызова f1() f2() f3(). Если какая-то из этих ф-ций имеет побочный эффект, то результат f( f1(), f2(), f3() ) неопределен.
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[8]: ФП: вводная статья
От: faulx  
Дата: 05.10.04 07:37
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>В приведенном виде сортировка уже может трактоваться как сортировка слиянием или даже пиповая. Хор изобрел конкретный алгоритм.


Хоар изобрел две вещи. Первая — это собственно алгоритм быстрой сортировки, формально отраженный приведенной программой на Haskell'е. Вторая — эффективная реализация этого алгоритма на императивной машине. Компилятор Haskell'а в данном случае выполняет часть работы Хоара — т. е. изобретает реализацию алгоритма на ассемблере. Разумеется, далеко не факт, что эта реализация будет столь же эффективна, как Хоаровская.

VD>Переврать Хор ничего не мог так как он был изобретателем данного алгоритма.


Повторяю — Хоар изобрел две вещи: алгоритм и его реализацию. Если будет найдена более эффективная реализация, будет ли это значит, что Хоар переврал в своей реализации? Нет? Тогда почему компилятор Haskell'а врет в своей?


VD>Алгоритм не может быть описан математически. Матемотически можно только задать принцип. А принцип скорее оностистя к лассу алгоритма. Ведь основной принцип в бустрой сортировке это рекурсивное деление списков на подсписки. Но под это определение начинают попадать и некоторые другие алгоритмы.


Почему это алгоритм нельзя задать математически? Математика — термин широкий, да и способов формализации алгоритма (точнее, вычислений) существуем тоже не один. Кстати, почему-то никто не упомянул о таком языке, как Рефал, который, сколь я знаю, основан на Марковских алгорифмах.

VD>К тому, же как я говорил у Хора за "средний" брался то ли элемент массива находящийся посередине, то ли послебний (правый). Если брать не средний элемент, то на сортированном списке алгоритм будет существнно медленнее.


Средний элемент — это не тот, который посередине, а медиана. Если браться находить медиану, то алгоритм тоже станет медленнее. Поэтому на практике берут какой попало элемент, и первый (в среднем) ничуть не хуже и не лучше второго или последнего.

VD>Это, как я понимаю, называется логическим программированием.

Ну, разве что в теории.

VD>Прологу уже много лет. Кстати, не факт, что такие простые вещи как сортировка не будет проще описать алгоритмически.

"Алгоритмически" — это синоним "императивно"?

Кстати, Пролог вряд ли решит эту задачу. Максимум, что он выведет из такого описания — это алгоритм сложности O(n!), генерирующий перестановки и выбирающий сортированную.

VD> Ну, а глваная проблема тут в том, что компилятор должен знать конкретные алгоритмы и уметь подбирать наиболее подходящий в конкретном случае, а то и уметь изобретать алгоритмы и выбирать наиболее подходящий. Ну, а это уже искуственный интелект. Да даже не искуственный, а идеальный. Ведь далеко не каждый человек знает все нужные алгоритмы и умеет правильно их выбирать. Но мечат о зеленой факсовй кномке нажатие на ктороую автоматически решает луюбую сложную проблему — это та мечта к которой нужно стремиться всему человечесту.


На самом деле, если такая кнопка будет (или будет такой компилятор), это далеко не решит всех проблем и не отменит программистов. Ведь спецификации тоже надо задавать. В качестве самопроверки: какие условия должны стоять в моей программе в секции POST?

PS. А вообще, чтобы не было недоразумений, спешу объясниться. Разумеется, некорректно сравнивать приведенную программу быстрой сортировки на Haskell'е с Хоаровской реализацией на С. Прежде всего, в них сортируются разные объекты — в Haskell'e список, а в Си — массив. Далее, некорректно сравнивать их по производительности. Разумеется, реалиазация на Си эффективней.

Потом, некорректно объявлять, что программа на Haskell'е выражает преимущества функционального подхода в целом. Дело в том, что эта программа приведена в самом начале учебника по Haskell'у, и иллюстрирует она именно преимущества этого языка, а не подхода в целом. В ней, собственно говоря, не так уж много чисто функционального. К тому же она не оптимальна — в ней делается лишний проход по списку (разделить список на два подсписка можно и за один проход), она не tail-recursive, да и операция конкатенации списков тоже накладна.

Однако это все придирки. На практике же это выглядит так: написали короткую программу, и она сразу заработала. Сортировка происходит без ошибок? Так в этом и состояла цель!
Re[17]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 05.10.04 07:45
Оценка:
Здравствуйте, prVovik, Вы писали:

N_>>f3(x,f2(y,f1(z))) — в строгом функциональном языке, функция f1 вычислится раньше чем функция f3. И это не итеративная программа. Монады — лишь синтаксический прием, что бы не писать вложеные вызовы.

V>Зато ТРЕБУЕТСЯ, чтобы результат вызова f( f1(), f2(), f3() ) был одинаковым вне зависимочти от порядка вызова f1() f2() f3(). Если какая-то из этих ф-ций имеет побочный эффект, то результат f( f1(), f2(), f3() ) неопределен.
Функциональные языки не предоставляют возможности написать функцию с побочным эффектом. Поэтому результат вызова f(f1(), f2(), f3()) будет одинаковым вне зависимости от порядка вызова. Можно даже вычислять аргументы одновременно в разных потоках.
А вот когда вызываются внешние функции, которые могут иметь побочный эффект, то им передается окружение, а они в свою очередь возвращают новое окружение, которое передается следующему вызову внешней функции. И f(f1(e),f2(e)), где f1 и f2 внешние функции написать нелзя.
Re[14]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 05.10.04 07:55
Оценка:
Здравствуйте, Sinclair, Вы писали:

V>>задачу придется "разжевать" до атомарной алгоритмической кашицы,

S>Вопрос в степени этой атомарности
Определяется атомарностью СТАНДАРТНЫХ для среды исполнения решений.

V>>которую часто практически "один в один" можно перевести на итеративный язык.

S>А это уже совсем неправда. Я сходу могу привести N+1 примеров, в которых постановка задачи перед средой исполнения очень и очень далека от императивного (кстати, итеративный!=императивный) представления. И безо всякого интеллекта среда очень неплохо справляется с этой задачей.
Речь не идет о СТАНДАРТНЫХ решениях, под которые "заточена" та или иная среда исполнения. Я говорю о языках общего назначения. Хотя, если говорить иенно о стандартных решениях, то они существенно не отличаются от библиотек. И в том, и в другом стучае алгоритм ДЕТЕРМИНИРОВАН. Разница только в удобствах.
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[18]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 05.10.04 08:07
Оценка:
Здравствуйте, Nick_, Вы писали:


Человек, ты вообще читал эту ветку? Или просто так, по последнему сообщению постишь?
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[9]: ФП: вводная статья
От: FR  
Дата: 05.10.04 08:54
Оценка:
Здравствуйте, faulx, Вы писали:


F>Кстати, Пролог вряд ли решит эту задачу. Максимум, что он выведет из такого описания — это алгоритм сложности O(n!), генерирующий перестановки и выбирающий сортированную.


qsort([], []).

qsort(X | Tail, Result) :-
   split(X, Tail, Less, Great),
   qsort(Less, L1),
   qsort(Great, L2),
   merge(L1, [X | L2], Result).
Re[10]: ФП: вводная статья
От: faulx  
Дата: 05.10.04 09:09
Оценка:
Здравствуйте, FR, Вы писали:

FR>Здравствуйте, faulx, Вы писали:



F>>Кстати, Пролог вряд ли решит эту задачу. Максимум, что он выведет из такого описания — это алгоритм сложности O(n!), генерирующий перестановки и выбирающий сортированную.


FR>
FR>qsort([], []).

FR>qsort(X | Tail, Result) :-
FR>   split(X, Tail, Less, Great),
FR>   qsort(Less, L1),
FR>   qsort(Great, L2),
FR>   merge(L1, [X | L2], Result).   
FR>


Это — слишком частное описание. Здесь мы фактически подсказываем компилятору, что делать. Нет, в данном случае я имел в виду, что после :- должно находится описание отсортированного списка. Я не настолько хорошо помню Пролог, чтобы записать это на нем, но попробую неформально:

1. Результат состоит из тех же элементов и в тех же количествах, что и исходный список.
2. Каждый элемент результата (кроме первого) больше (либо равен) предыдущего элемента.

Если ваш компилятор Пролога по этому описанию построит быструю сортировку — дайте ссылочку, где можно скачать
Re[11]: ФП: вводная статья
От: Sinclair Россия https://github.com/evilguest/
Дата: 05.10.04 10:00
Оценка: :))
Здравствуйте, faulx, Вы писали:

F>Если ваш компилятор Пролога по этому описанию построит быструю сортировку — дайте ссылочку, где можно скачать

Если у вас есть компилятор любого другого языка, который по аналогичному описанию построит любой алгоритм с асимптотикой NlogN — тоже дайте сылочку!
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[17]: Вопрос о конкретных примерах
От: Quintanar Россия  
Дата: 05.10.04 10:04
Оценка: +1 :)
Здравствуйте, prVovik, Вы писали:

V>Зато ТРЕБУЕТСЯ, чтобы результат вызова f( f1(), f2(), f3() ) был одинаковым вне зависимочти от порядка вызова f1() f2() f3(). Если какая-то из этих ф-ций имеет побочный эффект, то результат f( f1(), f2(), f3() ) неопределен.


Разделяйте строгие и ленивые (нестрогие) функциональные языки. В строгих все аргументы вычисляются до вызова самой функции, поэтому порядок вычислений определен заранее и побочные эффекты особого значения не имеют — они только способствуют появлению императивных глюков и их лучше избегать. Чего вы пытаетесь доказать никак не пойму. Если, что на функциональных языках нельзя писать программы, то нет — можно. Все компиляторы ФЯ обычно пишутся на них самих, например. Если, что понятие состояния невыразимо в ФЯ, то это тоже не так. Только там оно (причем только в ленивых языках) явно передается по цепочке вычислений — это ничего не меняет по сути. В программе на С тоже можно в каждую функцию передавать глобальное состояние и не пользоваться глобальными переменными. Говорят, оптимизаторы именно так и поступают в императивных языках — делают изменение состояния программы явным.
Re[13]: Вопрос о конкретных примерах
От: Quintanar Россия  
Дата: 05.10.04 10:06
Оценка:
Здравствуйте, prVovik, Вы писали:

V>Да, но, увы, искусственного интеллекта не суествует, а потому в любом случае задачу придется "разжевать" до атомарной алгоритмической кашицы, которую часто практически "один в один" можно перевести на итеративный язык.


Атомарность кашицы на ИЯ и ФЯ разная. Пример сортировки на haskell тому пример, хоть и одиозный. И причем тут итеративные языки — все языки итеративные.
Re[15]: Вопрос о конкретных примерах
От: Quintanar Россия  
Дата: 05.10.04 10:11
Оценка: +1
Здравствуйте, prVovik, Вы писали:


V>Из изменения массива появляется ВОЗМОЖНОСТЬ побочного эффекта. А функциональный стиль требует ГАРАНТИИ их отсутствия. Я понимаю, что в простейших случаях может сработать оптимизатор, но всеже...


Ничего он не требует, особенно в строгих языках. В ленивых просто физически невозможно написать программу со сторонним эффектом (исключая ввод-вывод).

V>Дак это и есть итеративная программа! То есть ты подтверждаешь мои слова!


И что? Итеративность или цикл — основа программирования. Я сомневаюсь, что есть языки общего назначения, которые обходятся без нее.

V>Опять таки, я с тобой абсолютно согласен, действительно, часть программы можно написать в функциональном стиле, но от императивного не избавиться. Об этом я писал еще в том посте, за который вы мне понаставили минусов (я, кстати, так и не погял: с чем именно вы не согласны? ).

V>Вот скажи, если бы тебе пришлось профессионально заняться фотографией, ты бы использовал для телефон со встроенным фотоаппаратом, или отдельный профессиональный фотоаппарат? Есть большое количество классов программ, а именно: программы, ориентированные на конечного пользователя (текстовые редакторы, например), всевозможные АСУ (бухгалтерские программы, документооборот и пр.), компьютерные игры (реальные, а не "академические") в которых будет доминировать именно итеративная составляющая. Дак может быть стоит все-таки использовать для таких задач языки, которые ИЗНАЧАЛЬНО приспособлены для программирования в итеративном стиле, а не "костыли", предоставляемые функциональными языками (это как телефон со встроенным фотоаппаратом ). Читая эту, и некоторые другие ветки, у меня сложилось впечатление, что вы все утверждаете обратное!

Ты все время повторяешь слово итеративный. Причем тут это? В ФЯ есть итеративность, реализуется рекурсией.
Re[19]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 05.10.04 11:52
Оценка: 1 (1) +1
Здравствуйте, prVovik, Вы писали:

V>Человек, ты вообще читал эту ветку?


Да, читал. И твой бред мне не понятен. Особенно филосовствования про предприятие.
Re[16]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 05.10.04 12:58
Оценка:
Здравствуйте, FR, Вы писали:

FR>пока вы меряли (на эротосфене) только скорость работы озу


Логично. А ведь тесты валяются на сайте уже сто лет. Для С++, Шарпа, Явы и т.п. они уже сделны.

Берем рассчет Пи (чисто вычислительный):
        public static string pi(int digits)
        {
            if (digits > 54900)
                throw new System.Exception("n must be <= 54900");

            RStringBuilder pi = new RStringBuilder(digits);
            string[] zero = { "0", "00", "000" };
            int d = 0, e, b, g, r;
            int c = (digits / 4 + 1) * 14;
            int[] a = new int[c];
            int f = 10000;

            for (int i = 0; i < a.Length; i++)
                a[i] = 20000000;

            while ((b = c -= 14) > 0)
            {
                d = e = d % f;

                while (--b > 0)
                {
                    d = d * b + a[b];
                    g = (b << 1) - 1;
                    a[b] = (d % g) * f;
                    d /= g;
                }

                r = e + d / f;

                if (r < 1000)
                    pi.Append(zero[r > 99 ? 0 : r > 9 ? 1 : 2]);
                pi.Append(r.ToString());
            }
            return pi.ToString();
        }


Берем ту же быструю сортировку (работа со списками/массивами):
public  static void QuickSortInt(int[] item, int left, int right)
{
    int i = left;
    int j = right;
    int center = item[(left + right) / 2];

    while (i <= j)
    {
        while (item[i] < center)
            i++;
        while (item[j] > center)
            j--;

        if (i <= j)
        {
            int x = item[i];
            item[i] = item[j];
            item[j] = x;
            i++;
            j--;
        }
    }

    if (left < j)
        QuickSortInt(item, left, j);
    if (right > i)
        QuickSortInt(item, i, right);
}


Берем StrangeAttractr (тоже рассчетный но с плавающей точкой):
private void StrangeAttractr(long iInitVal)
{
    _timer.Start();

    // Опорные точки.
    double x1 = -1, y1 = -1, z1 = 0;
    double x2 = -1, y2 = 1,  z2 = 0;
    double x3 = 1,  y3 = -1, z3 = 0;
    double x4 = 1,  y4 = 1,  z4 = 0;

    // Промежуточные переменные
    double px1 = 0, py1 = 0, pz1 = 0;
    double px2 = 0, py2 = 0, pz2 = 0;
    double px3 = 0, py3 = 0, pz3 = 0;
    double px4 = 0, py4 = 0, pz4 = 0;

    double ansx = 0;
    double ansy = 0;
    double ansz = 0;

    long iOptnum = iInitVal; //количество точек, которыми мы приближаем нашу кривую
    double t = 0;
    double dt = (double)1 / (double)iOptnum; // инкремент параметра t на каждой итерации
    double n0 = 0, n1 = 0, n2 = 0, n3 = 0;   // Коэффиц. сплайна

    for (long i = 0; i < iOptnum; i++)
    {

        n0 = (-t * ((1 - t) * (1 - t))) / 2;
        n1 = (2 - 5 * t * t + 3 * t * t * t) / 2;
        n2 = (t / 2) * (1 + 4 * t - 3 * t * t);
        n3 = -((t * t) / 2) * (1 - t);


        px1 = x1 * n0;
        py1 = y1 * n0;
        pz1 = z1 * n0;

        px2 = x2 * n1;
        py2 = y2 * n1;
        pz2 = z2 * n1;


        px3 = x3 * n2;
        py3 = y3 * n2;
        pz3 = z3 * n2;

        px4 = x4 * n3;
        py4 = y4 * n3;
        pz4 = z4 * n3;

        ansx = px1 + px2 + px3 + px4;
        ansy = py1 + py2 + py3 + py4;
        ansz = pz1 + pz2 + pz3 + pz4;
        t += dt;
    }

    Log(_timer.Finish());

    MessageBox.Show(string.Format(
        "Result is x:{0}, y:{1}, z:{2}", ansx, ansy, ansz));
}


Подставляем те же входные данные что в тесте и мереем...
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 05.10.04 12:58
Оценка:
Здравствуйте, FR, Вы писали:

FR>Да всем, вам не кажется что ваши результаты имеют очень малое отношение к реальной скорости кода созданного разными компиляторами и только показывают что они способны создавать программы которые успевают просчитать элемент массива быстрее чем идет обращение к памяти(не лезущей в кеш), для получения реальных результатов быстродействия надо мерять на малых массивах.


А на малых многие компиляторы начинают "мухлевать" выкидывая рассчеты результаты которых не нужны или кэшируя те что повторяются.

Тут нужно делать тесты результаты которых можно легко проверить. А для этого они должны быть осмысленными. Я тут рядом привел тесты из шустриков. Как раз те что осмысленны и подлежат проверке. Реализуйте их на любимых языках и сравним.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[15]: ФП: вводная статья
От: Nick_ Россия  
Дата: 05.10.04 13:30
Оценка: :))
Здравствуйте, VladD2, Вы писали:

VD>А на малых многие компиляторы начинают "мухлевать" выкидывая рассчеты результаты которых не нужны или кэшируя те что повторяются.


И что в это плохого?
Re[5]: ФП: F#
От: VladD2 Российская Империя www.nemerle.org
Дата: 05.10.04 13:56
Оценка:
Здравствуйте, gloomy rocker, Вы писали:

GR>Честно говоря у меня дальше беглого взгляда на примеры, идущие в комплекте с F#, дело не пошло.

GR>Так что вводную статью я тоже не против почитать.

Так как F# — это клон ОКамла. Так что можно просто включить особенности F# в статью по ОКамлу.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 05.10.04 13:56
Оценка: +1
Здравствуйте, Quintanar, Вы писали:

Q>Странный и бездоказательный вывод. Функциональное программирование исчезает только при вводе-выводе, поскольку

Q>внешний мир невозможно проконтролировать ну и что?

А ГУИ и взаимодействие сервера с внешними клиентами можно назвать вводом/выводом? Если да, то порой 99% задачи будет состоять из такого взаимодействия. А стало быть мысль о иртеграции функциональных идей в ИЯ очень даже не лишена смысла.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[19]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 05.10.04 13:56
Оценка: :)
Здравствуйте, Nick_, Вы писали:

N_>Еще бы эта программа компилировалась и ченить полезное делала...


Скомпилировать то ее может и можно. Но вот занять два гига в стэке и найти минимальное значение в пусоре заполняющем эти два гига будет не просто. Ну, и 0 секунд она может работать только если не запустится.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[18]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 05.10.04 13:56
Оценка:
Здравствуйте, Nick_, Вы писали:

N_>Пора бы уже согласиться, что в текущем стандарте С++ шаблоны это не более чем продвинутые макросы с возможностью их рекурсивного определения и проверкой на типы.


"Макросы с проверкой на типы" — это само по себе круче. Шаблоны можно навзать минтаксически управляемыми макросами. Реально они парсятся в АСТ и для них делаются некоторые проверки.

А вот дженерики из второго шарпа уже компилируются полностью и проверяются тоже полностью. Хотя имеют очень похожую на С++ семантику. Правда у них в параметрах вообще могутбыть только типы. А конструции подобные выше описанной вообще недопустимы.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 05.10.04 13:56
Оценка:
Здравствуйте, Nick_, Вы писали:

N_>Синтаксический анализ невозможно сделать до лукапа, а лукап до инстанциации.


Синтаксический как раз легко. Ты говоришь о разрешение имен.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 05.10.04 13:56
Оценка:
Здравствуйте, INTP_mihoshi, Вы писали:

INT>Ок, в C# есть почти строгая типизация


О том что в Шарпе есть строгая типизация написано даже в его стандарте. Просто ты путаешь динамическую типизацию и строгую.

В шарпе возможно отложить проверку типов до рантайма. Правда с большими ограничениями. Так во время выполнения допустимы только upcast.

И вообще, ты уже дцатый раз повторяещь эту не ерунду не смотря на то что тебе уже много раз указывали на это.

Вот выдержка из стандарта на второй шарп:

• C# is intended to be a simple, modern, general-purpose, object-oriented programming language.
• The language, and implementations thereof, should provide support for software engineering principles
such as strong type checking, array bounds checking, detection of attempts to use uninitialized variables,
and automatic garbage collection. Software robustness, durability, and programmer productivity are
important.
• The language is intended for use in developing software components suitable for deployment in
distributed environments.
• Source code portability is very important, as is programmer portability, especially for those
programmers already familiar with C and C++.
• Support for internationalization is very important.
• C# is intended to be suitable for writing applications for both hosted and embedded systems, ranging
from the very large that use sophisticated operating systems, down to the very small having dedicated
functions.
• Although C# applications are intended to be economical with regards to memory and processing power
requirements, the language was not intended to compete directly on performance and size with C or
assembly language.

... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[20]: Вопрос о конкретных примерах
От: Sinclair Россия https://github.com/evilguest/
Дата: 05.10.04 14:41
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Скомпилировать то ее может и можно. Но вот занять два гига в стэке и найти минимальное значение в пусоре заполняющем эти два гига будет не просто. Ну, и 0 секунд она может работать только если не запустится.

Да он имел в виду, что компилер вычислит отсутствие побочных эффектов и выкинет вызов FindMin, каков бы ни был там алгоритм. Ну и ессно получим время ===0.
З.Ы. Была у меня в жизни такая история:
Встретился я как-то по рабочим вопросам с одним 3d-маньяком. Юноша еще в раннем детстве расковырял дизассемблером все думы и десенты, какие в руки попали. Наизусть помнил тайминги на интеловских и амдшных процах, длины конвейеров и прочую муть, простым смертным малоинтересную. Сейчас всяк умеющий add EAX, 1 написать себя уже крутым ассемблерщиком мнит. А тот парень по-настоящему фишку рубил, запросто мог сказать при какой разрядности фиксед-поинт будет все еще быстрее флоата, и как что от чего зависит.
В общем, встала у нас задача код для VC6.0 написать. Мы, по причине некомпетентности своей, к этому гуру на поклон пошли. Дело было коммерческое, потому он поплевался, но VS поставил. Помню, как он при мне ругал всячески ихний компилер за плохие таланты к оптимизации. Был там у него примерчик с шибко сложным набором целочисленных операций. Но мы ему показали, где в опциях проекта оптимизацию врубить. Ну, собсно там от всего мэйна только один вызов и остался. Чисто пуш 0, пуш указатель на строку "%d", и call _printf. Так что уже в те далекие времена компилер тупыми тестами задурить трудно было
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[15]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 05.10.04 15:00
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Nick_, Вы писали:


N_>>Синтаксический анализ невозможно сделать до лукапа, а лукап до инстанциации.


VD>Синтаксический как раз легко. Ты говоришь о разрешение имен.


В том примере, который я приводил синтаксический анализ существенно зависит от того, что такое T::x. Его нельзя провести, если не сделать предположение о том, что T::x — не тип. Но если вдруг окажется, что T::x — это тип — придется проводить синтаксический анализ заново.
Легко провести лексический анализ, что компиляторы и делают. С каждым шаблоном ассоциируется цепочка лексем. А синтаксический анализ проводится при инстанциации.

Но это не суть. Я все это к тому, что шаблоны в С++ недалеко ушли от макросов.
Re[20]: Вопрос о конкретных примерах
От: WolfHound  
Дата: 05.10.04 15:52
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Скомпилировать то ее может и можно. Но вот занять два гига в стэке и найти минимальное значение в пусоре заполняющем эти два гига будет не просто. Ну, и 0 секунд она может работать только если не запустится.

Нет тут все на много проще... компилятор просто выкидывает вызов функции которая ни чего не возвращает и не содержит побочных эффектов...
... << RSDN@Home 1.1.4 rev. 185 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[20]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 05.10.04 15:55
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Скомпилировать то ее может и можно. Но вот занять два гига в стэке и найти минимальное значение в пусоре заполняющем эти два гига будет не просто. Ну, и 0 секунд она может работать только если не запустится.

Не поверишь, но это действительно так!
Можешь сам проверить, только не забудь оптимизацию включить
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[20]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 05.10.04 15:55
Оценка: :)
Здравствуйте, Nick_, Вы писали:

N_>Здравствуйте, prVovik, Вы писали:


V>>Человек, ты вообще читал эту ветку?


N_>Да, читал. И твой бред мне не понятен. Особенно филосовствования про предприятие.



Звонок в пейджинговую службу:
-- Девушка, до меня не доходят сообщения!
-- Попробуйте прочитать их еще раз.
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[18]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 05.10.04 15:55
Оценка:
Здравствуйте, Quintanar, Вы писали:

Q>Разделяйте строгие и ленивые (нестрогие) функциональные языки. В строгих все аргументы вычисляются до вызова самой функции, поэтому порядок вычислений определен заранее и побочные эффекты особого значения не имеют — они только способствуют появлению императивных глюков и их лучше избегать.

Да, возможно...

Q>Чего вы пытаетесь доказать никак не пойму. Если, что на функциональных языках нельзя писать программы, то нет — можно. Все компиляторы ФЯ обычно пишутся на них самих, например. Если, что понятие состояния невыразимо в ФЯ, то это тоже не так. Только там оно (причем только в ленивых языках) явно передается по цепочке вычислений — это ничего не меняет по сути. В программе на С тоже можно в каждую функцию передавать глобальное состояние и не пользоваться глобальными переменными. Говорят, оптимизаторы именно так и поступают в императивных языках — делают изменение состояния программы явным.

Я хочу сказать, что по моему мнению максимальный эффект от применения функционального подхода проявляется при использовании специализированных функциональных языков. Именно тут может проявиться в полную силу декларативные "бонусы" функционального подхода, так как в данном случае возможно автоматическое преобразование функциональной программы в соответствующую эффективную императивную (именно в таком виде она будет пригодна к исполнению). Не надо пытаться за уши притянуть ФЯ к задачам, которые не ложаться в философию функциональных языков. Короче говоря, Богу — богово, а кесарю — кесарево...
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[18]: Вопрос о конкретных примерах
От: Gaperton http://gaperton.livejournal.com
Дата: 05.10.04 16:16
Оценка:
Здравствуйте, prVovik, Вы писали:

V>Здравствуйте, Gaperton, Вы писали:


G>>Мы вообще-то компиляторы сравнивали, на одном алгоритме. Точнее, эффективность работы с массивами в чистом ФЯ сравнительно с С++. А не устанавливали рекорды скорости. Поэтому и не слышим.

V>Ну тогда в качестве задачки предлагаю искать минимальный элемент в массиве. Для простоты элементы массива можно ниоткуда не вводить, а результат никуда не выводить.

Было мнение, что в ФЯ принципиально дорогая модификация массива. Это проверили на простом алгоритме. Все. Я не понимаю, к чему ваши инсенуации.
Re[19]: Вопрос о конкретных примерах
От: Gaperton http://gaperton.livejournal.com
Дата: 05.10.04 16:31
Оценка:
Здравствуйте, prVovik, Вы писали:

V>Здравствуйте, Nick_, Вы писали:


V>Человек, ты вообще читал эту ветку? Или просто так, по последнему сообщению постишь?

Человек указывает на грубую ошибку в твоих рассуждениях. Твои опасения по поводу того, что в чисто функциональном вычислительно полном языке может вылезти побочный эффект (sic!), а иначе на нем принципиально невозможно написать эффективную программу ( ) мягко говоря не имеют под собой оснований. Причем, чем подробнее ты начинаешь объяснять свою точку зрения, тем веселее становится.
Re[19]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 05.10.04 17:43
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Было мнение, что в ФЯ принципиально дорогая модификация массива. Это проверили на простом алгоритме. Все. Я не понимаю, к чему ваши инсенуации.

А я вон привел тест, доказывающий, что в С++ проход по двухгигабайтному массиву вообще бесплатный. Но что это доказывает? Ничего !
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[20]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 05.10.04 17:43
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Человек указывает на грубую ошибку в твоих рассуждениях. Твои опасения по поводу того, что в чисто функциональном вычислительно полном языке может вылезти побочный эффект (sic!), а иначе на нем принципиально невозможно написать эффективную программу ( ) мягко говоря не имеют под собой оснований.

У тебя есть аргументы по существу? Ты, главное, не стесняйся, говори. И, желательно, без снисходительного тона.

G>Причем, чем подробнее ты начинаешь объяснять свою точку зрения, тем веселее становится.

Мощный аргумент! Внушает!
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[20]: Вопрос о конкретных примерах
От: Quintanar Россия  
Дата: 05.10.04 19:01
Оценка:
Здравствуйте, prVovik, Вы писали:

V>Здравствуйте, Gaperton, Вы писали:


G>>Было мнение, что в ФЯ принципиально дорогая модификация массива. Это проверили на простом алгоритме. Все. Я не понимаю, к чему ваши инсенуации.

V>А я вон привел тест, доказывающий, что в С++ проход по двухгигабайтному массиву вообще бесплатный. Но что это доказывает? Ничего !

Вот именно, что ничего. Так зачем, спрашивается, надо было тратить чужое время?
Re[21]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 05.10.04 19:22
Оценка: :)
Здравствуйте, Quintanar, Вы писали:

Q>Вот именно, что ничего. Так зачем, спрашивается, надо было тратить чужое время?

Этот тест не на много менее информативен, чем тот тест на Clean. И в том и в этом случае компилятору была предоставлена возможность жульничать, и как следствие в обоих случаях был получен фантастические результаты. Так же, как мой тест не говорит о бесплатности работы С с массивами, точно так, как тест с решетом не говорит об эффективности Clean. Я повторяю, и в том и в другом случае компиляторы "жульничали". Для качественных тестов эти задачки не подходят.
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[22]: Вопрос о конкретных примерах
От: Quintanar Россия  
Дата: 05.10.04 19:37
Оценка:
Здравствуйте, prVovik, Вы писали:

V>Здравствуйте, Quintanar, Вы писали:


Q>>Вот именно, что ничего. Так зачем, спрашивается, надо было тратить чужое время?

V>Этот тест не на много менее информативен, чем тот тест на Clean. И в том и в этом случае компилятору была предоставлена возможность жульничать, и как следствие в обоих случаях был получен фантастические результаты. Так же, как мой тест не говорит о бесплатности работы С с массивами, точно так, как тест с решетом не говорит об эффективности Clean. Я повторяю, и в том и в другом случае компиляторы "жульничали". Для качественных тестов эти задачки не подходят.

А в чем заключалось жульничество?
Re[16]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 05.10.04 19:43
Оценка:
Здравствуйте, Nick_, Вы писали:

VD>>А на малых многие компиляторы начинают "мухлевать" выкидывая рассчеты результаты которых не нужны или кэшируя те что повторяются.


N_>И что в это плохого?


Так... фигня. Хочешь измерить одно, а измеряешь общее понимание ненужности твоих телодвижений.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[21]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 05.10.04 19:43
Оценка: :)
Здравствуйте, prVovik, Вы писали:

V>Не поверишь, но это действительно так!


Не верю...
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[22]: Вопрос о конкретных примерах
От: Gaperton http://gaperton.livejournal.com
Дата: 05.10.04 20:09
Оценка:
Здравствуйте, prVovik, Вы писали:

V>Я повторяю, и в том и в другом случае компиляторы "жульничали".

Ну, после того, как ты повторил, твой аргумент конечно стал вдвое более весомым. Но все еще недостаточно. Я думаю, тебе надо повторить его еще раз 50, чтобы он набрал побольше веса
Re[21]: Вопрос о конкретных примерах
От: Gaperton http://gaperton.livejournal.com
Дата: 05.10.04 20:26
Оценка:
Здравствуйте, prVovik, Вы писали:

V>Здравствуйте, Gaperton, Вы писали:


G>>Человек указывает на грубую ошибку в твоих рассуждениях. Твои опасения по поводу того, что в чисто функциональном вычислительно полном языке может вылезти побочный эффект (sic!), а иначе на нем принципиально невозможно написать эффективную программу ( ) мягко говоря не имеют под собой оснований.

V>У тебя есть аргументы по существу? Ты, главное, не стесняйся, говори.
Это не стеснение, а нежелание силой, преодолевая твое сопротивление, вколачивать в твою голову знания. В конце концов, мне за это не платят, а желания у тебя нет. Но на всякий случай:
http://homepages.inf.ed.ac.uk/wadler/topics/monads.html
http://citeseer.ist.psu.edu/barendsen93conventional.html

V>И, желательно, без снисходительного тона.

Это уж извини. Сам напросился.

G>>Причем, чем подробнее ты начинаешь объяснять свою точку зрения, тем веселее становится.

V>Мощный аргумент! Внушает!
Ну что ты. Это не аргумент, а впечатления от твоих постов.
Re[23]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 05.10.04 20:27
Оценка: :)
Здравствуйте, Gaperton, Вы писали:

G>Ну, после того, как ты повторил, твой аргумент конечно стал вдвое более весомым. Но все еще недостаточно. Я думаю, тебе надо повторить его еще раз 50, чтобы он набрал побольше веса

Слушай, у тебя удивительный дар общения!
Ты этому где-то учился, или природа наградила?

... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[23]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 05.10.04 21:59
Оценка:
Здравствуйте, Quintanar, Вы писали:

Q>А в чем заключалось жульничество?

В том, что компиляторы воспользовались частным случаем.

Что было бы с той программой на Clean, если бы на преобразуемый массив существовало несколько ссылок? Очевидно, загнулась бы...
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[24]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 06.10.04 03:26
Оценка:
Здравствуйте, prVovik, Вы писали:

V>Что было бы с той программой на Clean, если бы на преобразуемый массив существовало несколько ссылок? Очевидно, загнулась бы...


Каких ссылок? Зачем?
Re[24]: Вопрос о конкретных примерах
От: FR  
Дата: 06.10.04 06:37
Оценка:
Здравствуйте, prVovik, Вы писали:

V>Здравствуйте, Quintanar, Вы писали:


Q>>А в чем заключалось жульничество?

V>В том, что компиляторы воспользовались частным случаем.

В тесте с решетом я не увидел никакого жульничества, другое дело что как тест производительности он никуда ни годится.
А вообще пусть компиляторы "жульничают" при условии что выдают корректные результаты.
Re[25]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 06.10.04 07:20
Оценка:
Здравствуйте, FR, Вы писали:

FR>В тесте с решетом я не увидел никакого жульничества, другое дело что как тест производительности он никуда ни годится.

FR>А вообще пусть компиляторы "жульничают" при условии что выдают корректные результаты.
Конечно, это не плохо, это очень даже хорошо. Это говорит о качестве компиляторов, о том, что они могут оптимизировать. НО! Не стоит на основании частного случая делать общих выводов!

То, что компилятор Clean научен оптимизировать именно массив и только тогда, когда на него существует единственная ссылка — это, конечно, хорошо, но проблемы, которую я описал еще в посте Re[10]: Вопрос о конкретных примерах
Автор: prVovik
Дата: 02.10.04
в не решает. То есть проблемы изменения объекта, когда на него существует множество ссылок.
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[25]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 06.10.04 07:20
Оценка:
Здравствуйте, Nick_, Вы писали:

N_>Каких ссылок? Зачем?

Ты уж все-таки изволь, прочти с чего началось данное обсуждение: Re[10]: Вопрос о конкретных примерах
Автор: prVovik
Дата: 02.10.04
. То есть задача ИЗНАЧАЛЬНО была поставлена, как задача изменения объекта, который существует не обособленно, а в рамках некоторого окружения и на который из этого окружения имеется МНОЖЕСТВО ссылок! Заметь, слова "массив" там даже никаким боком нет! Да, конечно, в решете достаточно одной ссылки на массив, но объясни мне, зачем тогда было приводить решето, как пример решения ВЫШЕОЗНАЧЕННОЙ задачи???
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[22]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 06.10.04 07:37
Оценка: :)
Здравствуйте, Gaperton, Вы писали:

Наша беседа:

Gaperton:
-- Гы-гы. Ацтой! Гы-гы. Ацтой! Гы-гы. Ацтой!
Я:
-- С чем именно ты не согласем? Приведи аргументы!
Gaperton:
-- А мне за аргументы деньги не платят.


Нормальное такое конструктивное обсуждение
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[26]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 06.10.04 07:48
Оценка:
Здравствуйте, prVovik, Вы писали:

Ну не может на объект в функциональной программе быть множество таких ссылок о которых компилятор не знает. Функциональные языки не компилируются в отрыве от контекста. Компилятор всегда знает из каких еще мест программы данный обьект пытаются прочитать или записать.

Кроме того, если вы в любой программе будете делать объект на который есть куча ссылок, то вашу программу практически невозможно будет распараллелить. Ведь не факт, что производительность на n-way системе увеличится в n раз, если вы на каждый обьект на который может быть множество ссылок будете ставить семафор или мьютекс. Функциональный подход предоставляет больше возможностей по оптимизации и распараллеливанию кода.

Вы мыслите в терминах фон-неймановской машины с памятью. Никто не спорит, что компьютеры так работают. И так мыслить было актуально, потому что компиляторы переводили программу на Си или фортране практически один в один в машинный код. Но в наше время, когда космические корабли бороздят просторы космоса...

V>Ты уж все-таки изволь, прочти с чего началось данное обсуждение: Re[10]: Вопрос о конкретных примерах
Автор: prVovik
Дата: 02.10.04
. То есть задача ИЗНАЧАЛЬНО была поставлена, как задача изменения объекта, который существует не обособленно, а в рамках некоторого окружения и на который из этого окружения имеется МНОЖЕСТВО ссылок! Заметь, слова "массив" там даже никаким боком нет! Да, конечно, в решете достаточно одной ссылки на массив, но объясни мне, зачем тогда было приводить решето, как пример решения ВЫШЕОЗНАЧЕННОЙ задачи???
Re[26]: Вопрос о конкретных примерах
От: Quintanar Россия  
Дата: 06.10.04 09:28
Оценка: +1
Здравствуйте, prVovik, Вы писали:

V>Ты уж все-таки изволь, прочти с чего началось данное обсуждение: Re[10]: Вопрос о конкретных примерах
Автор: prVovik
Дата: 02.10.04
. То есть задача ИЗНАЧАЛЬНО была поставлена, как задача изменения объекта, который существует не обособленно, а в рамках некоторого окружения и на который из этого окружения имеется МНОЖЕСТВО ссылок! Заметь, слова "массив" там даже никаким боком нет! Да, конечно, в решете достаточно одной ссылки на массив, но объясни мне, зачем тогда было приводить решето, как пример решения ВЫШЕОЗНАЧЕННОЙ задачи???


Твоя задача тоже высосана из пальца, поскольку сводится к требованию делать что-то через задницу, только потому что это заведомо будет тормозить на ФЯ. Приведи пример конкретной задачи, где бы нужно было множество ссылок на объект, и я тебе напишу как решить эту проблему без множества ссылок или признаю, что без тормозов ее решить нельзя. Кроме того, еще раз повторяю, что все эти проблемы со ссылками присущи только ленивым языкам, в строгих их нет.
Re[6]: ФП: F#
От: Alexey Chen Чили  
Дата: 06.10.04 19:15
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Так как F# — это клон ОКамла. Так что можно просто включить особенности F# в статью по ОКамлу.

Включите. Это будет здорово! Хотя, со временем хтелось бы развернутую статью именно по F# с точки зрения его полжения в семействе # и как этим успешно пользоваться. Как мне например вынести из приложения на C# или C++ реально функциональный код и написать его на F#-е. Это было бы очень интересно.
Re[21]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.10.04 19:57
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Да он имел в виду, что компилер вычислит отсутствие побочных эффектов и выкинет вызов FindMin, каков бы ни был там алгоритм. Ну и ессно получим время ===0.


Код вообще некорректен и рабоать вряд ли сможет. Ну, и столь вольные допущения компиляторы пока что не делают.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[21]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.10.04 19:57
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Нет тут все на много проще... компилятор просто выкидывает вызов функции которая ни чего не возвращает и не содержит побочных эффектов...


Ну, это возможно. Но если не выкинит, то 0 сек. обеспечено в следствии вылета.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[16]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.10.04 19:57
Оценка:
Здравствуйте, Nick_, Вы писали:

N_>Здравствуйте, VladD2, Вы писали:


VD>>Здравствуйте, Nick_, Вы писали:


N_>>>Синтаксический анализ невозможно сделать до лукапа, а лукап до инстанциации.


VD>>Синтаксический как раз легко. Ты говоришь о разрешение имен.


N_>В том примере, который я приводил синтаксический анализ существенно зависит от того, что такое T::x.


Ёлы-плаы. Ну, загляни в гугль. Погляди чем синтаксический анализ отличается от семантического. Ну, и что такое вообще синтаксический анализ.

N_> Его нельзя провести, если не сделать предположение о том, что T::x — не тип.


Да пофигу для синтаксического разбора чем будет эта конструкция. Тип, не тип — это уже семантика.

Ну, а макросы они вообще без синтаксического разбора работают. Это просто текстовые операции.

N_>Легко провести лексический анализ, что компиляторы и делают. С каждым шаблоном ассоциируется цепочка лексем. А синтаксический анализ проводится при инстанциации.


Нда. Гугль тебе в руки. Ты все перепутал.

N_>Но это не суть. Я все это к тому, что шаблоны в С++ недалеко ушли от макросов.


Да далеко. Но не доконца. Проблем хватает. Но тут оно как. Очень многие недостатки являются продолжениями достоинств. Если гибко, то обязательно будет небезопасно. И наоборот. Вот в дженериках проблем с поздними проврками нет. Но и гибкость ниже.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: ФП: F#
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.10.04 20:46
Оценка:
Здравствуйте, Alexey Chen, Вы писали:

AC>Включите. Это будет здорово! Хотя, со временем хтелось бы развернутую статью именно по F# с точки зрения его полжения в семействе # и как этим успешно пользоваться.


Дык не зная что такое ОКамл будет практически невозможно понять, что такое F#.

AC>Как мне например вынести из приложения на C# или C++ реально функциональный код и написать его на F#-е. Это было бы очень интересно.


Ну, это вроде как довольно просто. F# порождает стандартные дотнтные сборки. Так что достаточно оформить нужные входные точки (на F#) и использовать эти функции из Шарпа подключив сборку созданную на F# к Шарповскому прокту.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.10.04 20:46
Оценка:
Здравствуйте, Quintanar, Вы писали:

Q>У меня, например, есть пара парсеров на OCaml. Один интерпретор примитивного языка, а другой конвертатор из bnf в sml yacc. Могу их выложить, хотя я ими не очень доволен, писал их когда еще слабо разбирался в функциональном стиле.


Выкладывай. Хуже не будет. А пример есть пример.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[25]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.10.04 21:20
Оценка:
Здравствуйте, FR, Вы писали:

FR>А вообще пусть компиляторы "жульничают" при условии что выдают корректные результаты.


Для этого результаты должны быть осмысленными и предсказауемыми.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[22]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 06.10.04 21:33
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Код вообще некорректен и рабоать вряд ли сможет.

Хм, чем это он некорректен? Полностью соответствует стандарту.

VD>Ну, и столь вольные допущения компиляторы пока что не делают.

Для самых любознательных привожу ассемблерный вид, к которому преобразовал эту программу VC7.1

00401000  xor         eax,eax 
00401002  ret


Как думаешь, сколько времени это будет выполняться?

А вот еще пример из той же оперы:
int CalcSuperNumber(int n)
{
    for( int i=0, k=0; i < 500000000; ++i ) // ПЯТЬСОТ миллионов!!!!!!!
    {
        k += n;
    }
    return k;
}
int main()
{
    printf( "%i", CalcSuperNumber(10) );
    return 0;
}


Тут программа уже посложнее, имеется побочный эффект — вывод результата на консоль. Сколько же она будет работать? Минуту, две? .
А нисколько!
Потому как компилятор нынче пошел на редкость умен и сообразителен. Вот что получим на выходе:

00401070  push        2A05F200h         ; А вот это и есть готовый результат :)
00401075  push        offset KERNEL32_NULL_THUNK_DATA+2Ch (4060FCh) 
0040107A  call        printf (4010CDh) 
0040107F  add         esp,8 
00401082  xor         eax,eax


Какая досада, комнилятор сразу подставил готорый результат еще во время компиляции
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[23]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 07.10.04 07:35
Оценка: +1
Здравствуйте, prVovik, Вы писали:

V>Какая досада, комнилятор сразу подставил готорый результат еще во время компиляции


Знал бы ты какой ценой это дается разработчикам компиляторов.
Сначала программа переводится в SSA форму, над которой потом делаются оптимизации.
Так вот сюрпиз! SSA форма — это функциональная программа
http://citeseer.ist.psu.edu/appel98ssa.html

В функциональных языках сделать такие оптимизации на порядок проще, потому что компилятору легче вытянуть смысл из того, что написал программист.
Re[17]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 07.10.04 07:44
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Ёлы-плаы. Ну, загляни в гугль. Погляди чем синтаксический анализ отличается от семантического. Ну, и что такое вообще синтаксический анализ.


N_>> Его нельзя провести, если не сделать предположение о том, что T::x — не тип.


VD>Да пофигу для синтаксического разбора чем будет эта конструкция. Тип, не тип — это уже семантика.


Почитай на досуге грамматику С++ или С.

Для синтаксического анализа как раз важно, чем является символ — идентификатором или типом.
например:
x y;
Если x — не тип, то возникнет синтаксическая ошибка. До семантического анализа даже не дойдет.
Еще один пример:
если в выражении после `(' стоит тип, то это c-style cast, и по синтаксису, после `)' должно быть выражение.
а если после `(' не тип, то это просто скобки подвыражения, и после них может быть `;'
Хочешь сказать, что это семантика?
Re[24]: Вопрос о конкретных примерах
От: naje  
Дата: 07.10.04 07:45
Оценка:
Здравствуйте, Nick_, Вы писали:

N_>Здравствуйте, prVovik, Вы писали:


V>>Какая досада, комнилятор сразу подставил готорый результат еще во время компиляции


N_>Знал бы ты какой ценой это дается разработчикам компиляторов.

N_>Сначала программа переводится в SSA форму, над которой потом делаются оптимизации.
N_>Так вот сюрпиз! SSA форма — это функциональная программа
N_>http://citeseer.ist.psu.edu/appel98ssa.html

N_>В функциональных языках сделать такие оптимизации на порядок проще, потому что компилятору легче вытянуть смысл из того, что написал программист.

ты хотя раз видел этот ssa?

а вот в gcc 4 появится ещё одно промежуточное представление императивное(GIMPLE) c С подобным синтаксисом, они говорят после этого возможности оптимизации увеличатся на порядок.
Re[25]: Вопрос о конкретных примерах
От: naje  
Дата: 07.10.04 08:01
Оценка:
Здравствуйте, naje, Вы писали:

N>Здравствуйте, Nick_, Вы писали:


N_>>Здравствуйте, prVovik, Вы писали:


V>>>Какая досада, комнилятор сразу подставил готорый результат еще во время компиляции


N_>>Знал бы ты какой ценой это дается разработчикам компиляторов.

N_>>Сначала программа переводится в SSA форму, над которой потом делаются оптимизации.
N_>>Так вот сюрпиз! SSA форма — это функциональная программа
N_>>http://citeseer.ist.psu.edu/appel98ssa.html

N_>>В функциональных языках сделать такие оптимизации на порядок проще, потому что компилятору легче вытянуть смысл из того, что написал программист.

N>ты хотя раз видел этот ssa?

вот кстати rtl дамп програмки используемой в статье:

;; Function int main(int, char **)
(note 2 0 3 "" NOTE_INSN_DELETED)
(note 3 2 4 "" NOTE_INSN_DELETED)
(note 4 3 5 "" NOTE_INSN_FUNCTION_BEG)
(note 5 4 7 "" NOTE_INSN_DELETED)
(note 7 5 8 0 NOTE_INSN_BLOCK_BEG)
(note 8 7 11 "" NOTE_INSN_DELETED)
(insn 11 8 12 (set (mem/f:SI (plus:SI (reg:SI 18)
                (const_int -4 [0xfffffffc])) 0)
        (const_int 1 [0x1])) -1 (nil)
    (nil))

(note 12 11 15 "" NOTE_INSN_DELETED)
(insn 15 12 16 (set (mem/f:SI (plus:SI (reg:SI 18)
                (const_int -8 [0xfffffff8])) 0)
        (const_int 1 [0x1])) -1 (nil)
    (nil))
(note 16 15 19 "" NOTE_INSN_DELETED)
(insn 19 16 21 (set (mem/f:SI (plus:SI (reg:SI 18)
                (const_int -12 [0xfffffff4])) 0)
        (const_int 1 [0x1])) -1 (nil)
    (nil))
(note 21 19 60 "" NOTE_INSN_LOOP_BEG)
(note 60 21 22 "" NOTE_INSN_LOOP_CONT)
(code_label 22 60 23 3 "" [num uses: 0])
(note 23 22 24 "" NOTE_INSN_DELETED)
(insn 24 23 25 (set (cc0)
        (compare (mem/f:SI (plus:SI (reg:SI 18)
                    (const_int -12 [0xfffffff4])) 0)
            (const_int 99 [0x63]))) -1 (nil)
    (nil))
(jump_insn 25 24 26 (set (pc)
        (if_then_else (le (cc0)
                (const_int 0 [0x0]))
            (label_ref 28)
            (pc))) -1 (nil)
    (nil))
(jump_insn 26 25 27 (set (pc)
        (label_ref 64)) -1 (nil)
    (nil))
(barrier 27 26 28)
(code_label 28 27 29 5 "" [num uses: 0])
(note 29 28 31 "" NOTE_INSN_DELETED)
(note 31 29 32 "" NOTE_INSN_DELETED)
(insn 32 31 33 (set (cc0)
        (compare (mem/f:SI (plus:SI (reg:SI 18)
                    (const_int -8 [0xfffffff8])) 0)
            (const_int 19 [0x13]))) -1 (nil)
    (nil))
(jump_insn 33 32 35 (set (pc)
        (if_then_else (gt (cc0)
                (const_int 0 [0x0]))
            (label_ref 47)
            (pc))) 349 {bleu+1} (nil)
    (nil))
(note 35 33 37 "" NOTE_INSN_DELETED)
(note 37 35 39 "" NOTE_INSN_DELETED)
(insn 39 37 40 (set (reg:SI 22)
        (mem/f:SI (plus:SI (reg:SI 18)
                (const_int -4 [0xfffffffc])) 0)) -1 (nil)
    (nil))
(insn 40 39 42 (set (mem/f:SI (plus:SI (reg:SI 18)
                (const_int -8 [0xfffffff8])) 0)
        (reg:SI 22)) -1 (nil)
    (nil))
(note 42 40 44 "" NOTE_INSN_DELETED)
(insn 44 42 45 (set (mem/f:SI (plus:SI (reg:SI 18)
                (const_int -12 [0xfffffff4])) 0)
        (plus:SI (mem/f:SI (plus:SI (reg:SI 18)
                    (const_int -12 [0xfffffff4])) 0)
            (const_int 1 [0x1]))) -1 (nil)
    (nil))
(jump_insn 45 44 46 (set (pc)
        (label_ref 59)) -1 (nil)
    (nil))
(barrier 46 45 47)
(code_label 47 46 49 6 "" [num uses: 0])
(note 49 47 51 "" NOTE_INSN_DELETED)
(note 51 49 53 "" NOTE_INSN_DELETED)
(insn 53 51 54 (set (reg:SI 23)
        (mem/f:SI (plus:SI (reg:SI 18)
                (const_int -12 [0xfffffff4])) 0)) -1 (nil)
    (nil))
(insn 54 53 56 (set (mem/f:SI (plus:SI (reg:SI 18)
                (const_int -8 [0xfffffff8])) 0)
        (reg:SI 23)) -1 (nil)
    (nil))
(note 56 54 58 "" NOTE_INSN_DELETED)
(insn 58 56 59 (set (mem/f:SI (plus:SI (reg:SI 18)
                (const_int -12 [0xfffffff4])) 0)
        (plus:SI (mem/f:SI (plus:SI (reg:SI 18)
                    (const_int -12 [0xfffffff4])) 0)
            (const_int 2 [0x2]))) -1 (nil)
    (nil))
(code_label 59 58 61 7 "" [num uses: 0])
(jump_insn 61 59 62 (set (pc)
        (label_ref 22)) -1 (nil)
    (nil))
(barrier 62 61 63)
(note 63 62 64 "" NOTE_INSN_LOOP_END)
(code_label 64 63 66 4 "" [num uses: 0])
(note 66 64 68 "" NOTE_INSN_DELETED)
(insn 68 66 70 (set (reg:SI 25)
        (mem/f:SI (plus:SI (reg:SI 18)
                (const_int -8 [0xfffffff8])) 0)) -1 (nil)
    (nil))
(insn 70 68 71 (set (reg/i:SI 0 %eax)
        (reg:SI 25)) -1 (nil)
    (nil))
(insn 71 70 72 (use (reg/i:SI 0 %eax)) -1 (nil)
    (nil))
(jump_insn 72 71 73 (set (pc)
        (label_ref 83)) -1 (nil)
    (nil))
(barrier 73 72 74)
(note 74 73 75 0 NOTE_INSN_BLOCK_END)
(note 75 74 77 "" NOTE_INSN_DELETED)
(insn 77 75 78 (set (reg/i:SI 0 %eax)
        (const_int 0 [0x0])) -1 (nil)
    (nil))
(insn 78 77 79 (use (reg/i:SI 0 %eax)) -1 (nil)
    (nil))
(jump_insn 79 78 80 (set (pc)
        (label_ref 83)) -1 (nil)
    (nil))
(barrier 80 79 81)
(note 81 80 83 "" NOTE_INSN_FUNCTION_END)
(code_label 83 81 0 2 "" [num uses: 0])


как видно от функциональных языков остаётся только схемовский синтаксис и всё, в остальном это просто платформенно независимы асемблер, или кто-то скажет что jump_insn это функциональная конструкция?
Re[25]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 07.10.04 08:07
Оценка:
Здравствуйте, naje, Вы писали:

N_>>В функциональных языках сделать такие оптимизации на порядок проще, потому что компилятору легче вытянуть смысл из того, что написал программист.

N>ты хотя раз видел этот ssa?
Да.

N>а вот в gcc 4 появится ещё одно промежуточное представление императивное(GIMPLE) c С подобным синтаксисом, они говорят после этого возможности оптимизации увеличатся на порядок.

Просто так оптимизации в компиляторы не вставляют. Для любой оптимизации надо сначала доказать, что она не меняет семантику кода. А для этого в свою очередь нужен способ, который бы позволил сказать, что два разных алгоритма делают одно и то же. В общем случае, эта задача алгоритмически неразрешима. Но для более узких типов эквивалентности алгоритмов это можно сделать. Кроме того алгоритм должет быть как-то записан. Для некоторых форм записи провести доказательство правильности оптимизации проще чем для других. SSA — это уже де-факто стандартная форма записи алгоритмов. Большинство доказательств корректности оптимизаций делается для оптимизайций SSA формы. В большинстве современных компиляторов используется SSA форма, как внутреннее представление программы.

PS: Ну а gcc для меня не авторитет.
Re[26]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 07.10.04 08:10
Оценка:
Здравствуйте, naje, Вы писали:

N>вот кстати rtl дамп програмки используемой в статье:


N>как видно от функциональных языков остаётся только схемовский синтаксис и всё, в остальном это просто платформенно независимы асемблер, или кто-то скажет что jump_insn это функциональная конструкция?


register transfer language — это действительно, переносимый ассемблер. высокоуровневые оптимизации на этом представлении не сделаешь. И то, что в gcc используется только rtl для представления программы ему чести не делает.
Re[27]: Вопрос о конкретных примерах
От: naje  
Дата: 07.10.04 08:17
Оценка: -1
Здравствуйте, Nick_, Вы писали:

N_>Здравствуйте, naje, Вы писали:


N>>вот кстати rtl дамп програмки используемой в статье:


N>>как видно от функциональных языков остаётся только схемовский синтаксис и всё, в остальном это просто платформенно независимы асемблер, или кто-то скажет что jump_insn это функциональная конструкция?


N_>register transfer language — это действительно, переносимый ассемблер. высокоуровневые оптимизации на этом представлении не сделаешь. И то, что в gcc используется только rtl для представления программы ему чести не делает.


вобще-то rtl это какраз и есть представление ssa
я вот только не пойму, если верить той статье, то компилятор из нормальный цикл переводит в рекурсию, после чего обратно в цикл, может покажешь мне продолжение этой статьи, о том как компиляторы из рекурсий в ssa оптять делают циклы?
Re[23]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.10.04 08:28
Оценка:
Здравствуйте, prVovik, Вы писали:

VD>>Код вообще некорректен и рабоать вряд ли сможет.

V>Хм, чем это он некорректен? Полностью соответствует стандарту.

Массив не инициализирован и превышает размеры стэка.

VD>>Ну, и столь вольные допущения компиляторы пока что не делают.

V>Для самых любознательных привожу ассемблерный вид, к которому преобразовал эту программу VC7.1

V>
V>00401000  xor         eax,eax 
V>00401002  ret  
V>


Дык, ты результат верни и погляди что получится. А так он просто выбрасил с дури код и все.

V>Как думаешь, сколько времени это будет выполняться?


Думаю, что смысла в таком коде еще мешьше чем в заявлениях сделанных на его основе.

V>А вот еще пример из той же оперы:

V>
V>int CalcSuperNumber(int n)
V>{
V>    for( int i=0, k=0; i < 500000000; ++i ) // ПЯТЬСОТ миллионов!!!!!!!
V>    {
V>        k += n;
V>    }
V>    return k;
V>}
V>int main()
V>{
V>    printf( "%i", CalcSuperNumber(10) );
V>    return 0;
V>}
V>


V>Тут программа уже посложнее, имеется побочный эффект — вывод результата на консоль. Сколько же она будет работать? Минуту, две? .

V>А нисколько!
V>Потому как компилятор нынче пошел на редкость умен и сообразителен.

О! Умища палата. Вот только достаточно переменную в классик вынести или малейшие зачатки разума в алгоритм заложить и вся прыть компилятора куда-то улитучивается.

V>Какая досада, комнилятор сразу подставил готорый результат еще во время компиляции


Вот именно по этому синтетические тесты не имеют смысла. У тебя даже заведомо бессмысленный код скомпилируется. А на рельный код это ровным счетом никакого влияние не окажет.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[28]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 07.10.04 08:42
Оценка:
Здравствуйте, naje, Вы писали:

N>вобще-то rtl это какраз и есть представление ssa

Да? А как же jump'ы?

N>я вот только не пойму, если верить той статье, то компилятор из нормальный цикл переводит в рекурсию, после чего обратно в цикл, может покажешь мне продолжение этой статьи, о том как компиляторы из рекурсий в ssa оптять делают циклы?

А зачем?
Re[29]: Вопрос о конкретных примерах
От: naje  
Дата: 07.10.04 08:46
Оценка:
Здравствуйте, Nick_, Вы писали:

N_>Здравствуйте, naje, Вы писали:


N>>вобще-то rtl это какраз и есть представление ssa

N_>Да? А как же jump'ы?

ты можешь привести какое-нибудь другое представление без jump'ов?

N>>я вот только не пойму, если верить той статье, то компилятор из нормальный цикл переводит в рекурсию, после чего обратно в цикл, может покажешь мне продолжение этой статьи, о том как компиляторы из рекурсий в ssa оптять делают циклы?

N_>А зачем?

а зачем это ocalm например пытается делать?
Re[30]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 07.10.04 09:02
Оценка:
Здравствуйте, naje, Вы писали:
N>>>вобще-то rtl это какраз и есть представление ssa
N_>>Да? А как же jump'ы?

N>ты можешь привести какое-нибудь другое представление без jump'ов?

Граф.

N>>>я вот только не пойму, если верить той статье, то компилятор из нормальный цикл переводит в рекурсию, после чего обратно в цикл, может покажешь мне продолжение этой статьи, о том как компиляторы из рекурсий в ssa оптять делают циклы?

N_>>А зачем?

N>а зачем это ocalm например пытается делать?

Не знаю. Это надо спросить кого-нибудь кто знает ocaml.
Возможно имеется в виду, что рекурсия в ocaml так же эффективна как цикл в Си. Просто многие считают, что рекурсия это плохо, основываясь на своем опыте программирования в Си, где действительно каждый вызов функции приводит к работе со стеком. Поэтому и говорят, что ocaml превращает рекурсию в цикл.
Re[18]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.10.04 11:28
Оценка:
Здравствуйте, Nick_, Вы писали:

N_>Почитай на досуге грамматику С++ или С.


Ну, спасибо дорогой! А то то я думал что мне почитать на досуге. Блин, я фигею.

Я тут между делом как раз парсеры разрабатываю: http://gzip.rsdn.ru/?article/rsharp/rsharp.xml
Автор(ы): Чистяков Влад (VladD2)
Дата: 28.01.2004


И уверяю тебя что кое-что в этом понимаю. Ты перепутал понятия синтаксического разбора (собственно парсинга) и семантического анализа.

N_>Хочешь сказать, что это семантика?


Даже говорить ничего не хочу. Если тебя интересует этот вопрос, то учебников по построению компиляторов море.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[31]: Вопрос о конкретных примерах
От: INTP_mihoshi Россия  
Дата: 07.10.04 11:45
Оценка:
Здравствуйте, Nick_, Вы писали:

N>>а зачем это ocalm например пытается делать?

N_>Не знаю. Это надо спросить кого-нибудь кто знает ocaml.
N_>Возможно имеется в виду, что рекурсия в ocaml так же эффективна как цикл в Си. Просто многие считают, что рекурсия это плохо, основываясь на своем опыте программирования в Си, где действительно каждый вызов функции приводит к работе со стеком. Поэтому и говорят, что ocaml превращает рекурсию в цикл.

Что? Где? А...

Tail recursion
Re[19]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 07.10.04 12:48
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Nick_, Вы писали:


VD>Я тут между делом как раз парсеры разрабатываю: http://gzip.rsdn.ru/?article/rsharp/rsharp.xml
Автор(ы): Чистяков Влад (VladD2)
Дата: 28.01.2004

Хочешь письками помериться?

VD>И уверяю тебя что кое-что в этом понимаю. Ты перепутал понятия синтаксического разбора (собственно парсинга) и семантического анализа.

А я тебя уверяю, что я ничего не напутал.

N_>>Хочешь сказать, что это семантика?


VD>Даже говорить ничего не хочу. Если тебя интересует этот вопрос, то учебников по построению компиляторов море.

То-есть аргументированно возразить уже не можешь?
Re[20]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.10.04 13:36
Оценка: :)
Здравствуйте, Nick_, Вы писали:

VD>>Я тут между делом как раз парсеры разрабатываю: http://gzip.rsdn.ru/?article/rsharp/rsharp.xml
Автор(ы): Чистяков Влад (VladD2)
Дата: 28.01.2004

N_>Хочешь письками помериться?

Ну, выкладывай, что у тебя там...

N_>А я тебя уверяю, что я ничего не напутал.


N_>То-есть аргументированно возразить уже не можешь?


Не просто доказывать подобные банальности. Да и не очень разумно. Я тебе уже говорил погугли по этому поводу. Например, так синтаксическим разбором называется.

Лучше уж ты даказывай свои гипотизы.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[21]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 07.10.04 14:13
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Лучше уж ты даказывай свои гипотизы.


В такой обстановке, когда пиписьками машут, как-то уже не хочется...
Re[24]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 07.10.04 18:41
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Массив не инициализирован и превышает размеры стэка.

А где сказано, что это Win32?

VD>Дык, ты результат верни и погляди что получится. А так он просто выбрасил с дури код и все.

А зачем? Разговор шел про конкретно ЭТУ программу.

VD>Думаю, что смысла в таком коде еще мешьше чем в заявлениях сделанных на его основе.

Про код согласен, а о заявлениях огласите весь список, пожалуйста! (что-то я не припомню никаких заявлений...)

VD>О! Умища палата. Вот только достаточно переменную в классик вынести или малейшие зачатки разума в алгоритм заложить и вся прыть компилятора куда-то улитучивается.

А нет никаких "если". Я говорил про конкретно ЭТУ программу и все!

VD>Вот именно по этому синтетические тесты не имеют смысла. У тебя даже заведомо бессмысленный код скомпилируется. А на рельныйкод это ровным счетом никакого влияние не окажет.

Дак я это и хотел сказать!
Я привел эти тесты как раз для того, чтобы продемонстрировать бессмысленность бенчмарков на тривиальных задачах, когда у компиля
тора имеется возможность "жульничать". Пожалуйста, читай внимательнее мои посты...
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[22]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.10.04 20:31
Оценка:
Здравствуйте, Nick_, Вы писали:

N_>В такой обстановке, когда пиписьками машут, как-то уже не хочется...


Ну, ты давай на разные органы то не сваливай. Сморозил фигню... с кем не бывает. Скажи: "ишибся, извни". А то сразу на чужие органы ссылки.

Если серьезно, то какой ты еще хотел реакции на слова "Почитай на досуге грамматику С++ или С." человеку который последние пол года только этой темой и занимался?
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[23]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 07.10.04 21:25
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Если серьезно, то какой ты еще хотел реакции на слова "Почитай на досуге грамматику С++ или С." человеку который последние пол года только этой темой и занимался?


OK. Обьясняю еще раз. на этот раз разжовываю как совсем чайнику.
Берем стандарт С++. Читаем Appendix A: Grammar summary

Компилятор разбирает выражение (hello.... перед ним стоит открывающая скобка.
Дальше он может идти по одному из двух путей

Если hello — тип:
expression->...->cast-expression->(->type-id->...->type-name->hello.
Если hello — идентификатор(переменная):
expression->...->cast-expression->...->primary-expression->(->expression->...->id-expression->hello.

Ну и как определить по какому пути делать синтаксический разбор, не зная hello тип или не тип?
Еще в качестве примера могу привести приоритет операций. То, что умножение имеет более высокий приоритет чем сложение выясняется уже на этапе синтаксического анализа, а не семантического.

После того как я тебе еще раз попытался разжевать, может ты потрудишься обьяснить что ты имел в виду в
сообщении http://rsdn.ru/Forum/Message.aspx?mid=840770&amp;only=1
Автор: VladD2
Дата: 06.10.04
когда заявил, что "Да пофигу для синтаксического разбора чем будет эта конструкция. Тип, не тип — это уже семантика."

cast-expression:
unary-expression
( type-id ) cast-expression

unary-expression:
postfix-expression
... -- здесь правила начинающиеся на ключевое слово или унарный оператор

postfix-expression:
primary-expression
... -- здесь правила либо начинающиеся на ключевое слово, либо postfix-expression, либо имя типа.

primary-expression:
literal
this
( expression )
id-expression

type-id:
type-specifier-seq [abstract-declarator]

type-specifier-seq:
type-specifier [type-specifier-seq]

type-specifier:
simple-type-specifier
...

simple-type-specifier:
[::] [nested-name-specifier] type-name

Цепочку от expression до cast-expression я пропустил. она простая. можешь сам ее посмотреть в стандарте.
Re[24]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.10.04 22:16
Оценка:
Здравствуйте, Nick_, Вы писали:

N_>OK. Обьясняю еще раз. на этот раз разжовываю как совсем чайнику.

N_>Берем стандарт С++. Читаем Appendix A: Grammar summary

N_>Компилятор разбирает выражение (hello.... перед ним стоит открывающая скобка.


Ну, это 100%-ный вызов функции.

N_>Дальше он может идти по одному из двух путей


N_>Если hello — тип:

N_>expression->...->cast-expression->(->type-id->...->type-name->hello.
N_>Если hello — идентификатор(переменная):
N_>expression->...->cast-expression->...->primary-expression->(->expression->...->id-expression->hello.

Ты наверно имешь в виду двусмысленность в трактовании выражения в скобках идущее перед идентификатором или другими скобками.

Дык тут в станадрте должно быть написано, что имеет место двусмысленность (ambiguities). Под рукой плюсового стандарта нет, так что точную формулировку привести не могу.

Так вот, чтобы разрешить эту двусмысленность компилятору нужно провести семантический анализ и определить является ли выражение в скобках типом или нет. Ситуация вроде "(Type)id" решается и без анализа. Но "(Type)-id" уже двусмысленна.

Это нормально. И не в коем случае не противоречит моим словам. Синтаксический разбор при этом остается синтаксическим рабзбором, а семантический анализ — семантическим анализом который проходит исключительно после стадии синтаксического разбора (иначе как собственно установить, был ли вообще объевлян Type?). Просто С++ довольно древний язык и в нем используемый тип обязан быть объявлен (продекларирован) до его использования. В C#, например, все намного сложнее. В нем тип не обязан быть объявлен до использования. По этому для начала семантического анализа требуется полностью закончить стадию синтаксического разбора. Именно по этому в C# данная неодназначность (к сожалению повзаимствованная из С++) решается более топорно. В C# введены эвристические правила позволяющие трактовать выражение в скобках как приведение типов:

The grammar for a cast-expression leads to certain syntactic ambiguities. [Example: The expression (x)–y could either be interpreted as a cast-expression (a cast of –y to type x) or as an additive- ression combined with a parenthesized-expression (which computes the value x – y). end example] To resolve cast-expression ambiguities, the following rule exists: A sequence of one or more tokens (§9.4) sed in parentheses is considered the start of a cast-expression only if at least one of the following are true:
• The sequence of tokens is correct grammar for a type, but not for an expression.
• The sequence of tokens is correct grammar for a type, and the token immediately following the closing
parentheses is the token “~”, the token “!”, the token “(”, an identifier (§9.4.1), a literal (§9.4.4), or any 13
keyword (§9.4.3) except as and is.
The term “correct grammar” above means only that the sequence of tokens shall conform to the rticular grammatical production. It specifically does not consider the actual meaning of any ituent identifiers. [Example: If x and y are identifiers, then x.y is correct grammar for a type, even if x.y doesn’t actually denote a type. end example]
[Note: From the disambiguation rule, it follows that, if x and y are identifiers, (x)y, (x)(y), and (-y) are cast-expressions, but (x)-y is not, even if x identifies a type. However, if x is a keyword identifies a predefined type (such as int), then all four forms are cast-expressions (because such a


N_>Ну и как определить по какому пути делать синтаксический разбор, не зная hello тип или не тип?


Только проведением семантического анализа. Но он может быть проведен только для части кода разобранной с помощью синтаксического разбора.

N_>Еще в качестве примера могу привести приоритет операций.

N_> То, что умножение имеет более высокий приоритет чем сложение выясняется уже на этапе синтаксического анализа, а не семантического.

Это выясняется на этапе составления граматики языка. А парсер всего лишь отражает спецификацию. К семантике приоритеты не имеют ни малейшего отношения.

N_>После того как я тебе еще раз попытался разжевать, может ты потрудишься обьяснить что ты имел в виду в

N_>сообщении http://rsdn.ru/Forum/Message.aspx?mid=840770&amp;only=1
Автор: VladD2
Дата: 06.10.04
когда заявил, что "Да пофигу для синтаксического разбора чем будет эта конструкция. Тип, не тип — это уже семантика."


В приведенном тобой примере никакой двусмысленности нет и семантический анализ не трелуется. Из контекста четко видно, чем должен быть идентификатор. Так что код будет спокойно распарсен в АСТ и кога пойдет воплощение шаблона просто будет проверено, что данный идинтификатор действительно существует и является типом. А для разрешения неоднозначностей как раз и был введен typename.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[25]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 08.10.04 04:50
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Nick_, Вы писали:


N_>>OK. Обьясняю еще раз. на этот раз разжовываю как совсем чайнику.

N_>>Берем стандарт С++. Читаем Appendix A: Grammar summary

N_>>Компилятор разбирает выражение (hello.... перед ним стоит открывающая скобка.


VD>Ну, это 100%-ный вызов функции.

Ты бредишь?

N_>>Дальше он может идти по одному из двух путей


N_>>Если hello — тип:

N_>>expression->...->cast-expression->(->type-id->...->type-name->hello.
N_>>Если hello — идентификатор(переменная):
N_>>expression->...->cast-expression->...->primary-expression->(->expression->...->id-expression->hello.

VD>Ты наверно имешь в виду двусмысленность в трактовании выражения в скобках идущее перед идентификатором или другими скобками.

Это как? Выражение в скобках (exp) идущее перед идентификатором или другими скобками...
(expr)id или (expr)(...
Слушай, я об одном, а ты о другом. Попробуй еще раз почитать что я написал.
Я о двусмысленности трактования идентификатора в скобках, при разборе выражения.
(hello)...
Это может быть либо c-style-cast либо переменная в скобках.

VD>Дык тут в станадрте должно быть написано, что имеет место двусмысленность (ambiguities). Под рукой плюсового стандарта нет, так что точную формулировку привести не могу.

Найди и почитай стандарт. Никакой двусмысленности нет, если компилятор знает, что тип а что не тип.

VD>Так вот, чтобы разрешить эту двусмысленность компилятору нужно провести семантический анализ и определить является ли выражение в скобках типом или нет. Ситуация вроде "(Type)id" решается и без анализа. Но "(Type)-id" уже двусмысленна.

О том я и говорю. Так вот в шаблоне, компилятор не может определить тип или не тип стоит в скобках.
Я уже приводил пример с (T::x)+1; Поэтому компилятор не может сделать синтаксический разбор. А семантический разбор может быть проведен только при инстанциации. Никакие эвристики тут не помогут. Некоторые компиляторы С++ стоят AST в предположении что T::x это переменная, а потом выкидывают эти результаты и парсят заново шаблон при инстанциации. Некоторые вообще не парсят шаблон до инстанциации.
Если не веришь, то можешь попробовать взять сановский компилятор С++ Forte и проверить.
template<class T>
class A
{
this is a test;
};
Скомпилируется без ошибок.

VD>Это нормально. И не в коем случае не противоречит моим словам. Синтаксический разбор при этом остается синтаксическим рабзбором, а семантический анализ — семантическим анализом который проходит исключительно после стадии синтаксического разбора (иначе как собственно установить, был ли вообще объевлян Type?). Просто С++ довольно древний язык и в нем используемый тип обязан быть объявлен (продекларирован) до его использования. В C#, например, все намного сложнее. В нем тип не обязан быть объявлен до использования. По этому для начала семантического анализа требуется полностью закончить стадию синтаксического разбора.

Еще пример:
01 typedef int free;
02 void main()
03 {
04 free(ptr);
05 }
Компилятор не может сделать семантический анализ четвертой строки до синтаксического анализа четвертой строки. Это как ты утверждаешь и я с этим согласен.
Но компилятор не может сделать синтаксический анализ четвертой строки до семантического анализа первой.
Ну не может для такой программы семантический анализ быть "исключительно после" синтаксического.

N_>>Ну и как определить по какому пути делать , не зная hello тип или не тип?


VD>Только проведением семантического анализа. Но он может быть проведен только для части кода разобранной с помощью синтаксического разбора.

Тоесть в одном месте ты пишешь: "семантическим анализом который проходит исключительно после стадии синтаксического разбора", а теперь ты отвечаешь мне, что синтаксический разбор можно сделать только после семантического. "Но он может быть проведен только для части кода разобранной с помощью синтаксического разбора."
Ты похоже не только не читаешь что люди пишут, но и не читаешь что пишешь сам...

N_>>Еще в качестве примера могу привести приоритет операций.

N_>> То, что умножение имеет более высокий приоритет чем сложение выясняется уже на этапе синтаксического анализа, а не семантического.

VD>Это выясняется на этапе составления граматики языка. А парсер всего лишь отражает спецификацию. К семантике приоритеты не имеют ни малейшего отношения.

Ну почему же? Кто мешает составить грамматику так, что бы в ней не отражался приоритет операций? Тогда приоритет будет делом семантического анализа. И такие языки есть, в которых можно менять приоритеты операций. Например пролог.

N_>>После того как я тебе еще раз попытался разжевать, может ты потрудишься обьяснить что ты имел в виду в

N_>>сообщении http://rsdn.ru/Forum/Message.aspx?mid=840770&amp;only=1
Автор: VladD2
Дата: 06.10.04
когда заявил, что "Да пофигу для синтаксического разбора чем будет эта конструкция. Тип, не тип — это уже семантика."


VD>В приведенном тобой примере никакой двусмысленности нет и семантический анализ не трелуется. Из контекста четко видно, чем должен быть идентификатор. Так что код будет спокойно распарсен в АСТ и кога пойдет воплощение шаблона просто будет проверено, что данный идинтификатор действительно существует и является типом. А для разрешения неоднозначностей как раз и был введен typename.

В каком из примеров нет двусмысленности? В этом?
template<class T>
class A
{
int x = (T::x)+1;
};
А если пойдет воплощение шаблона, и окажется что идентификатор — не то о чем компилятор подумал при первом проходе?

А вот например, если бы параметров у шаблона было 5, то вариантов разбора было бы 2^5 = 32. Зачем запоминать AST, при первом проходе, а потом проверять при инстанциации, если скорее всего он никогда не понадобится и придется заново делать разбор?

Короче, у меня складывается впечатление, что ты не вникаешь в то, что люди пишут... Попробуй прочитать с чего все началось еще раз и выписать с чем конкретно ты несогласен. А то одному все разжевал, и тут приходит второй и начинается заново.
Re[26]: Вопрос о конкретных примерах
От: prVovik Россия  
Дата: 08.10.04 14:43
Оценка: +1
Здравствуйте, Nick_, Вы писали:

N_>Я о двусмысленности трактования идентификатора в скобках, при разборе выражения.

N_>(hello)...
N_>Это может быть либо c-style-cast либо переменная в скобках.

Пожобная двусмысленность не может быть обработана на этаме синтаксического анализа, так как на данном этапе происходит разбор выражнния исключительно по КОНТЕКСТНО СВОБОДНОЙ грамматике. А описанная тобой двусмысленность может быть обработана контекстно зависимой грамматикой, а следовательно это может произойти только на этапе семантического анализа.
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[27]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 08.10.04 15:00
Оценка:
Здравствуйте, prVovik, Вы писали:

V>Пожобная двусмысленность не может быть обработана на этаме синтаксического анализа, так как на данном этапе происходит разбор выражнния исключительно по КОНТЕКСТНО СВОБОДНОЙ грамматике. А описанная тобой двусмысленность может быть обработана контекстно зависимой грамматикой, а следовательно это может произойти только на этапе семантического анализа.


Грамматика Си — контекстно зависима. То, что Си парсится LL парсером ничего не говорит, потому что это не честный LL или LR парсер. при чтении символа лексическим анализатором проверяется, является ли этот символ типом. А синтаксический анализатор заносит новые типы определенные c gjvjom. ензувуа в таблицу типов, которой пользуется лексический анализатор.
Такая обратная связь выходит за рамки LL разбора и позволяет разобрать контекстно зависимую грамматику языка Си.
Еще раз приведу пример:

int main()
{
free(ptr); // это вызов функции или определение переменной?
}

Для вызова функции и определения переменной используются разные синтаксические конструкции.
И в данном случае, это зависит от контекста: встретилось ли ранее typedef int free;
Re[26]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 08.10.04 16:20
Оценка:
Здравствуйте, Nick_, Вы писали:

N_>Ты бредишь?


Я нет. А ты вот хамишь.

VD>>Дык тут в станадрте должно быть написано, что имеет место двусмысленность (ambiguities). Под рукой плюсового стандарта нет, так что точную формулировку привести не могу.

N_>Найди и почитай стандарт. Никакой двусмысленности нет, если компилятор знает, что тип а что не тип.

Даже не собираюсь искать. Компилятор не одущевленное существо, чтобы что-то знать. Есть конфликт граматики (двусмысленность) которая разрешается семантическими средствами. И это совсем другой случай.

N_>О том я и говорю. Так вот в шаблоне, компилятор не может определить тип или не тип стоит в скобках.

N_>Я уже приводил пример с (T::x)+1; Поэтому компилятор не может сделать синтаксический разбор.

Для решения пдобных двусмысленностей и существует typename. В приведенном же тобой тогда примере никаких двусмысленностей нет. И компилятор может сделать четкий вывод.

N_>Если не веришь, то можешь попробовать взять сановский компилятор С++ Forte и проверить.

N_>template<class T>
N_>class A
N_>{
N_> this is a test;
N_>};
N_>Скомпилируется без ошибок.

Каким-то компилятором без ошибок. А каким-то и с ошибками. Согласен, что контрольк производится во многих случаях поздновато. Но в этом есть дополнительная гибкость.

Кстати, вот именно этот тест показывает, что тот же VC разбор делает:
c:\MyProjects\FizTypeTest\FizTypeTest\FizTypeTest.cpp(120) : error C2059: syntax error : 'this'
c:\MyProjects\FizTypeTest\FizTypeTest\FizTypeTest.cpp(120) : error C2238: unexpected token(s) preceding ';'


То есть подобные ситуации распарсиваются им, но не в конкретные, в более общие АСТ-структуры. Ну, а окончательный семантический контроль проводится уже на стадии воплощения шаблона.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[27]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 08.10.04 18:27
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Каким-то компилятором без ошибок. А каким-то и с ошибками. Согласен, что контрольк производится во многих случаях поздновато. Но в этом есть дополнительная гибкость.


VD>Кстати, вот именно этот тест показывает, что тот же VC разбор делает:

VD>
VD>c:\MyProjects\FizTypeTest\FizTypeTest\FizTypeTest.cpp(120) : error C2059: syntax error : 'this'
VD>c:\MyProjects\FizTypeTest\FizTypeTest\FizTypeTest.cpp(120) : error C2238: unexpected token(s) preceding ';'
VD>


VD>То есть подобные ситуации распарсиваются им, но не в конкретные, в более общие АСТ-структуры. Ну, а окончательный семантический контроль проводится уже на стадии воплощения шаблона.


Об этом и речь, что окончательный разбор шаблона делается уже при инстанциации.
Обсуждать остальные разногласия я считаю уже бессмысленым делом.
Re[24]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 08.10.04 19:45
Оценка:
Здравствуйте, Nick_, Вы писали:

N_>Сначала программа переводится в SSA форму, над которой потом делаются оптимизации.

N_>Так вот сюрпиз! SSA форма — это функциональная программа
N_>http://citeseer.ist.psu.edu/appel98ssa.html

Для подобных оптимизаций достаточно АСТ. Где ты взял что МС использует именно этот SSA?
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[26]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 08.10.04 19:45
Оценка:
Здравствуйте, Nick_, Вы писали:

N_>Просто так оптимизации в компиляторы не вставляют. Для любой оптимизации надо сначала доказать, что она не меняет семантику кода.


К сожалению в том же VC часто можно встретить оптимизации таки меняющие семантику и способные вызвать проблемы. Ну, да к ФЯ изменение семантики вряд ли имеет прямое отношение.

N_> А для этого в свою очередь нужен способ, который бы позволил сказать, что два разных алгоритма делают одно и то же. В общем случае, эта задача алгоритмически неразрешима. Но для более узких типов эквивалентности алгоритмов это можно сделать. Кроме того алгоритм должет быть как-то записан. Для некоторых форм записи провести доказательство правильности оптимизации проще чем для других. SSA — это уже де-факто стандартная форма записи алгоритмов. Большинство доказательств корректности оптимизаций делается для оптимизайций SSA формы. В большинстве современных компиляторов используется SSA форма, как внутреннее представление программы.


N_>PS: Ну а gcc для меня не авторитет.


А как на счет байткода Явы, МСИЛ-а дотнета, промежуточного кода Фекниса? Они вроде к этому SSA отношения не имеют. Но тем не менее оптимизации поддаются в лучшем виде. Те же джиты делают кучу оптимизаций при генерации исполняемого кода.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[28]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 08.10.04 19:45
Оценка:
Здравствуйте, Nick_, Вы писали:

N_>Еще раз приведу пример:


N_>int main()

N_>{
N_> free(ptr); // это вызов функции или определение переменной?
N_>}

Это вообще безконфликтый случай. Это никак не может быть определением переменной. Тут конфликта нет. А вот в приведении типов конфликт действительно есть, и без привлечения семантического анализа определить конкретный тип конструкции нельзя.

N_>Для вызова функции и определения переменной используются разные синтаксические конструкции.

N_>И в данном случае, это зависит от контекста: встретилось ли ранее typedef int free;

В данном случае ничего повлиять уже не может. Приведи, плиз, пример где бы твоя конструкция была бы корректно распознана парсером как объявление переменной.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[28]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 08.10.04 20:05
Оценка:
Здравствуйте, Nick_, Вы писали:

N_>Об этом и речь, что окончательный разбор шаблона делается уже при инстанциации.

N_>Обсуждать остальные разногласия я считаю уже бессмысленым делом.

Ты утверждал, что разбор вообще не делается.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[26]: Вопрос о конкретных примерах
От: WolfHound  
Дата: 08.10.04 21:22
Оценка:
Здравствуйте, Nick_, Вы писали:

N_>В каком из примеров нет двусмысленности? В этом?

N_>template<class T>
N_>class A
N_>{
N_> int x = (T::x)+1;
N_>};
N_>А если пойдет воплощение шаблона, и окажется что идентификатор — не то о чем компилятор подумал при первом проходе?

Ты бы пошол станларт почитал чтоли.
14.6/2

A name used in a template declaration or definition and that is dependent on a template-parameter is assumed not to name a type unless the applicable name lookup finds a type name or the name is qualified by the keyword typename.

14.6/3

A qualified-name that refers to a type and that depends on a template-parameter (14.6.2) shall be prefixed by the keyword typename to indicate that the qualified-name denotes a type, forming an elaborated-type-specifier (7.1.5.3).

... << RSDN@Home 1.1.4 rev. 185 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[18]: Вопрос о конкретных примерах
От: eugals Россия  
Дата: 09.10.04 11:47
Оценка:
Здравствуйте, FR, Вы писали:

FR>Питон (c psyco) не может упереся в память, плохие у него массивы(вернее их и нету вовсе)

см. module array
... << RSDN@Home 1.1.4 beta 2 >>
Re[19]: Вопрос о конкретных примерах
От: FR  
Дата: 09.10.04 13:27
Оценка:
Здравствуйте, eugals, Вы писали:

E>Здравствуйте, FR, Вы писали:


FR>>Питон (c psyco) не может упереся в память, плохие у него массивы(вернее их и нету вовсе)

E>см. module array

смотрел уже, с ними упирается в память.
... << RSDN@Home 1.1.3 stable >>
Re[29]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 09.10.04 21:09
Оценка:
Здравствуйте, VladD2, Вы писали:

N_>>Еще раз приведу пример:


N_>>int main()

N_>>{
N_>> free(ptr); // это вызов функции или определение переменной?
N_>>}

VD>Это вообще безконфликтый случай. Это никак не может быть определением переменной. Тут конфликта нет. А вот в приведении типов конфликт действительно есть, и без привлечения семантического анализа определить конкретный тип конструкции нельзя.


N_>>Для вызова функции и определения переменной используются разные синтаксические конструкции.

N_>>И в данном случае, это зависит от контекста: встретилось ли ранее typedef int free;

VD>В данном случае ничего повлиять уже не может. Приведи, плиз, пример где бы твоя конструкция была бы корректно распознана парсером как объявление переменной.


Я считаю, что с тобой уже обсуждать что-то бессмысленно. Мало того, что ты Си не знаешь, так еще и не удосужился проверить.

typedef int free;
int main()
{
    free(ptr); /* обьявление переменной int ptr */
}
Re[27]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 09.10.04 21:12
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Ты бы пошол станларт почитал чтоли.


Вот не надо придираться к фразам выранным из контекста. Если бы читал о чем была речь ранее, то обратил бы внимание на "...unless the applicable name lookup finds a type name..."
Re[30]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.10.04 01:07
Оценка:
Здравствуйте, Nick_, Вы писали:

N_>Я считаю, что с тобой уже обсуждать что-то бессмысленно.


Так что тогда разговариваешь? Столько пафоса и все в пустую.

N_> Мало того, что ты Си не знаешь, так еще и не удосужился проверить.


N_>
N_>typedef int free;
N_>int main()
N_>{
N_>    free(ptr); /* обьявление переменной int ptr */
N_>}
N_>


Да, ошибся я тут. По крайней мере VC действительно воспринимает это за объявление переменной. Был лучшего мнения о С++. В Шарпе такой бред недопустим, а к хорошему быстро привыкаешь. Хотя возможно это очередная глюка VC. Тут нужно стандарт глядеть. А его под рукой нет.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.10.04 01:07
Оценка:
Здравствуйте, Quintanar, Вы писали:

Q>Атомарность кашицы на ИЯ и ФЯ разная. Пример сортировки на haskell тому пример, хоть и одиозный. И причем тут итеративные языки — все языки итеративные.


Откровенно говоря чем больше сморю на быструю сортировку на Хаскеле, тем больше совневаюсь в его доказательности и честности. Тут было уже довольно много разумных слов о том, что и красоты этой можно добиться на импиративных языках, и о том, что она больше из-за того что работа со списками красиво интегрирована в хаскель, и о том, что сортировка эта не быстрая, и даже о том, что это не савсем как бы и тот алгоритм.

Так же многие тут предлагали создать более близкий к жизник пример. А то примеры уж больно оторваны от жизни. Например, интересно было бы поглядеть на то как будет выглядеть динамическая веб-страничка на одном из ФЯ. Ну, или утилита вроде этой: http://gzip.rsdn.ru/article/dotnet/regexprep_.xml
Автор(ы): Владислав Чистяков
Дата: 26.10.2002
Аннотация: Статья рассчитана на тех, кто хочет изучить программирование в .Net и язык C#, или хотя бы понять, как можно использовать эту среду, чтобы решить стоит ли этим заниматься. Эта статья также будет полезна начинающим программистам, так как позволяет пройти весь цикл разработки программы. В качестве побочного эффекта вы получите полезную утилиту.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[15]: Вопрос о конкретных примерах
От: INTP_mihoshi Россия  
Дата: 10.10.04 10:38
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Так же многие тут предлагали создать более близкий к жизник пример. А то примеры уж больно оторваны от жизни. Например, интересно было бы поглядеть на то как будет выглядеть динамическая веб-страничка на одном из ФЯ. Ну, или утилита вроде этой: http://gzip.rsdn.ru/article/dotnet/regexprep_.xml
Автор(ы): Владислав Чистяков
Дата: 26.10.2002
Аннотация: Статья рассчитана на тех, кто хочет изучить программирование в .Net и язык C#, или хотя бы понять, как можно использовать эту среду, чтобы решить стоит ли этим заниматься. Эта статья также будет полезна начинающим программистам, так как позволяет пройти весь цикл разработки программы. В качестве побочного эффекта вы получите полезную утилиту.


А как она должна выглядеть? HTML как HTML. С вкраплениями типа
<?ocml Printf.printf ("This is generated by the OCAML interpreter.");; ?>
, если используется mod_ocaml

Имху, реальным стресс-тестом для любого языка общего назначения может быть серьезная real-time 3d графика и/или физика...
Re[16]: Вопрос о конкретных примерах
От: FR  
Дата: 10.10.04 12:21
Оценка: +1
Здравствуйте, INTP_mihoshi, Вы писали:


INT>Имху, реальным стресс-тестом для любого языка общего назначения может быть серьезная real-time 3d графика и/или физика...


Только если брать ту же 3D графику там очень много алгоритмов завязанных на большие массивы данных, а с ними (даже на примере обсуждения здесь) проще работать императивно.
Хотя в 3D есть и алгоритмы которые могут неплохо лечь под функциональный стиль(те же построения всякого рода древовидных конструкции для определения видимости и т. п.), но боюсь с ними может получится то же что и с быстрой сортировкой, так как реализация обычно сильно усложнена всякими мелкими деталями и оптимизацией.
... << RSDN@Home 1.1.3 stable >>
Re[28]: Вопрос о конкретных примерах
От: WolfHound  
Дата: 10.10.04 12:29
Оценка:
Здравствуйте, Nick_, Вы писали:

WH>>Ты бы пошол станларт почитал чтоли.


N_>Вот не надо придираться к фразам выранным из контекста. Если бы читал о чем была речь ранее, то обратил бы внимание на "...unless the applicable name lookup finds a type name..."

Re[6]: ??? Какого оно компилится???
Автор: WolfHound
Дата: 01.10.04
... << RSDN@Home 1.1.4 rev. 185 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[15]: Вопрос о конкретных примерах
От: Quintanar Россия  
Дата: 10.10.04 14:51
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Так же многие тут предлагали создать более близкий к жизник пример. А то примеры уж больно оторваны от жизни. Например, интересно было бы поглядеть на то как будет выглядеть динамическая веб-страничка на одном из ФЯ. Ну, или утилита вроде этой: http://gzip.rsdn.ru/article/dotnet/regexprep_.xml
Автор(ы): Владислав Чистяков
Дата: 26.10.2002
Аннотация: Статья рассчитана на тех, кто хочет изучить программирование в .Net и язык C#, или хотя бы понять, как можно использовать эту среду, чтобы решить стоит ли этим заниматься. Эта статья также будет полезна начинающим программистам, так как позволяет пройти весь цикл разработки программы. В качестве побочного эффекта вы получите полезную утилиту.


Динамическая — это с событиями? Думаю так же, как и javascript какой-нибудь.

А с утилитой вроде этой есть один вопрос — она с графическим интерфейсом. ФЯ используют обычно чужие билиотеки (OCaml, вроде, GTK. Haskell — wxWidgets и GTK). И вид конкретной программы будет зависеть от того, какую библиотеку она использует. Я чисто из интереса мог бы попробовать написать интерфейс на Haskell + wxWidgets, там это относительно легко, как я понял из примеров.
Re[17]: Вопрос о конкретных примерах
От: Quintanar Россия  
Дата: 10.10.04 14:54
Оценка:
Здравствуйте, FR, Вы писали:

FR>Здравствуйте, INTP_mihoshi, Вы писали:



INT>>Имху, реальным стресс-тестом для любого языка общего назначения может быть серьезная real-time 3d графика и/или физика...


FR>Только если брать ту же 3D графику там очень много алгоритмов завязанных на большие массивы данных, а с ними (даже на примере обсуждения здесь) проще работать императивно.


Они там read only в основном, вроде, и проблемы с массивами есть только у ленивых языков. Но все равно сложно сказать, что получится в результате.
Re[16]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.10.04 15:00
Оценка:
Здравствуйте, INTP_mihoshi, Вы писали:

VD>>Так же многие тут предлагали создать более близкий к жизник пример. А то примеры уж больно оторваны от жизни. Например, интересно было бы поглядеть на то как будет выглядеть динамическая веб-страничка на одном из ФЯ. Ну, или утилита вроде этой: http://gzip.rsdn.ru/article/dotnet/regexprep_.xml
Автор(ы): Владислав Чистяков
Дата: 26.10.2002
Аннотация: Статья рассчитана на тех, кто хочет изучить программирование в .Net и язык C#, или хотя бы понять, как можно использовать эту среду, чтобы решить стоит ли этим заниматься. Эта статья также будет полезна начинающим программистам, так как позволяет пройти весь цикл разработки программы. В качестве побочного эффекта вы получите полезную утилиту.


INT>А как она должна выглядеть? HTML как HTML. С вкраплениями типа

INT><?ocml Printf.printf ("This is generated by the OCAML interpreter.");; ?>
INT>, если используется mod_ocaml

Как она должна выглядить я не знаю. Но то что к ней нужно подробное объяснение приложить и аналогичный пример на том же ASP.NET — это точно. Вот такой пример тут был бы воспринят на ура.

INT>Имху, реальным стресс-тестом для любого языка общего назначения может быть серьезная real-time 3d графика и/или физика...


Не думаю, что кто-то из здесь присуствующих способен создать подбный пример. Да и вряд ли его можно будет легко понять. Ведь как не крути это будет огромный объем кода.

Но как пример того, что такие проекты возможны и есть было бы неплохо заполучить ссылку на подобное приложение. Кстати, сказать 3D-игры на дотнете уже точно есть. Я тут как-то скачивал и устанавливал одну 3D RTS. Надо признаться очень недурственно (жаль немецы делали... слишком много немецкого). Со скоростью проблем нет. Использует D3D и вообще DX.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[18]: Вопрос о конкретных примерах
От: FR  
Дата: 10.10.04 16:08
Оценка: 4 (1)
Здравствуйте, Quintanar, Вы писали:


FR>>Только если брать ту же 3D графику там очень много алгоритмов завязанных на большие массивы данных, а с ними (даже на примере обсуждения здесь) проще работать императивно.


Q>Они там read only в основном, вроде, и проблемы с массивами есть только у ленивых языков. Но все равно сложно сказать, что получится в результате.


Полно и не read only, например динамическое заполнение вершиных и индексных буферов, по довольно замороченному алгоритму и со скоростью близкой к пропускной способности ОЗУ. И вообще общение с 3D API практически очень близко к системному программированию. Мне кажется писать именно 3D движек на функциональном языке (даже на ocaml) будет намного сложнее чем на C/C++.
... << RSDN@Home 1.1.3 stable >>
Re[16]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.10.04 17:12
Оценка:
Здравствуйте, Quintanar, Вы писали:

VD>>Так же многие тут предлагали создать более близкий к жизник пример. А то примеры уж больно оторваны от жизни. Например, интересно было бы поглядеть на то как будет выглядеть динамическая веб-страничка на одном из ФЯ. Ну, или утилита вроде этой: http://gzip.rsdn.ru/article/dotnet/regexprep_.xml
Автор(ы): Владислав Чистяков
Дата: 26.10.2002
Аннотация: Статья рассчитана на тех, кто хочет изучить программирование в .Net и язык C#, или хотя бы понять, как можно использовать эту среду, чтобы решить стоит ли этим заниматься. Эта статья также будет полезна начинающим программистам, так как позволяет пройти весь цикл разработки программы. В качестве побочного эффекта вы получите полезную утилиту.


Q>Динамическая — это с событиями? Думаю так же, как и javascript какой-нибудь.


Динамическая — это значит интерактивная. Но не клиентских скриптах, а не серверном коде. Ну, там оформление заказа на продажу.

Q>А с утилитой вроде этой есть один вопрос — она с графическим интерфейсом.


Дык это как раз одно из самых интересных. Кому сегодня нужен язык не позволяющий создавать ГУИ?

Q> ФЯ используют обычно чужие билиотеки (OCaml, вроде, GTK. Haskell — wxWidgets и GTK). И вид конкретной программы будет зависеть от того, какую библиотеку она использует.


Да какая разница? Интересен сам пример.

Q> Я чисто из интереса мог бы попробовать написать интерфейс на Haskell + wxWidgets, там это относительно легко, как я понял из примеров.


Давай. Но потому нужно будет описать все по шагам. Ну, чтобы начинающий мог понять что и как.

ЗЫ

Кстати, тем и интересен F#. В нем же можно использовать тот же WinForms.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[17]: Вопрос о конкретных примерах
От: Quintanar Россия  
Дата: 10.10.04 18:04
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Да какая разница? Интересен сам пример.


Q>> Я чисто из интереса мог бы попробовать написать интерфейс на Haskell + wxWidgets, там это относительно легко, как я понял из примеров.


VD>Давай. Но потому нужно будет описать все по шагам. Ну, чтобы начинающий мог понять что и как.


wxWidgets — мультиплатформенная. А поскольку Haskell тоже мультиплатформенный, то такая прога будет работать и под Мас и под XWindows и под просто Windows, в отличие от WinForms. Хотя у wxWidgets есть свой минус, к выходному файлу статически прилинковывается немерянный 8 метровый файл библиотеки. Возможно это можно обойти, но пока не знаю.
Пока для примера могу запостить код Hello World с кнопкой, чисто для сравнения, хотя сравнивать особо нечего — получается практически тоже самое, что и в C# — длинные вереницы команд для создания контролов, задания свойств контролов и добавления одних контролов в другие.
module Main where

import Graphics.UI.WX

-- главная функция. start - инициализирует библиотеку и запускает цикл для сообщений
main :: IO ()
main = start demo     -- "start" initializes the GUI.

demo :: IO ()
demo = do f <- frame        [text := "Bye!"] -- создаем главное окно
          p <- panel f      []  -- создаем панельку для размещения других контролов
          t <- staticText p [text := "Hello World"] -- контрол Static Text
          b <- button     p [text := "Bye"] -- кнопка
          set b [on command := bye f t b] -- устанавливаем event "command", срабатывает при нажатии
          set f [layout := fill $ container p $ margin 10 $ -- указываем как должны быть расположены контролы друг относительно друга
                           column 5 [widget t, widget b]]      
          focusOn b -- ну тут понятно - фокус на кнопку
     where
       -- вызывается при нажатии на кнопку
       bye f t b
         = do set t [text := "Goodbye"] -- устанавливаем новый текст для Static Text
              set b [on command := close f]   -- и новый обработчик события для кнопки
Re[18]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.10.04 21:01
Оценка:
Здравствуйте, Quintanar, Вы писали:

Q>wxWidgets — мультиплатформенная. А поскольку Haskell тоже мультиплатформенный, то такая прога будет работать и под Мас и под XWindows и под просто Windows, в отличие от WinForms.


Ну, это не хорошо и не плохо. 90% програмистам с этого сайта переносимость ненужна. Но раз уж она есть, то не бороться ся же сний?

Q> Хотя у wxWidgets есть свой минус, к выходному файлу статически прилинковывается немерянный 8 метровый файл библиотеки. Возможно это можно обойти, но пока не знаю.


Да уж. 8 метров это что-то крутовато. Хотя если дальнейший рост маленький то пержить можно.

Q>Пока для примера могу запостить код Hello World с кнопкой, чисто для сравнения, хотя сравнивать особо нечего — получается практически тоже самое, что и в C# — длинные вереницы команд для создания контролов, задания свойств контролов и добавления одних контролов в другие.

Q>
Q>module Main where

Q>import Graphics.UI.WX

Q>-- главная функция. start - инициализирует библиотеку и запускает цикл для сообщений
Q>main :: IO ()
Q>main = start demo     -- "start" initializes the GUI.

Q>demo :: IO ()
Q>demo = do f <- frame        [text := "Bye!"] -- создаем главное окно
Q>          p <- panel f      []  -- создаем панельку для размещения других контролов
Q>          t <- staticText p [text := "Hello World"] -- контрол Static Text
Q>          b <- button     p [text := "Bye"] -- кнопка
Q>          set b [on command := bye f t b] -- устанавливаем event "command", срабатывает при нажатии
Q>          set f [layout := fill $ container p $ margin 10 $ -- указываем как должны быть расположены контролы друг относительно друга
Q>                           column 5 [widget t, widget b]]      
Q>          focusOn b -- ну тут понятно - фокус на кнопку
Q>     where
Q>       -- вызывается при нажатии на кнопку
Q>       bye f t b
Q>         = do set t [text := "Goodbye"] -- устанавливаем новый текст для Static Text
              Что-то я не понял, когда устанавливается текст "Goodbye"? Его хоть кто-то увидит?
Q>              set b [on command := close f]   -- и новый обработчик события для кнопки
Q>


Замечания:
1. Переменным все же нужно давать осмысленные имена, а не однобуквенные. Инача воспринимать код очень трудно. Это больше похоже на шифрование.
2. Хотя бы скриншот того что получилось. Ведь не каждый может скачать себе все что жуно чтобы зпустить этот пример. Тут же потребуется и Цигвин ставить, и Хаскель, и еще чего нить.

Кстати, конструкции вроде:
f <- frame        [text := "Bye!"]

тоже хорошо бы объяснить.

С шарпом подобный пример тяжело сравнивать по той причине, что он а) ничего не далет, б) дизайн форм в Шарпе делается визуально и из всего приведенного кода написать прийдется только "Close();". Но конечно можно и вручную:
using System;
using System.Windows.Forms;

class Form1 : Form
{
    public Form1()
    {
        // Настраиваем лэйбл
        Label _labelText = new Label();
        this.Text = labelText.Text = "Hello World";
        labelText.AutoSize = true;
        
        // Настравивем кнопку
        Button pbGoodbye = new Button();
        pbGoodbye.Text = "Close";
        pbGoodbye.Click += delegate(object sender, EventArgs e) { Close(); };

        _pbGoodbye.Anchor = labelText.Anchor = AnchorStyles.None;

        // Настраиваем лэйаут (просто для похожести). С ним можно и не выпендриваться.
        TableLayoutPanel tblLayout = new TableLayoutPanel();
        tblLayout.Controls.Add(pbGoodbye, 0, 1);
        tblLayout.Controls.Add(labelText, 0, 0);
        tblLayout.Dock = DockStyle.Fill;

        this.Controls.Add(tblLayout); // Дабавляем TableLayoutPanel к форме
        this.Size = new System.Drawing.Size(200, 100); // Задаем размер формы.
    }
}




Я не знаю как-кто, а я особоно приемущества не вижу.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[19]: Вопрос о конкретных примерах
От: Quintanar Россия  
Дата: 10.10.04 21:56
Оценка: 15 (1)
Здравствуйте, VladD2, Вы писали:

VD>bye f t b

VD>Q> = do set t [text := "Goodbye"] -- устанавливаем новый текст для Static Text
VD> Что-то я не понял, когда устанавливается текст "Goodbye"? Его хоть кто-то увидит?
VD>Q> set b [on command := close f] -- и новый обработчик события для кнопки
VD>Q>
При нажатии на кнопку вызовется этот метод. Он поменяет текст в static text и установит новый обработчик события нажатия на кнопку для кнопки. При следующем нажатии, выполнение программы закончится.

VD>Замечания:

VD>1. Переменным все же нужно давать осмысленные имена, а не однобуквенные. Инача воспринимать код очень трудно. Это больше похоже на шифрование.
VD>2. Хотя бы скриншот того что получилось. Ведь не каждый может скачать себе все что жуно чтобы зпустить этот пример. Тут же потребуется и Цигвин ставить, и Хаскель, и еще чего нить.

Получится тоже, что и у тебя. Хотя у меня стиль GUI старый, не знаю, что на XP будет. И я не знаю, как сюда вставлять рисунки. Что нужно для этого сделать?

VD>Кстати, конструкции вроде:

VD>
VD>f <- frame        [text := "Bye!"]
VD>

VD>тоже хорошо бы объяснить.

Это синтаксис языка заточенный под работу с монадами (в конечном счете для того, чтобы ввод-вывод был более красивым и понятным). Подобная конструкция означает, что с переменной f будет связано некоторое значение, в данном случае окно. frame — функция, которая его создает. В квадратных скобках список пропертей. := — на самом деле просто перегруженная функция, а не равно, которая присваивает значение соответствующему атрибуту и возвращает его в виде проперти.

VD>С шарпом подобный пример тяжело сравнивать по той причине, что он а) ничего не далет, б) дизайн форм в Шарпе делается визуально и из всего приведенного кода написать прийдется только "Close();". Но конечно можно и вручную:


VD>Я не знаю как-кто, а я особоно приемущества не вижу.


Ну правильно. Я же говорю, все очень похоже. То что есть визуальный редактор, облегчает работу, конечно, но теоретически можно и для Haskell такой написать.
Re[20]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.10.04 22:32
Оценка:
Здравствуйте, Quintanar, Вы писали:

Q>При нажатии на кнопку вызовется этот метод. Он поменяет текст в static text и установит новый обработчик события нажатия на кнопку для кнопки. При следующем нажатии, выполнение программы закончится.


Ужас какой.
К сожалению это совсем не очевидно.

Q>Получится тоже, что и у тебя.


Вот только я не уверен, что все догадаются об этом.

Q>И я не знаю, как сюда вставлять рисунки. Что нужно для этого сделать?


Нажать на свое имя в верхнем правом углу броузера. Откроется профайл... Выбрать в нем пункт "Файлы" (ссылка сверху). Далее сделать картинку и положит ее где-нить на свой винт. Потом указать путь в соотвествующем текстовом поле и нажать кнопку "загрузить". После этого файл добавится в твой личный список файлов на сервере и ты сможешь дать на него ссылку (она как раз появится на экране после загрузки). На, а далее все элементарно. Берешь ЮРЛ и помещаешь в тэк [url=]мой юрл[/url]. При этом уже в превью картинка должна быть видна.

VD>>Кстати, конструкции вроде:

VD>>
VD>>f <- frame        [text := "Bye!"]
VD>>

VD>>тоже хорошо бы объяснить.

Q>Это синтаксис языка заточенный под работу с монадами (в конечном счете для того, чтобы ввод-вывод был более красивым и понятным). Подобная конструкция означает, что с переменной f будет связано некоторое значение, в данном случае окно. frame — функция, которая его создает. В квадратных скобках список пропертей. := — на самом деле просто перегруженная функция, а не равно, которая присваивает значение соответствующему атрибуту и возвращает его в виде проперти.


Во! Это уже обяснение! Именно так и нужно.

Q>Ну правильно. Я же говорю, все очень похоже. То что есть визуальный редактор, облегчает работу, конечно, но теоретически можно и для Haskell такой написать.


ЗЫ

А вот с подменой обработчика я без объяснения врубиться не смог.

В обще, нужно взять этот бесхитросный пример и разжевать до мелочей. При этом продемонстрировать его на несколькоих языках, чтобы те кто знает один из них поняли остальные по аналогии (и объяснениям).
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[26]: Вопрос о конкретных примерах
От: Gaperton http://gaperton.livejournal.com
Дата: 11.10.04 03:10
Оценка:
Здравствуйте, prVovik, Вы писали:

V>Здравствуйте, FR, Вы писали:


FR>>В тесте с решетом я не увидел никакого жульничества, другое дело что как тест производительности он никуда ни годится.

FR>>А вообще пусть компиляторы "жульничают" при условии что выдают корректные результаты.
V>Конечно, это не плохо, это очень даже хорошо. Это говорит о качестве компиляторов, о том, что они могут оптимизировать. НО! Не стоит на основании частного случая делать общих выводов!

V>То, что компилятор Clean научен оптимизировать именно массив и только тогда, когда на него существует единственная ссылка — это, конечно, хорошо, но проблемы, которую я описал еще в посте Re[10]: Вопрос о конкретных примерах
Автор: prVovik
Дата: 02.10.04
в не решает. То есть проблемы изменения объекта, когда на него существует множество ссылок.

Компилятор Clean научен оптимизировать изменение любого объекта, тип которого помечен как unique. Если на такой объект будет больше одной ссылки, прога не скомпилируется — признак unique часть сигнатуры типа. Для того, чтобы решить твою неразрешимую "проблему", достаточно добавить этот признак к некоторым объектам и немного перекомпоновать структуру данных, и в результате удастся получить производительность сравнимую с С (не более чем в 2-3 раза медленнее с одинаковой асимптотикой) в чисто функциональной программе. Что я, так же как и Quintatar, готов показать на конкретном примере.

Без которого вся твоя "философия" — просто сотрясяние воздуха. Привел бы ты конкретный пример с самого начала — не было бы вопросов. А так — похоже на студенческий замер пиписьками.
Re[23]: Вопрос о конкретных примерах
От: Gaperton http://gaperton.livejournal.com
Дата: 11.10.04 03:23
Оценка: +1
Здравствуйте, prVovik, Вы писали:

V>Здравствуйте, Gaperton, Вы писали:


V>Наша беседа:

Поправлю.

V>Gaperton:

V>-- Гы-гы. Ацтой! Гы-гы. Ацтой! Гы-гы. Ацтой!
Поклеп и инсенуации.

V>Я:

V>-- С чем именно ты не согласем? Приведи аргументы!
Не, не так. Ты:
Ты чо, чувак, МОИ посты не читаешь, я не понял? Не понимаешь, чо за умную штуку я тут написал? Так я для тебя еще разок повторю, может тебе надоест, и ты согласишься?
А я тебе:
Нет, не понимаю, и не соглашусь.



V>Gaperton:

V>-- А мне за аргументы деньги не платят.
Ну да. Не платят ведь, и в самом деле!

V>Нормальное такое конструктивное обсуждение

Обсуждения я не заметил. Заметил, что ты споришь, а не обсуждаешь.
А по существу аргументы люди тебе привели в достаточном количестве, я расставил им плюсы, и не вижу нужды повторяться.
Re[17]: Вопрос о конкретных примерах
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.10.04 04:10
Оценка:
Здравствуйте, VladD2, Вы писали:
VD>Дык это как раз одно из самых интересных. Кому сегодня нужен язык не позволяющий создавать ГУИ?

Кстати, если верно то, что я понял об функциональных языках, то на них можно писать совершенно замечательный гуй. Только нужно отвлечься от этих дурацких Button1.Width=71.
По идее, если придумать удачное описание гуя, то всякий докинг и прочее должно очень изящно получаться. При помощи функций высшего порядка

Кстати, обрати внимание, что в MS тоже догадались, что большая часть инициализационного кода (того, что в Delphi лежало в DFM) тоже нафиг никому не упала. Существуют диздоки, которые явным образом запрещают программерам заниматься попиксельной подгонкой контролов. Вместо дурацких статичных диалогов, стандарты на которые надо пересматривать раз в 5 лет для адаптации к новым характеристикам мониторов, мы переходим к динамичным "резиновым" формам. Ну и язык разметки вместо разбрасывания контролов как коровьих лепешек на лугу превращается в задание взаимосвязей между ними. В новых WinForms есть соответствующие контролы для управления собсно алигнментом.

Так вот если я что-то в чем-то понимаю, то ФП может предоставить еще более крутые методы управления всей этой ерундой. Типа выбора алигнмента контролов на основе паттерн-матчинга и прочих всяких суперпозиций.
Вот только чтобы это придумать голову надо очень сильно извернуть.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[15]: Вопрос о конкретных примерах
От: faulx  
Дата: 11.10.04 06:04
Оценка:
Здравствуйте, VladD2, Вы писали:


VD>Так же многие тут предлагали создать более близкий к жизник пример. А то примеры уж больно оторваны от жизни. Например, интересно было бы поглядеть на то как будет выглядеть динамическая веб-страничка на одном из ФЯ.


Это не подойдет? Если верить тому, что написано здесь, это то, что нужно.
Re[17]: Вопрос о конкретных примерах
От: faulx  
Дата: 11.10.04 06:19
Оценка: :))
Здравствуйте, VladD2, Вы писали:


INT>>Имху, реальным стресс-тестом для любого языка общего назначения может быть серьезная real-time 3d графика и/или физика...


VD>Не думаю, что кто-то из здесь присуствующих способен создать подбный пример. Да и вряд ли его можно будет легко понять. Ведь как не крути это будет огромный объем кода.


VD>Но как пример того, что такие проекты возможны и есть было бы неплохо заполучить ссылку на подобное приложение


Это не подойдет? Erlang.

Вроде видел и другие ссылки, но они менее серьезные. Кое-что есть здесь, можно также поискать в Google на предмет OcamlDoom.
Re[18]: Вопрос о конкретных примерах
От: faulx  
Дата: 11.10.04 06:28
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Кстати, если верно то, что я понял об функциональных языках, то на них можно писать совершенно замечательный гуй. Только нужно отвлечься от этих дурацких Button1.Width=71.

S>По идее, если придумать удачное описание гуя, то всякий докинг и прочее должно очень изящно получаться. При помощи функций высшего порядка

S>Кстати, обрати внимание, что в MS тоже догадались, что большая часть инициализационного кода (того, что в Delphi лежало в DFM) тоже нафиг никому не упала. Существуют диздоки, которые явным образом запрещают программерам заниматься попиксельной подгонкой контролов. Вместо дурацких статичных диалогов, стандарты на которые надо пересматривать раз в 5 лет для адаптации к новым характеристикам мониторов, мы переходим к динамичным "резиновым" формам. Ну и язык разметки вместо разбрасывания контролов как коровьих лепешек на лугу превращается в задание взаимосвязей между ними. В новых WinForms есть соответствующие контролы для управления собсно алигнментом.


S>Так вот если я что-то в чем-то понимаю, то ФП может предоставить еще более крутые методы управления всей этой ерундой. Типа выбора алигнмента контролов на основе паттерн-матчинга и прочих всяких суперпозиций.

S>Вот только чтобы это придумать голову надо очень сильно извернуть.

Здесь нельзя не вспомнить о Fudgets, FranTk, а также о кое-каких любопытных статьях вроде этой или этой.
Re[19]: Вопрос о конкретных примерах
От: INTP_mihoshi Россия  
Дата: 11.10.04 08:33
Оценка:
Здравствуйте, FR, Вы писали:

FR>Полно и не read only, например динамическое заполнение вершиных и индексных буферов, по довольно замороченному алгоритму и со скоростью близкой к пропускной способности ОЗУ. И вообще общение с 3D API практически очень близко к системному программированию. Мне кажется писать именно 3D движек на функциональном языке (даже на ocaml) будет намного сложнее чем на C/C++.


Так стресс-тест и есть стресс-тест. Работа с полной отдачей. Я не специалист по 3d движкам, но насколько я понимаю, 3d engine — это, в основном, геометрия и оптимизация (по памяти, нагрузке на процессор и нагрузке на ускоритель). Т.е. масса нетривиальных алгоритмов. Самое то для проверки возможности языка, претендующего на универсальность.
Re[20]: Вопрос о конкретных примерах
От: FR  
Дата: 11.10.04 09:51
Оценка:
Здравствуйте, INTP_mihoshi, Вы писали:

INT>Здравствуйте, FR, Вы писали:


FR>>Полно и не read only, например динамическое заполнение вершиных и индексных буферов, по довольно замороченному алгоритму и со скоростью близкой к пропускной способности ОЗУ. И вообще общение с 3D API практически очень близко к системному программированию. Мне кажется писать именно 3D движек на функциональном языке (даже на ocaml) будет намного сложнее чем на C/C++.


INT>Так стресс-тест и есть стресс-тест. Работа с полной отдачей. Я не специалист по 3d движкам, но насколько я понимаю, 3d engine — это, в основном, геометрия и оптимизация (по памяти, нагрузке на процессор и нагрузке на ускоритель). Т.е. масса нетривиальных алгоритмов. Самое то для проверки возможности языка, претендующего на универсальность.


Я согласен, что это не плохой стресс тест, но объем работы слишком большой. Например типичный современный движок на С++(Ogre, Nebula 2) это 5 — 7 Mb кода.
И я не уверен что переписывание такого движка например на ocaml, существенно уменьшит его объем и сделает более простым использование.
Просто многие функциональные фишки например та же ленивость и неупорядоченность вызовов могут только помешать в системе где как раз требуется жестко выстроенные по времени вызовы.
... << RSDN@Home 1.1.3 stable >>
Re[21]: Вопрос о конкретных примерах
От: INTP_mihoshi Россия  
Дата: 11.10.04 10:50
Оценка:
Здравствуйте, FR, Вы писали:

FR>Я согласен, что это не плохой стресс тест, но объем работы слишком большой. Например типичный современный движок на С++(Ogre, Nebula 2) это 5 — 7 Mb кода.

Типичный современный — да. Но во-первых, движок — понятие растяжимое... Голый OpenGL — тоже, в некотором роде движок. Остальное нужно только чтобы иметь одновременно и приличную картинку и приличный FPS

FR>И я не уверен что переписывание такого движка например на ocaml, существенно уменьшит его объем и сделает более простым использование.

Вот и интересно бы было проверить

FR>Просто многие функциональные фишки например та же ленивость и неупорядоченность вызовов могут только помешать в системе где как раз требуется жестко выстроенные по времени вызовы.

Уже не раз говорилось, что не стоит смешивать вычисление и управление. Чисто функциональная программа может выполнять только вычисления. Управление на основе этих вычислений осуществляет всегда некоторая императивная надстройка.
Такая схема может вызывает проблемы в действительно реал-тайм системах, где требуется очень быстрая реакция.

Большая часть движка, все-таки, вычисления (например, значения и порядка вершинных и текстурных координат), а не управление.
Re[22]: Вопрос о конкретных примерах
От: FR  
Дата: 11.10.04 11:16
Оценка: 16 (1)
Здравствуйте, INTP_mihoshi, Вы писали:

INT>Здравствуйте, FR, Вы писали:


FR>>Я согласен, что это не плохой стресс тест, но объем работы слишком большой. Например типичный современный движок на С++(Ogre, Nebula 2) это 5 — 7 Mb кода.

INT>Типичный современный — да. Но во-первых, движок — понятие растяжимое... Голый OpenGL — тоже, в некотором роде движок. Остальное нужно только чтобы иметь одновременно и приличную картинку и приличный FPS

Даже (вернее особенно) не голый, а со всеми расширениями OpenGL сейчас уже не движок а скорее прямой интерфейс к аппаратуре. Если же брать DirectX в pure режиме, то это вообще тончайшая прослойка к драйверу.

FR>>И я не уверен что переписывание такого движка например на ocaml, существенно уменьшит его объем и сделает более простым использование.

INT>Вот и интересно бы было проверить

интерес может в человеко-годы вылится

FR>>Просто многие функциональные фишки например та же ленивость и неупорядоченность вызовов могут только помешать в системе где как раз требуется жестко выстроенные по времени вызовы.

INT>Уже не раз говорилось, что не стоит смешивать вычисление и управление. Чисто функциональная программа может выполнять только вычисления. Управление на основе этих вычислений осуществляет всегда некоторая императивная надстройка.

Так тут как раз может получится что прослойка сильно толще основного кода.

INT>Такая схема может вызывает проблемы в действительно реал-тайм системах, где требуется очень быстрая реакция.


так основное применение 3D движков игры, которые достаточно (насколько это возможно на не real-time OS) близки к real-time.

INT>Большая часть движка, все-таки, вычисления (например, значения и порядка вершинных и текстурных координат), а не управление.


Я же говорю алгоритмы сильно специализированны и императивны по большей части.
... << RSDN@Home 1.1.3 stable >>
Re[18]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.10.04 15:33
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Кстати, если верно то, что я понял об функциональных языках, то на них можно писать совершенно замечательный гуй. Только нужно отвлечься от этих дурацких Button1.Width=71.


Это называется ООП.

S>По идее, если придумать удачное описание гуя, то всякий докинг и прочее должно очень изящно получаться. При помощи функций высшего порядка


А это называется XAML.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[16]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.10.04 17:03
Оценка:
Здравствуйте, faulx, Вы писали:

VD>>Так же многие тут предлагали создать более близкий к жизник пример. А то примеры уж больно оторваны от жизни. Например, интересно было бы поглядеть на то как будет выглядеть динамическая веб-страничка на одном из ФЯ.


F>Это не подойдет? Если верить тому, что написано здесь, это то, что нужно.


Неоткрывается.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[17]: Вопрос о конкретных примерах
От: faulx  
Дата: 12.10.04 07:00
Оценка:
Здравствуйте, VladD2, Вы писали:

F>>Это не подойдет? Если верить тому, что написано здесь, это то, что нужно.


VD>Неоткрывается.


Странно, у меня все работает.
Re[18]: Вопрос о конкретных примерах
От: Quintanar Россия  
Дата: 12.10.04 09:10
Оценка:
Здравствуйте, faulx, Вы писали:

VD>Не думаю, что кто-то из здесь присуствующих способен создать подбный пример. Да и вряд ли его можно будет легко понять. Ведь как не крути это будет огромный объем кода.


VD>Но как пример того, что такие проекты возможны и есть было бы неплохо заполучить ссылку на подобное приложение


>Это не подойдет? Erlang.


На самом деле не открывается эта ссылка. У тебя она пустая.
Re[19]: Вопрос о конкретных примерах
От: faulx  
Дата: 12.10.04 09:33
Оценка:
Здравствуйте, Quintanar, Вы писали:

Q>Здравствуйте, faulx, Вы писали:


VD>>Не думаю, что кто-то из здесь присуствующих способен создать подбный пример. Да и вряд ли его можно будет легко понять. Ведь как не крути это будет огромный объем кода.


VD>>Но как пример того, что такие проекты возможны и есть было бы неплохо заполучить ссылку на подобное приложение


>>Это не подойдет? Erlang.


Q>На самом деле не открывается эта ссылка. У тебя она пустая.


Виноват. Wings
Re[18]: Вопрос о конкретных примерах
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.10.04 15:26
Оценка:
Здравствуйте, faulx, Вы писали:

F>>>Это не подойдет? Если верить тому, что написано здесь, это то, что нужно.


VD>>Неоткрывается.


F>Странно, у меня все работает.


Открылось. Но там же ничего скачать нельзя.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[18]: Вопрос о конкретных примерах
От: Gaperton http://gaperton.livejournal.com
Дата: 12.10.04 17:40
Оценка:
Здравствуйте, faulx, Вы писали:

F>Здравствуйте, VladD2, Вы писали:



INT>>>Имху, реальным стресс-тестом для любого языка общего назначения может быть серьезная real-time 3d графика и/или физика...


VD>>Не думаю, что кто-то из здесь присуствующих способен создать подбный пример. Да и вряд ли его можно будет легко понять. Ведь как не крути это будет огромный объем кода.


VD>>Но как пример того, что такие проекты возможны и есть было бы неплохо заполучить ссылку на подобное приложение


F>Это не подойдет? Erlang.

Поправил-бы ты ссылочку , а то зело смешно (http://Это/)

F>Вроде видел и другие ссылки, но они менее серьезные.


Особенно это
Re[19]: Вопрос о конкретных примерах
От: faulx  
Дата: 13.10.04 08:20
Оценка:
Здравствуйте, Gaperton, Вы писали:

F>>Это не подойдет? Erlang.

G>Поправил-бы ты ссылочку , а то зело смешно (http://Это/)

Борюсь с тэгами, и они пока побеждают. Я имел в виду Wings. Впрочем, в 3D-графике я не специалист, может, это и не то.
Re[20]: Вопрос о конкретных примерах
От: FR  
Дата: 13.10.04 08:59
Оценка:
Здравствуйте, faulx, Вы писали:


F>Борюсь с тэгами, и они пока побеждают. Я имел в виду Wings. Впрочем, в 3D-графике я не специалист, может, это и не то.


Не то, это просто редактор 3D моделей.
... << RSDN@Home 1.1.3 stable >>
Re[21]: Вопрос о конкретных примерах
От: Gaperton http://gaperton.livejournal.com
Дата: 13.10.04 15:22
Оценка:
Здравствуйте, FR, Вы писали:

FR>Здравствуйте, faulx, Вы писали:



F>>Борюсь с тэгами, и они пока побеждают. Я имел в виду Wings. Впрочем, в 3D-графике я не специалист, может, это и не то.


FR>Не то, это просто редактор 3D моделей.

В любом случае неважно, Erlang не подходит для таких задач. Будет слишком медленно, и никаких плюсов взамен.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.