Здравствуйте, Klapaucius, Вы писали:
K>псевдокод: K>
K>//Есть HOF без параметров, возвращающая функцию a -> b.
K>//Т.е. тип функционального значения для нее () -> (a -> b)
K>foo : a -> b
K>{
K> //...
K>}
K>//Имеем функцию высшего порядка
K>bar1(a : () -> (a -> b))
K>{
K> //...
K>}
K>bar1(foo) // передаем в bar1 функциональное значение.
K>
А как будет различаться вызов foo, если его результат никуда не передается. Например, есть запись:
_ = foo
Это что?
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>А как будет различаться вызов foo, если его результат никуда не передается. Например, есть запись: E>
E>_ = foo
E>
E>Это что?
Это уже более интересный вопрос.
Если мы предположим, что это передача функционального значения в никуда — то данный участок кода ничего не делает.
Если же мы предположим, что это вызов функции ради сайд эффекта и игнорирование возвращаемого значения — получается, что данный код что-то делает. Исходя из тех соображений, что код пишется для того, чтобы организовать какое-то вычисление, а не для того, чтобы он ничего не делал, выбираем второй вариант.
... << RSDN@Home 1.2.0 alpha rev. 774>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Здравствуйте, eao197, Вы писали:
E>Говоря об Eiffel не нужно забывать о том, что одной из целей языка является максимальная читабельность программ, которая является одним из основных факторов, облегчающих сопровождение кода.
Если это так, то фунциональная составляющая в этом языке точно провальная, так как синтаксис громоздок и неуклюж. Сравни сам. Это твой пример на Эфиле:
Здравствуйте, Klapaucius, Вы писали:
K>Собственно, именно это я и имел в виду, когда написал: K>
K>Разве только автор считал удобным синтаксически подчеркнуть разницу — а это прямое указание на то, что первоклассность функций считается в этом языке нежелательной возможностью.
In the early years of Eiffel, the language had no routine types
because having routines as distinct entities outside objects
was seen as incompatible with the OO method.
Nevertheless, it has now been accepted that routines as first
class objects are essential and the 'agents' facility has been
introduced. It has been implemented at least in part in Eiffel
Software's compiler and SmartEiffel. Other active vendors are
likely to follow.
While this feature is new and the standard is being finalised,
the core concepts, routine types and tuples for representing
the parameters and return type of a routine, are now well
understood.
An ordinary agent is created within the current object,
which provides a context and makes the facility as expressive as
higher order functions (closures) in functional programming
languages.
Т.е. агенты в Eiffel -- это непосредственный аналог HOF.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, eao197, Вы писали:
E>>Говоря об Eiffel не нужно забывать о том, что одной из целей языка является максимальная читабельность программ, которая является одним из основных факторов, облегчающих сопровождение кода.
VD>Если это так, то фунциональная составляющая в этом языке точно провальная, так как синтаксис громоздок и неуклюж. Сравни сам. Это твой пример на Эфиле: VD>
По сравнению с языком с выводом типов -- да громоздок. Но даже не в части создания агента, а в части его последующего использования, т.е. вызова. Хотя ничем не хуже, чем делегаты в D или лямбды в Nice. А уж по сравнению с C++
Однако, вопрос стоял не столько в удобстве, сколько в эквивалентности агентов функциям высшего порядка.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Klapaucius, Вы писали:
K>Здравствуйте, eao197, Вы писали:
E>>А как будет различаться вызов foo, если его результат никуда не передается. Например, есть запись: E>>
E>>_ = foo
E>>
E>>Это что?
K>Это уже более интересный вопрос. K>Если мы предположим, что это передача функционального значения в никуда — то данный участок кода ничего не делает. K>Если же мы предположим, что это вызов функции ради сайд эффекта и игнорирование возвращаемого значения — получается, что данный код что-то делает. Исходя из тех соображений, что код пишется для того, чтобы организовать какое-то вычисление, а не для того, чтобы он ничего не делал, выбираем второй вариант.
Мне кажется, что одной из задач ЯП является устранение неоднозначности конструкций и их зависимости от контекста. Причем это же не сложно в данном случае. Достаточно ввести простые правила: вызов функции/метода всегда записывается в форме f(), т.е. со скобочками. Но это нарушает такой прицип Eiffel, как Uniform Access Principle. Поэтому можно воспользоваться альтернативой: сделать специальный оператор для "взятия адреса" функции. Будет ли он ключевым словом agent, как в Eiffel или же оператором '&', как в D, уже не важно. Важно, что не будет неоднозначности.
А то ведь, может получиться как в C++:
void f()
{
A b(C);
}
что такое b?
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
K>>Разве только автор считал удобным синтаксически подчеркнуть разницу — а это прямое указание на то, что первоклассность функций считается в этом языке нежелательной возможностью.
E>Так я и не могу понять, откуда же следует этот вывод. E>Вот, кстати, в тему (http://www.faqs.org/faqs/eiffel-faq/): E>
E>LAGE: What are Eiffel agents?
E>In the early years of Eiffel, the language had no routine types
E>because having routines as distinct entities outside objects
E>was seen as incompatible with the OO method.
E>Nevertheless, it has now been accepted that routines as first
E>class objects are essential and the 'agents' facility has been
E>introduced. It has been implemented at least in part in Eiffel
E>Software's compiler and SmartEiffel. Other active vendors are
E>likely to follow.
E>While this feature is new and the standard is being finalised,
E>the core concepts, routine types and tuples for representing
E>the parameters and return type of a routine, are now well
E>understood.
E>An ordinary agent is created within the current object,
E>which provides a context and makes the facility as expressive as
E>higher order functions (closures) in functional programming
E>languages.
E>Т.е. агенты в Eiffel -- это непосредственный аналог HOF.
Во-первых, тут терминологическая путаница. HOF — это функция, которая принимает и/или возвращает функцию. Например qsort из crt можно назвать непосредственным аналогом HOF.
Поэтому агенты не непосредственный аналог HOF, но с помощью них можно получить непосредственный аналог HOF.
Во-вторых, я же с самого начала говорил, что агенты в Eiffel предназанчены для решения тех задач, которые решаются в языках с первоклассными функциями без дополнительных сущностей. Но то, что agent является объектом, это не деталь реализации, (как являющийся объектом делегат в C# 2.0) агент отличается от функции и семантически и синтаксически, и при конструировании и при вызове. Именно поэтому я и утверждаю, что функции в Eiffel не являются первоклассными объектами — первоклассными объектами являются агенты, как и экземпляры любых других классов. Но средства, позволяющие реализовать аналог HOF, в Eiffel имеются — это факт. Просто объект с одним методом и функция это не одно и то же.
Язык с fco:
foo()
f = foo
f()
Язык без fco:
foo()
а = agent foo
a.call()
Вопрос о том, какой ценой дается первоклассность функций — отдельный и к спору о классификации Eiffel, по моему мнению, отношения не имеет.
... << RSDN@Home 1.2.0 alpha rev. 774>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Здравствуйте, eao197, Вы писали:
E>Мне кажется, что одной из задач ЯП является устранение неоднозначности конструкций и их зависимости от контекста.
Согласен, что неоднозначность это плохо, но часто зависимость от контекста — это очень удобно.
Например, тип опрератора + зависит от конекста в подавляющем большинстве языков. Даже в тех, где нет перегрузки функций. Если уж на то пошло, ad hoc — полиморфизм есть зависимость от контекста по сути своей.
E>Причем это же не сложно в данном случае. Достаточно ввести простые правила: вызов функции/метода всегда записывается в форме f(), т.е. со скобочками. Но это нарушает такой прицип Eiffel, как Uniform Access Principle. Поэтому можно воспользоваться альтернативой: сделать специальный оператор для "взятия адреса" функции. Будет ли он ключевым словом agent, как в Eiffel или же оператором '&', как в D, уже не важно. Важно, что не будет неоднозначности.
Допустим, но это выбор между Uniform Access Principle и fco-функциями. Кроме того, я ведь не спорил с тем, что неоднозначность может представлять неудобство для программиста, я утверждал, что для компилятора статически и строго типизированного языка это не проблема.
... << RSDN@Home 1.2.0 alpha rev. 774>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Здравствуйте, Klapaucius, Вы писали:
E>>Т.е. агенты в Eiffel -- это непосредственный аналог HOF.
K>Во-первых, тут терминологическая путаница. HOF — это функция, которая принимает и/или возвращает функцию. Например qsort из crt можно назвать непосредственным аналогом HOF.
А то, что в C вызов функции по указателю записывается не так, как вызов обычной функции -- это не является препятствием для того, чтобы qsort считать аналогом HOF?
K>Язык с fco: K>
K>foo()
K>f = foo
K>f()
K>
K>Язык без fco: K>
K>foo()
K>а = agent foo
K>a.call()
K>
Разница всего-лишь в форме записи.
Впрочем, если форма важнее содержимого, пусть остается так.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
K>>Во-первых, тут терминологическая путаница. HOF — это функция, которая принимает и/или возвращает функцию. Например qsort из crt можно назвать непосредственным аналогом HOF. E>А то, что в C вызов функции по указателю записывается не так, как вызов обычной функции -- это не является препятствием для того, чтобы qsort считать аналогом HOF?
Для того, чтобы считать аналогом hof — не препятствие. Для того, чтобы считать hof — препятствие. Все-таки qsort получает на вход не функцию, а указатель на функцию.
E>Разница всего-лишь в форме записи.
Ну да, конечно. И здесь тоже:
foo(bar)
bar.foo()
Во-первых, разница не только в синтаксисе, но и в семантике. Я же говорю, что объект с одним методом это не то же самое, что функция. Ясно, что объект в Eiffel можно передавать по ссылке. Ну так и в Java можно по месту определить анонимный класс с одним методом. И что их этого следует? Что в Java функции первоклассные?
Во-вторых, когда речь идет о языке — форма записи это не какой-то незначительный вопрос.
... << RSDN@Home 1.2.0 alpha rev. 726>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Т>(defun foo ()...)
Т>(setq f (function foo))
Т>(funcall f)
Т>
Ну так что из этого?
Это аргумент такого же класса, как и "Я отказываюсь верить, что число 4776913109852041418248056622882488319 — простое. Мне кажется, что оно ужасно сложное! Уж во всяком случае сложнее, чем 9"
Предположим, что мы хотим сформулировать какое-то правило, по которому отличим функциональный язык, от не функционального.
Есть, на самом деле, только два способа:
1) Индуктивный. Допустим, что у нас есть некий список языков, которые мы можем априорно считать функциональными, хотя и не знаем еще, что такое "функциональный". Например, этот список возвестили нам из горящего куста. Или утвердили на всемирном симпозиуме Организации Бюрократических Наций. Теперь проанализировав все случаи из этого списка, мы получим некоторое пересечение множеств фич этих языков, сопоставление с которым поможет нам определить функциональность языка, которого нет в списке.
Тут есть сложности. Во-первых, мы можем получить что-то вроде "двуногое без перьев", а во-вторых, непонятно, откуда это априорное знание о функциональности некоторых языков? На самом деле, для определения это не проблема. Все-таки определения существуют преимущественно для коммуникации, и тут общепринятость важна, но где взять этот список общепринятых функциональных языков?
2) Дедуктивный. Мы принимаем некоторые постулаты, и выводим из них некоторые следствия. Именно так я и сделал. Ясно, что результаты могут противоречить некоторым интуитивным представлениям. Но ведь согласовать два интуитивных представления тоже проблематично.
... << RSDN@Home 1.2.0 alpha rev. 726>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Здравствуйте, Klapaucius, Вы писали:
E>>Разница всего-лишь в форме записи.
K>Ну да, конечно. И здесь тоже: K>
K>foo(bar)
K>bar.foo()
K>
Вы будете смеятся, но в Nice это совершенно одно и то же.
И в D в некоторых случаях так же.
K>Во-первых, разница не только в синтаксисе, но и в семантике. Я же говорю, что объект с одним методом это не то же самое, что функция. Ясно, что объект в Eiffel можно передавать по ссылке. Ну так и в Java можно по месту определить анонимный класс с одним методом. И что их этого следует? Что в Java функции первоклассные?
Вообще-то, анонимный класс в Java как раз таки будет классом, со своим родительским классом и прочими атрибутами. В частности, для объекта этого класса можно определить его тип, базовый тип и т.д., выполнять приведение и прочее.
А вот агент в Eiffel -- это не объект.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Klapaucius, Вы писали:
E>>Разница всего-лишь в форме записи.
K>Ну да, конечно. И здесь тоже: K>
K>foo(bar)
K>bar.foo()
K>
эквивалентность этих двух синтаксисов, кстати, хотят ввести в будущих версиях С++ (в смысле, чтоб первое приводило к вызову второго).
K>Во-первых, разница не только в синтаксисе, но и в семантике. Я же говорю, что объект с одним методом это не то же самое, что функция. Ясно, что объект в Eiffel можно передавать по ссылке. Ну так и в Java можно по месту определить анонимный класс с одним методом. И что их этого следует? Что в Java функции первоклассные? K>Во-вторых, когда речь идет о языке — форма записи это не какой-то незначительный вопрос.
А если этот метод имеет синтаксис вызова функции (как operator() в С++)?
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, Klapaucius, Вы писали:
E>>>Разница всего-лишь в форме записи.
K>>Ну да, конечно. И здесь тоже: K>>
K>>foo(bar)
K>>bar.foo()
K>>
E>Вы будете смеятся, но в Nice это совершенно одно и то же. E>И в D в некоторых случаях так же.
Плюс ещё в Скале подобная фишка, правда там нужен метод apply у класса для "закоса под функцию". Т.е. семантически класс с apply и функция есть одно и то же.
По-моему это вообще базовая фишка языков, которые допускают смешивание ФП и ООП.
BTW А в Немерле разве это нетак?
Здравствуйте, Klapaucius, Вы писали:
K>Ну так что из этого? K>Это аргумент такого же класса, как и "Я отказываюсь верить, что число 4776913109852041418248056622882488319 — простое. Мне кажется, что оно ужасно сложное! Уж во всяком случае сложнее, чем 9"
Нет, это аргумент такого же класса, как и "Я отказываюсь считать, что число 4776913109852041418248056622882488319 — простое, а число 0x397FFFFFFFFFFFFFFFFFFFFFFFFFFFF — нет".
K>Мы принимаем некоторые постулаты, и выводим из них некоторые следствия.
Можно, конечно, делать и так. Но если результаты противоречат интуитивным представлениям, то получившийся термин будет иметь мало общего с исходным понятием.
Здравствуйте, eao197, Вы писали:
E>>>Разница всего-лишь в форме записи. K>>Ну да, конечно. И здесь тоже: K>>
K>>foo(bar)
K>>bar.foo()
K>>
E>Вы будете смеятся, но в Nice это совершенно одно и то же. E>И в D в некоторых случаях так же.
Не буду. В мультипарадигменном Nice первое сделано для поддержки ФП, а второе для поддержки ООП. Но речь не идет о том, что можно, а о том, что нельзя. В C# 2.0 тоже можно повсеместно оборачивать функцию в делегат явным образом, но ведь можно этого и не делать. А в Eiffel нельзя.
K>>Во-первых, разница не только в синтаксисе, но и в семантике. Я же говорю, что объект с одним методом это не то же самое, что функция. Ясно, что объект в Eiffel можно передавать по ссылке. Ну так и в Java можно по месту определить анонимный класс с одним методом. И что их этого следует? Что в Java функции первоклассные? E>Вообще-то, анонимный класс в Java как раз таки будет классом, со своим родительским классом и прочими атрибутами. В частности, для объекта этого класса можно определить его тип, базовый тип и т.д., выполнять приведение и прочее. E>А вот агент в Eiffel -- это не объект.
Почему? Для того, чтобы быть объектом не нужно вообще-то иметь тип. Хотя тип у агента есть, не говоря уже о базовом классе.
Агент передается по правилам для объектов, у него есть метод call, который вызывается по правилам для объектов — я вижу семантику объекта. Если вызов функции через агент выглядит как вызов метода объекта, а не как вызов функции, почему агент следует считать функцией?
... << RSDN@Home 1.2.0 alpha rev. 774>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Здравствуйте, jazzer, Вы писали:
K>>Во-первых, разница не только в синтаксисе, но и в семантике. Я же говорю, что объект с одним методом это не то же самое, что функция. Ясно, что объект в Eiffel можно передавать по ссылке. Ну так и в Java можно по месту определить анонимный класс с одним методом. И что их этого следует? Что в Java функции первоклассные? K>>Во-вторых, когда речь идет о языке — форма записи это не какой-то незначительный вопрос. J>А если этот метод имеет синтаксис вызова функции (как operator() в С++)?
Значит это шаг в направлении первоклассности функции.
... << RSDN@Home 1.2.0 alpha rev. 774>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll