eao197 wrote:
> Здравствуйте, dr.Chaos, Вы писали: > >>> Нет не предмет. Для вас. Поскольку вы считаете, что раз в Nice что-то >>> называется функцией, значит это функция. А если это же самое называется >>> в другом языке делегатом, то это не функция. >>> >>> Хотя разницу между ними найти лично мне очень тяжело. > > ИМХО эта разница примерно такая же, как между переменной и ссылкой на > неё. В С++ это две разные сущности, хотя и могут применяться для > решения одной и той же задачи. > > Я бы уточнил: разница как между объектом и ссылкой на него в таких языках, > как Java/C#/D и др. Объект живет сам по себе, но обратиться к нему можно > только через ссылку. И переменные в таких языках содержат не объекты, а > ссылки на них.
Это уточнение меняет смысл моей фразы . Т.к. в этих языках сущность одна,
а то что там есть ссылка, дык это деталь реализации.
> DC>Мне не понятно во что ты упёрся. Ведь в Ди делегат и функция две разных > DC>сущности, а в Nice есть только функция. > > Вот именно в это и уперся. Поскольку в таких языках, как D и Nice функция > -- это блок кода, реализующий функцию. Вызвать этот блок можно двумя > способами: либо написав в коде обращение функции через ее имя > (непосредственный вызов), либо получив ссылку на функцию. Но что такое > ссылка? Это указатель на сам код + некий контекст, на котором этот код > будет работать.
[skip]
Это особенность платформы. В Java, всё есть объект и трындец. Просто в Nice
эту особенность сделали, судя по твоим примерам, максимально незаметной.
> Т.е. разница в том, что в D ссылки на функции называются делегатами, а в > Nice они называются функциями.
Делегат это не функция . В Ди связка делегат+функция дают возможность
работать с функциями как с FCO. В Nice для этого достаточно лишь понятия
функции или функционального типа. В Ди есть функциональный тип?
> Т.е. дело только в названии.
ЗЫ Ну дык и спор то терминологический.
Posted via RSDN NNTP Server 2.1 beta
Побеждающий других — силен,
Побеждающий себя — Могущественен.
Лао Цзы
Здравствуйте, dr.Chaos, Вы писали:
>> Я бы уточнил: разница как между объектом и ссылкой на него в таких языках, >> как Java/C#/D и др. Объект живет сам по себе, но обратиться к нему можно >> только через ссылку. И переменные в таких языках содержат не объекты, а >> ссылки на них.
DC>Это уточнение меняет смысл моей фразы . Т.к. в этих языках сущность одна, DC>а то что там есть ссылка, дык это деталь реализации.
От этой детали много чего зависит. Например, нельзя получить ссылку на переменную.
DC>Делегат это не функция . В Ди связка делегат+функция дают возможность DC>работать с функциями как с FCO. В Nice для этого достаточно лишь понятия DC>функции или функционального типа. В Ди есть функциональный тип?
Не, ну сколько можно!
В Nice функциональный тип описывается как (A)->V, а в D как V delegate(A). Все остальное одно и то же.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>вы считаете, что раз в Nice что-то называется функцией, значит это функция. А если это же самое называется в другом языке делегатом, то это не функция.
E>Хотя разницу между ними найти лично мне очень тяжело.
Давайте попробуем вместе.
Вы утверждали, что & ставится для устранения неопределенности между вызовом и возвратом функционального значения.
Если мы имеем переменную со знаачением — делегатом — ситуация с неопределенностью в точности такая же, нес па?
Проделаем небольшой опыт. Я написал примеры на псевдо-D (я не знаю D и, вполне вероятно, допустил ошибки, надеюсь, что идея в каждом случае ясна):
Пример 1
T delegate(T a) foo(T)()
{
T Id(T a)
{
return a;
}
return&Id; // в случае с Id неопределенность между вызовом и возвратом функции была бы возможна,
// если бы Id была функцией без параметров, зачем здесь уточнение непонятно, ну да ладно.
}
Пример 2
T delegate(T a) foo(T)()
{
T delegate(T) id = (T a){return a;};
return id; // в случае с id неопределенность между вызовом и возвратом функции была бы возможна и т.д.
// ВОПРОС: сработает ли это без & ?
}
Пример 3
T delegate() foo(T)()
{
T bar()
{
// ничего не делается
}
return&bar; // в случае с bar неопределенность между вызовом и возвратом функции.
}
Пример 4
T delegate(T a) foo(T)()
{
T delegate(T) bar = T delegate(){return a;};
return bar; // в случае с bar неопределенность между вызовом и возвратом функции.
// ВОПРОС: сработает ли это без & ?
}
Если второй и четвертый примеры также требуют указания & — значит вы правы и & — просто указание для разрешения противоречия между вызовом и возвратом, если нет — значит прав я: делегат и функция — разные вещи не только на уровне реализации, но и на уровне языка.
... << 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
K>>>>interface IAgent<T, U, V>
K>>>>{
K>>>> V call(T a, U b);
K>>>>}
K>>>>
K>>>>Такой же "функциональный тип" как и агент — ничуть не хуже. Более громоздкий синтаксис при оборачивании функции — да. Но факт явного оборачивания в обоих случаях — налицо. Использование вообще ничем не отличается. E>>>Попробуйте передать реализацию этого интерфейса в конструктор TreeMap или в метод Arrays.sort вместо Comparator-а. K>>Я показал, как делаются агенты в Java — то что стандартная библиотека их сейчас не поддерживает — другой вопрос. E>Знаете, чем отличается математика от программирования? Это в математике можно показать способ решения какого-то класса задач и считать эту задачу решенной, а все остальное -- другой вопрос. В программировании мало показать способ -- нужно написать _работающую_ программу -- без программы нет решения. И это не другой -- это самый важный вопрос.
В огороде бузина — а в Киеве дядька. Допустим, что вопрос самый важный — но тем не менее другой. Факт, что у Java нет Map, Fold, Filter и "функциональных типов" в стандартной библиотеке, а если бы и были — пользоваться ими было бы не очень удобно из-за перегруженности синтаксиса анонимных классов. С практической точки зрения это имеет значение.
Тем не менее, в свете ваших заявлений о том, что надо смотреть не на "форму" (синтаксис?) а на "содержание" (семантику?) вопросы остаются.
Какая разница между агентом и анонимным классом с одним методом кроме синтаксической?
... << 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, Вы писали:
K>Если второй и четвертый примеры также требуют указания & — значит вы правы и & — просто указание для разрешения противоречия между вызовом и возвратом, если нет — значит прав я: делегат и функция — разные вещи не только на уровне реализации, но и на уровне языка.
Думаю, что по отношению к D это не совсем так, поскольку, как я говорил dr.Chaos, в Java нельзя получить ссылку на переменную, а вот в D можно. И использование &id или &bar во втором и четвертом примерах означало бы взятие адреса переменных id и bar.
Корректно ваш пример на D записывается следующим образом:
T delegate(T a) foo1(T)()
{
T Id(T a)
{
return a;
}
return &Id;
}
T delegate(T a) foo2(T)()
{
T delegate(T) id = (T a) { return a; };
return id;
}
T delegate() foo3(T)()
{
T bar() { return T.init; }
return &bar;
}
T delegate(T a) foo4(T)()
{
T delegate(T) bar = delegate T(T a) { return a; };
return bar;
}
void main()
{
auto f1 = foo1!(int)();
auto f2 = foo2!(int)();
auto f3 = foo3!(int)();
auto f4 = foo4!(int)();
}
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Klapaucius, Вы писали:
K>Тем не менее, в свете ваших заявлений о том, что надо смотреть не на "форму" (синтаксис?) а на "содержание" (семантику?) вопросы остаются. K>Какая разница между агентом и анонимным классом с одним методом кроме синтаксической?
Агент может получать ссылку на уже реализованный в каком-то классе метод. Например:
agent my_object.some_method
Тогда как при инстанциировании анонимного класса нужно делать вызов этого метода явно внутри самостоятельно реализованного метода call:
new Agent { public void call() { myObject.some_method(); } };
Т.е. здесь программиста заставляют сделать две вещи: определить метод call() и самостоятельно написать вызов some_method. Тогда как в агенте указывается только какой метод должен вызываться.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
K>>Если второй и четвертый примеры также требуют указания & — значит вы правы и & — просто указание для разрешения противоречия между вызовом и возвратом, если нет — значит прав я: делегат и функция — разные вещи не только на уровне реализации, но и на уровне языка. E>Думаю, что по отношению к D это не совсем так, поскольку, как я говорил dr.Chaos, в Java нельзя получить ссылку на переменную, а вот в D можно. И использование &id или &bar во втором и четвертом примерах означало бы взятие адреса переменных id и bar.
Ну вот, значит & вовсе не является элементом синтаксиса для разрешения противоречия, ведь в случае
T delegate(T a) foo4(T)()
{
T delegate(T) bar = delegate T(T a) { return a; };
return bar;
}
компилятор принимает решение о том, что нужно возвращать делегат, а не вызывать функцию без параметров bar по сведеньям о типах, которые у него есть.
Как я и предполагал — делегат и функция — разные сущности и на уровне языка делегат это "ссылка на функцию" (пусть и с неявным контекстом), причем сходство с ссылкой на переменную подчеркивается.
Что касается примера с явой — там нет ссылки, как отдельной сущности — там есть ссылочные типы. А в D — ссылка это отдельная сущность. Точно также и делегат — сущность отдельная.
Можно сделать следующие выводы:
1) Функция и делегат разные сущности
2) Различается не только синтаксис, но и семантика.
... << 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, Вы писали:
K>>Какая разница между агентом и анонимным классом с одним методом кроме синтаксической? E>Агент может получать ссылку на уже реализованный в каком-то классе метод. Например: E>
E>agent my_object.some_method
E>
E>Тогда как при инстанциировании анонимного класса нужно делать вызов этого метода явно внутри самостоятельно реализованного метода call: E>
E>Т.е. здесь программиста заставляют сделать две вещи: определить метод call() и самостоятельно написать вызов some_method. Тогда как в агенте указывается только какой метод должен вызываться.
И это, по-вашему, разница по форме или по содержанию?
... << 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, Вы писали:
K>>>Какая разница между агентом и анонимным классом с одним методом кроме синтаксической? E>>Агент может получать ссылку на уже реализованный в каком-то классе метод. Например: E>>
E>>agent my_object.some_method
E>>
E>>Тогда как при инстанциировании анонимного класса нужно делать вызов этого метода явно внутри самостоятельно реализованного метода call: E>>
E>>Т.е. здесь программиста заставляют сделать две вещи: определить метод call() и самостоятельно написать вызов some_method. Тогда как в агенте указывается только какой метод должен вызываться.
K>И это, по-вашему, разница по форме или по содержанию?
По содержанию.
Вызов f() вместо f.call() -- это синтаксический сахар.
Но вот инструкция agent вместо ручного инстанцирования интерфейса -- это уже не синтаксический сахар.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Klapaucius, Вы писали:
K>Как я и предполагал — делегат и функция — разные сущности и на уровне языка делегат это "ссылка на функцию" (пусть и с неявным контекстом), причем сходство с ссылкой на переменную подчеркивается. K>Что касается примера с явой — там нет ссылки, как отдельной сущности — там есть ссылочные типы. А в D — ссылка это отдельная сущность. Точно также и делегат — сущность отдельная. K>Можно сделать следующие выводы: K>1) Функция и делегат разные сущности K>2) Различается не только синтаксис, но и семантика.
Как я уже говорил, в языках типа D, Java, Nice функция -- это блок кода, который можно либо вызвать непосредственно, либо получить на него ссылку. Следовательно, любые переменные, которые ссылаются на функции -- это ссылки на функции, со своей семантикой. И ссылки не являются функциями. Только в D ссылки называются делагатами, а в Nice -- функциями. Но семантика ссылок сохраняется. И вот пример в подтверждение:
void main( String[] args )
{
int inc( int a ) = a + 1;
int dec( int a ) = a - 1;
(int)?->int f = inc;
f = null;
f = dec;
}
Конструкция (int)?->int описывает ссылку на функцию (int)->int, которая может быть нулевой. И вы можете увидеть в примере, как переменной f присваивается null.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Klapaucius, Вы писали:
K>Снова повторяю, то, что делегат — сущность первоклассная я не отрицал, не отрицаю и отрицать не собираюсь. Функция же — сущность не первоклассная — вернуть ее из функции нельзя. K>Если бы можно было написать так: K>
K> V finalResult( U b )
K> {
K> return func( a, b );
K> }
K>return finalResult;
K>
K>Было бы очевидно, что функцию вернуть можно. K>Тем не менее, ее приходится явным образом оборачивать в делегат, который, естественно, можно вернуть: K>
K>return&finalResult;
K>
Вопрос, видимо, сводиться к тому, что, собственно, такое функция. Попробую определить функцию как нечто(некий черный ящик, к которому можно обратиться), что может быть вызвано с передачей параметров и возвращающее какое-то значение.
int f(int x, double y)
{
return 1;
}
f — это функция. Вопрос в том, является ли &f тоже функцией, можно ли делать, например, так: z=(&f)(1,1.0) ?
return &f;
Это можно интерпретировать так
return& f;
Т.е. для возвращения ф-ии необходим оперетор "return&"
Аналогично
f2 =& f;
Для присваивания функций нужен оперетор "&=".
f3(&f);
Даже здесь происходит неявное присваивание "=&" параметру ф-ии f3.
Т.е. ф-ии в С тоже первокласные, только для их использования нужны специальные операторы
Здравствуйте, eao197, Вы писали:
E>Как я уже говорил, в языках типа D, Java, Nice функция -- это блок кода, который можно либо вызвать непосредственно, либо получить на него ссылку. Следовательно, любые переменные, которые ссылаются на функции -- это ссылки на функции, со своей семантикой. И ссылки не являются функциями. Только в D ссылки называются делагатами, а в Nice -- функциями. Но семантика ссылок сохраняется.
В Nice ссылка не называется функцией. Ссылки как отдельной сущности в Nice (как и в Java), насколько я понимаю, нет. Просто функциональный тип — это ссылочный тип. и семантика у него — семантика ссылочного типа.
Если бы функция в D была первоклассной, функциональный объект, представляющий из себя функцию и замыкание можно было бы передать не только по ссылке, но и копированием, не так ли?
... << 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
Спасибо, что все-таки ответили
Тогда я полностью разделяю вашу точку зрения.
Есть два возможных варианта:
1. foo — определение функции и тогда то, что foo также является объектом, уже роли никакой не играет. С ней можно обращаться как с любым объектом, т.е. она является первоклассной сущностью, в отличие от функций в Д, где их надо оборачивать в объект-делегат.
2. foo — определение не функции, а объекта, просто выглядящее, как определение функции. Тогда придется утверждать, что в Nice вообще нет функций, их роль выполняют объекты, а спор переходит уже в исключительно терминологический. Мне этот вариант кажется неприемлемым, потому что даже если это определение объекта, то как минимум с методом Тогда что такое метод?
Если вы пропустите скомпилированный код через jad, то увидите, что конструкции f.getClass и foo.getClass применяются не к функциям, а к специальным объектам, которые Nice создает для хранения ссылок на эти функции.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Klapaucius, Вы писали:
K>Здравствуйте, eao197, Вы писали:
E>>Как я уже говорил, в языках типа D, Java, Nice функция -- это блок кода, который можно либо вызвать непосредственно, либо получить на него ссылку. Следовательно, любые переменные, которые ссылаются на функции -- это ссылки на функции, со своей семантикой. И ссылки не являются функциями. Только в D ссылки называются делагатами, а в Nice -- функциями. Но семантика ссылок сохраняется.
K>В Nice ссылка не называется функцией. Ссылки как отдельной сущности в Nice (как и в Java), насколько я понимаю, нет.
Переменная, ссылающаяся на ссылочный тип или аргумент функции, ссылающийся на ссылочный тип, или атрибут класса, ссылающийся на ссылочный тип -- это все ссылки. Как в Nice, так и в Java.
K>Просто функциональный тип — это ссылочный тип. и семантика у него — семантика ссылочного типа.
Мне, вероятно, нужно еще многому учиться, чтобы понять, что функция может иметь прототип (int)->int, но не иметь тела, а быть null-ом.
Что так может быть с ссылкой, я понимаю. А вот что так может быть с функциями...
K>Если бы функция в D была первоклассной, функциональный объект, представляющий из себя функцию и замыкание можно было бы передать не только по ссылке, но и копированием, не так ли?
Если бы функция в Nice была первоклассной, функциональный объект, представляющий из себя функцию и замыкание можно было бы передать не только по ссылке, но и копированием, не так ли?
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, VoidEx, Вы писали:
VE>Есть два возможных варианта: VE>1. foo — определение функции и тогда то, что foo также является объектом, уже роли никакой не играет. С ней можно обращаться как с любым объектом, т.е. она является первоклассной сущностью, в отличие от функций в Д, где их надо оборачивать в объект-делегат. VE>2. foo — определение не функции, а объекта, просто выглядящее, как определение функции. Тогда придется утверждать, что в Nice вообще нет функций, их роль выполняют объекты, а спор переходит уже в исключительно терминологический. Мне этот вариант кажется неприемлемым, потому что даже если это определение объекта, то как минимум с методом Тогда что такое метод?
Посмотрите на то, во что компилятор Nice превращает код по работе с функциями и ссылками на функции, например, вот здесь
.
Там видно, что непосредственный вызов функции происходит совсем не так, как вызов через ссылку. Отличие Nice от D в том, что в Nice ссылки на функции генерируются неявно. Что не столько достоинство языка или показатель его функциональной оринтированности, сколько проявление непоследовательности, поскольку эквивалентные конструкции в Nice приводят к разным результатам. Так, в Nice:
class A {
void f() {}
void demo() {
f; // Это ссылка на функцию.this.f; // Это вызов функции.
}
}
Хотя казалось бы, в чем разница?
В то же время, в таких языках, как D или Eiffel обе эти конструкции означают одно и то же, что и ожидается.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
. E>Там видно, что непосредственный вызов функции происходит совсем не так, как вызов через ссылку. Отличие Nice от D в том, что в Nice ссылки на функции генерируются неявно. Что не столько достоинство языка или показатель его функциональной оринтированности, сколько проявление непоследовательности, поскольку эквивалентные конструкции в Nice приводят к разным результатам. Так, в Nice: E>
E>class A {
E> void f() {}
E> void demo() {
E> f; // Это ссылка на функцию.
E> this.f; // Это вызов функции.
E> }
E>}
E>
E>Хотя казалось бы, в чем разница? E>В то же время, в таких языках, как D или Eiffel обе эти конструкции означают одно и то же, что и ожидается.
Хм... Ну если компилятор неявно преобразовывает, то тут без ответа автора языка не обойтись. Реализация, конечно, важна, но чисто формально неявное преобразование и эквивалентность вещи разные. Возможно, там имеется ввиду именно то, что функция является объектом, а ее неявное преобразование — деталь реализации, а возможно и нет. Может, это и правда неявное преобразование.
Без ответа автора надо лишь искать различие в поведении с обычными объектами. Если никак не различимо, то тут неважно, как оно в реализации, но, видимо, код, приведенный вами, для других объектов будет означать уже одно и то же.
Но тут действительно непоследовательность, одно от другого по логике не должно отличаться. Даже если представить, что функция также является объектом, то что такое { f } должно определяться как-то однозначно, то ли ее вызов, то ли она сама (ссылка на нее, если угодно). Это уже, по-моему, такие тонкости, что не разберешь. Ибо в любом случае, если функция есть объект, как-то надо различать, "берем" мы этот объект, или вызываем его как функцию, может, это один из способов.
Здравствуйте, VoidEx, Вы писали:
E>>В то же время, в таких языках, как D или Eiffel обе эти конструкции означают одно и то же, что и ожидается.
VE>Хм... Ну если компилятор неявно преобразовывает, то тут без ответа автора языка не обойтись.
Автор языка уже давно раставил все точки над i. У него в каждом исходном файле компилятора написано:
/**************************************************************************/
/* N I C E */
/* A high-level object-oriented research language */
Ни о какой функциональности речи нет
Вопрос ему можно задать, но часто от него ответов приходится ждать по нескольку недель. Видимо так же давно потерял мотивацию.
VE>Но тут действительно непоследовательность, одно от другого по логике не должно отличаться. Даже если представить, что функция также является объектом, то что такое { f } должно определяться как-то однозначно, то ли ее вызов, то ли она сама (ссылка на нее, если угодно).
Я по ходу этой дискуссии попробовал получить в качестве функции метод объекта в Nice -- и не нашел как. Т.е., в случае со свободной функцией:
int inc( int a ) = a + 1;
void main( String[] args ) {
let f = inc;
}
f -- это всегда (int)->int. Но в случае с объектом:
class A {
int inc( int a ) = a + 1;
}
void main( String[] args ) {
let o = new A();
let f = o.f;
}
o.f -- это всегда вызов функции (хотя казалось бы, что в функциональном языке это должно было бы означать взятие ссылки на метод). И данный пример не скомпилируется, поскольку o.f требует аргумент. В то же время в D и Eiffel превращение метода объекта в делегат/агент опроисходит обычным образом.
Имхо, все это свидетельсво того, что Nice просто еще не доработан. Все-таки версия 0.9.13, не 1.0. И, возможно, будь он доработан до более-менее логичного поведения с функциями/методами, он бы не сильно отличался от D и Eiffel-я.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
K>>В Nice ссылка не называется функцией. Ссылки как отдельной сущности в Nice (как и в Java), насколько я понимаю, нет. E>Переменная, ссылающаяся на ссылочный тип или аргумент функции, ссылающийся на ссылочный тип, или атрибут класса, ссылающийся на ссылочный тип -- это все ссылки. Как в Nice, так и в Java.
Разница между языком со ссылками и языком со ссылочными типами в данном случае в том, что в первом можно и нужно явно указывать способ передачи — по ссылке или по значению, а во втором это определяется свойствами типа.
Можно ли в D передать объект по значению? Или только по ссылке?
И да, кстати, является ли тип RT delegate(T) типом всех видов функций T->RT в D (т.е. экземплярных, статических, свободных)?
... << 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