Здравствуйте, eao197, Вы писали:
E>А вы бы могли сформулировать определение "полный человек"? А "толстый человек"? E>Между тем люди используют эти определения, понимают друг друга и редко нуждаются в математической формулировке этого критерия.
E>Свой критерий я уже давно высказал, он был мной позаимствован у Страуструпа: язык можно считать поддерживающим некую парадигму, если он позволяет писать с использованием этой парадигмы без особых усилий. Да, критерий настолько же субъективный, как и критерии оценки "полноты" людей. Но я и не ставил перед собой задачи создания периодической системы языков и занесения языка Nice в одну из ее ячеек.
Проблема определения "полный человек" в том, что разные люди проведут границу между "полный" и "вмеру упитанный" в разных точках на оси упитанности. Однако, все согласятся друг с другом, если нужно будет выбрать кто из двух людей упитаннее, начиная с некоторого интервала между ними на оси упитанности. Именно это и позволяет пользоваться определением.
С "особыми усилиями" дело обстоит гораждо хуже. Проблема не только в том, что разные люди разойдутся во мнении какие усилия считать особыми, а какие ординарными. Проблема возникнет также и с тем, что Петя будет без особых усилий программировать функционально на языке Блаблабла, и с особыми на языке Траляля. В то время как Вася, наоборот, без особых на Траляля и с особыми на Блаблабла.
Т.е. мы имеем дело с необъективностью следующего порядка.
... << 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 для функций неопределенность разрешается явным указанием foo и &foo, а для делегатов foo() и foo соответственно. E>>Потому, что &foo для делегата будет означать указатель на делегата. Ведь делегат -- это первоклассный объект. А значит для него можно получить указаль в D, так же, как для объекта, экземпляра типа int и т.д.
K>C делегатом все ясно. Непонятно почему для функции нельзя сделать foo() и foo.
Если речь о том, что foo() является вызовом, а foo -- получением ссылки на функцию, то тогда нарушится uniform access principle. Ведь тогда вызов любой функции/метода должен сопровождаться указанием (), а это ухудшает сопровождение программ, когда атрибут заменяется методом-getter-ом или наоборот. Например, было:
class Demo {
public int priority;
...
}
auto d = new Demo();
writefln( d.priority );
а затем стало:
class Demo {
public int priority() { return ... };
...
}
auto d = new Demo();
writefln( d.priority );
Изменения касаются только класса, но не кода, который использует этот класс. В C++, например, методы всегда вызываются через () и заменить атрибут методом-getter-ом в C++ сложнее, чем в D -- слишком много кода от этого изменения зависят.
K>Вообще неудобно, что функция непосредственно используется иначе, чем через делегат — т.е. одинаковые семантически вещи выглядят в коде различно,
Для функций с аргументами использование не отличается.
Различия проявляются только с функциями без аргументов. Однако, в Nice существует такая же дилема при использовании функционального типа:
{
f = () => {}; // ()->void;
f; // всегда ()->void.
f(); // всегда вызов f."hello".length; // всегда вызов length, даже без ()."hello".length(); // то же самое.
}
Имхо, в нормальных функциональных языках функции без аргументов -- это вообще скорее исключение из правил, чем норма. Ведь результат функции должен зависеть только от аргументов функции и функция при одинаковых значениях аргументов должна возвращать одинаковое значение (функция в математическом смысле, без побочных эффектов). Следовательно, при отсутствии аргументов функция должна вырождаться в константу. А посему я не знаю, бывают ли в "нормальных" функциональных языках функции без параметров (насколько я помню, то при чтении документации по OCaml я таких не видел).
K>а разные вроде указателя и делегата похоже.
Если принять точку зрения, что делегат является аналогом указателя, то все станет на свои места.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Klapaucius, Вы писали:
K>С "особыми усилиями" дело обстоит гораждо хуже. Проблема не только в том, что разные люди разойдутся во мнении какие усилия считать особыми, а какие ординарными. Проблема возникнет также и с тем, что Петя будет без особых усилий программировать функционально на языке Блаблабла, и с особыми на языке Траляля. В то время как Вася, наоборот, без особых на Траляля и с особыми на Блаблабла. K>Т.е. мы имеем дело с необъективностью следующего порядка.
При большом количестве использующих язык программистов накопится достаточная статистика для того, чтобы считать какие-то усилия "особыми", а какие-то "ординарными". Соответственно, язык приобритет репутацию "функционального" или не приобритет ее.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
K>>C делегатом все ясно. Непонятно почему для функции нельзя сделать foo() и foo. E>Если речь о том, что foo() является вызовом, а foo -- получением ссылки на функцию, то тогда нарушится uniform access principle. Ведь тогда вызов любой функции/метода должен сопровождаться указанием (), а это ухудшает сопровождение программ, когда атрибут заменяется методом-getter-ом или наоборот. Например, было: E>
E>class Demo {
E> public int priority;
E> ...
E>}
E>auto d = new Demo();
E>writefln( d.priority );
E>
E>а затем стало: E>
E>class Demo {
E> public int priority() { return ... };
E> ...
E>}
E>auto d = new Demo();
E>writefln( d.priority );
E>
E>Изменения касаются только класса, но не кода, который использует этот класс.
Зато если сначала был геттер, а его сменили на публичное поле — сломается весь код, в котором создавался и использовался делегат для геттера. Кроме того, для доступа к функции через делегат этот uniform access principle все равно не выполняется.
E>Различия проявляются только с функциями без аргументов. Однако, в Nice существует такая же дилема при использовании функционального типа: E>
E>{
E> f = () => {}; // ()->void;
E> f; // всегда ()->void.
E> f(); // всегда вызов f.
E> "hello".length; // всегда вызов length, даже без ().
E> "hello".length(); // то же самое.
E>}
E>
Учитывая, что "hello".length — сахар для length("hello") тут все вполне логично.
Хуже другое — такая логика работает только в одну сторону:
class A {
int inc(int a ) = a + 1;
}
void main( String[] args ) {
let o = new A();
let i = o.inc(1);
let i2 = inc(o, 1); // так должно работать.
let f = inc;
let j = f(o, 1);
let j2 = o.f(1); // так тоже должно, но не работает.
println(i == j);
}
Вот это для меня оказалось неожиданностью.
E>Имхо, в нормальных функциональных языках функции без аргументов -- это вообще скорее исключение из правил, чем норма. Ведь результат функции должен зависеть только от аргументов функции и функция при одинаковых значениях аргументов должна возвращать одинаковое значение (функция в математическом смысле, без побочных эффектов). Следовательно, при отсутствии аргументов функция должна вырождаться в константу. А посему я не знаю, бывают ли в "нормальных" функциональных языках функции без параметров (насколько я помню, то при чтении документации по OCaml я таких не видел).
В "нормальных" функциональных языках "константа" это, в общем-то и есть функция без параметров.
K>>а разные вроде указателя и делегата похоже. E>Если принять точку зрения, что делегат является аналогом указателя, то все станет на свои места.
До того, как в 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
Здравствуйте, eao197, Вы писали:
E>При большом количестве использующих язык программистов накопится достаточная статистика для того, чтобы считать какие-то усилия "особыми", а какие-то "ординарными". Соответственно, язык приобритет репутацию "функционального" или не приобритет ее.
При таком подходе, функциональность языков вроде Nice принципиально непозноваема. Не смотря на это, вы уверенно вынесли суждение о функциональности Nice, хотя большое количество программистов Nice не использует, и с очень хорошей вероятностью использовать не будет.
... << 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>Здравствуйте, eao197, Вы писали:
E>>При большом количестве использующих язык программистов накопится достаточная статистика для того, чтобы считать какие-то усилия "особыми", а какие-то "ординарными". Соответственно, язык приобритет репутацию "функционального" или не приобритет ее.
K>При таком подходе, функциональность языков вроде Nice принципиально непозноваема. Не смотря на это, вы уверенно вынесли суждение о функциональности Nice,
Я вынес это суждение после того, как попробовал поработать на Nice. Мне показалось, что работа на нем мало отличается от работы на D или Eiffel. В отличии от, например, Scala или OCaml, которые заставляют программировать в ином ключе.
Так что, если я составлял на тот момент значительную часть от программирующих на Nice программистов, то...
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Klapaucius, Вы писали:
K>Зато если сначала был геттер, а его сменили на публичное поле — сломается весь код, в котором создавался и использовался делегат для геттера.
Это все равно гораздо лучше того, что есть в С++ и, насколько я помню, в Java.
K>Кроме того, для доступа к функции через делегат этот uniform access principle все равно не выполняется.
А uniform access principe распространяется не на работу с методами объекта, а на работу с атрибутами объекта. Т.е. благодоря этому принципу нет разницы между o.f и o.f, если f является атрибутом или методом-геттером.
E>>Различия проявляются только с функциями без аргументов. Однако, в Nice существует такая же дилема при использовании функционального типа: E>>
E>>{
E>> f = () => {}; // ()->void;
E>> f; // всегда ()->void.
E>> f(); // всегда вызов f.
E>> "hello".length; // всегда вызов length, даже без ().
E>> "hello".length(); // то же самое.
E>>}
E>>
K>Учитывая, что "hello".length — сахар для length("hello") тут все вполне логично. K>Хуже другое — такая логика работает только в одну сторону: K>
K>class A {
K> int inc(int a ) = a + 1;
K>}
K>void main( String[] args ) {
K> let o = new A();
K> let i = o.inc(1);
K> let i2 = inc(o, 1); // так должно работать.
K> let f = inc;
K> let j = f(o, 1);
K> let j2 = o.f(1); // так тоже должно, но не работает.
K> println(i == j);
K>}
K>
K>Вот это для меня оказалось неожиданностью.
Еще интереснее, когда внутри объекта используется функция без параметров:
class A {
public int f() { ... };
public int g() { doSomething( f ); /* oops! */ }
}
let o = new A();
doSomething( o.f );
Т.е. вызов метода без параметров f внутри класса A и снаружи выполняется по разному.
E>>Имхо, в нормальных функциональных языках функции без аргументов -- это вообще скорее исключение из правил, чем норма. Ведь результат функции должен зависеть только от аргументов функции и функция при одинаковых значениях аргументов должна возвращать одинаковое значение (функция в математическом смысле, без побочных эффектов). Следовательно, при отсутствии аргументов функция должна вырождаться в константу. А посему я не знаю, бывают ли в "нормальных" функциональных языках функции без параметров (насколько я помню, то при чтении документации по OCaml я таких не видел).
K>В "нормальных" функциональных языках "константа" это, в общем-то и есть функция без параметров.
Но такую функцию, надо полагать, нельзя передать в качестве параметра и возвратить. Т.к. будет использоваться результат вызова функция (значение), но не сама функция.
Или можно?
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
DC>>Это уточнение меняет смысл моей фразы . Т.к. в этих языках сущность одна, а то что там есть ссылка, дык это деталь реализации. E>От этой детали много чего зависит. Например, нельзя получить ссылку на переменную.
В C# можно. См ref и out параметры у функций.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, eao197, Вы писали:
K>>Зато если сначала был геттер, а его сменили на публичное поле — сломается весь код, в котором создавался и использовался делегат для геттера. E>Это все равно гораздо лучше того, что есть в С++ и, насколько я помню, в Java.
Наверное. Но, на мой взгляд, хуже, чем в C#, например.
K>>Кроме того, для доступа к функции через делегат этот uniform access principle все равно не выполняется. E>А uniform access principe распространяется не на работу с методами объекта, а на работу с атрибутами объекта. Т.е. благодоря этому принципу нет разницы между o.f и o.f, если f является атрибутом или методом-геттером.
Мммм... А что, геттер — не метод?
E>Еще интереснее, когда внутри объекта используется функция без параметров: E>
E>class A {
E> public int f() { ... };
E> public int g() { doSomething( f ); /* oops! */ }
E>}
E>let o = new A();
E>doSomething( o.f );
E>
E>Т.е. вызов метода без параметров f внутри класса A и снаружи выполняется по разному.
Совершенно одинаково:
class A {
int f() = 1;
void g() = doSomething( f );
void h() = doSomething( this.f );
}
void doSomething(int i) = println ("result");
void doSomething(A -> int fn) = println ("function");
void main( String[] args ) {
let o = new A();
o.g();
doSomething( f );
o.h();
doSomething( o.f );
}
Выведет:
function
function
result
result
И, кстати, методов без параметров не бывает.
K>>В "нормальных" функциональных языках "константа" это, в общем-то и есть функция без параметров. E>Но такую функцию, надо полагать, нельзя передать в качестве параметра и возвратить. Т.к. будет использоваться результат вызова функция (значение), но не сама функция. E>Или можно?
Можно. "Нормальные" функциональные языки — ленивые. Если уж на то пошло, нужно приложить усилия, чтобы так не сделать. foo bar в таком языке это не "вызов функции foo с параметром 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
Здравствуйте, eao197, Вы писали:
E>>>При большом количестве использующих язык программистов накопится достаточная статистика ... K>>При таком подходе, функциональность языков вроде Nice принципиально непозноваема. Не смотря на это, вы уверенно вынесли суждение о функциональности Nice, E>Я вынес это суждение после того, как попробовал поработать на Nice. Мне показалось, что работа на нем мало отличается от работы на D или Eiffel. В отличии от, например, Scala или OCaml, которые заставляют программировать в ином ключе.
Что поделать — субъективность есть субъективность.
Конечно, в Nice параметрический полиморфизм с "классами типов", диспетчеризация для многих аргументов, отсутствуют касты и области видимости (конечно, можно написать private и public, но компилятор их игнорирует), зато есть лямбды с замыканиями (инкапсуляция возможна, кстати, ха-ха, только в замыкании. Объекты Nice прозрачны как слеза комсомолки) и функциональные типы.
Классика ООП, короче говоря.
E>Так что, если я составлял на тот момент значительную часть от программирующих на Nice программистов, то...
Вы же написали "большом", а не "большем". Впрочем, какая разница? Думаю, что я составляю не меньшее число программировавших на Nice чем вы, если, конечно, вы представляете из себя не коллектив авторов с одним псевдонимом.
... << 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>Здравствуйте, eao197, Вы писали:
K>>>Зато если сначала был геттер, а его сменили на публичное поле — сломается весь код, в котором создавался и использовался делегат для геттера. E>>Это все равно гораздо лучше того, что есть в С++ и, насколько я помню, в Java.
K>Наверное. Но, на мой взгляд, хуже, чем в C#, например.
Чем?
K>>>Кроме того, для доступа к функции через делегат этот uniform access principle все равно не выполняется. E>>А uniform access principe распространяется не на работу с методами объекта, а на работу с атрибутами объекта. Т.е. благодоря этому принципу нет разницы между o.f и o.f, если f является атрибутом или методом-геттером.
K>Мммм... А что, геттер — не метод?
Я имел в виду, что когда кто-то пишет o.f, то ему интересно, что внутри у объекта.
Когда же кто-то пытается получить делегат для o.f, то он интересуется не значением атрибута объекта, а чем-то другим, например, способом взаимодействия с объектом в дальнейшем.
E>>Еще интереснее, когда внутри объекта используется функция без параметров: E>>
E>>class A {
E>> public int f() { ... };
E>> public int g() { doSomething( f ); /* oops! */ }
E>>}
E>>let o = new A();
E>>doSomething( o.f );
E>>
E>>Т.е. вызов метода без параметров f внутри класса A и снаружи выполняется по разному.
K>Совершенно одинаково: K>
K>class A {
K> int f() = 1;
K> void g() = doSomething( f );
K> void h() = doSomething( this.f );
K>}
K>void doSomething(int i) = println ("result");
K>void doSomething(A -> int fn) = println ("function");
K>void main( String[] args ) {
K> let o = new A();
K> o.g();
K> doSomething( f );
K> o.h();
K> doSomething( o.f );
K>}
K>
K>Выведет: K>
K>function
K>function
K>result
K>result
K>
Вы написали собственный пример, введя вторую функцию doSomething с типом аргумента A->int. Оставте только одну с аргументом типа int и тогда получится то, о чем я говорил.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
K>>>>Зато если сначала был геттер, а его сменили на публичное поле — сломается весь код, в котором создавался и использовался делегат для геттера. E>>>Это все равно гораздо лучше того, что есть в С++ и, насколько я помню, в Java. K>>Наверное. Но, на мой взгляд, хуже, чем в C#, например. E>Чем?
Тем, что свойство это не метод, со всеми вытекающими. Впрочем, нет предела совершенству — было бы неплохо, если бы публичные поля в C# запретили.
E>Я имел в виду, что когда кто-то пишет o.f, то ему интересно, что внутри у объекта. E>Когда же кто-то пытается получить делегат для o.f, то он интересуется не значением атрибута объекта, а чем-то другим, например, способом взаимодействия с объектом в дальнейшем.
И что? Это как-то снимает проблему?
E>Вы написали собственный пример, введя вторую функцию doSomething с типом аргумента A->int. Оставте только одну с аргументом типа int и тогда получится то, о чем я говорил.
class A {
int f() = 1;
void g() = doSomething( f );
void h() = doSomething( this.f );
}
void doSomething(int i) = println ("result");
//void doSomething(A -> int fn) = println ("function");void main( String[] args ) {
let o = new A();
o.g();
doSomething( f );
o.h();
doSomething( o.f );
}
Получается:
C:\nice_projects\test\test.nice: line 3, column 14:
Arguments ((test.A)->nice.lang.int) do not fit:
nice.lang.void doSomething(nice.lang.int i)
C:\nice_projects\test\test.nice: line 13, column 3:
Arguments ((test.A)->nice.lang.int) do not fit:
nice.lang.void doSomething(nice.lang.int i)
compilation failed with 2 errors
... << 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>Здравствуйте, eao197, Вы писали:
K>>>>>Зато если сначала был геттер, а его сменили на публичное поле — сломается весь код, в котором создавался и использовался делегат для геттера. E>>>>Это все равно гораздо лучше того, что есть в С++ и, насколько я помню, в Java. K>>>Наверное. Но, на мой взгляд, хуже, чем в C#, например. E>>Чем?
K>Тем, что свойство это не метод, со всеми вытекающими.
Опять не понял. Если речь идет о properties, то они в D реализуются через методы.
E>>Я имел в виду, что когда кто-то пишет o.f, то ему интересно, что внутри у объекта. E>>Когда же кто-то пытается получить делегат для o.f, то он интересуется не значением атрибута объекта, а чем-то другим, например, способом взаимодействия с объектом в дальнейшем.
K>И что? Это как-то снимает проблему?
Это говорит о том, что проблемы нет вообще. Uniform access principle гарантирует, что конструкции вида a = o.f или g(o.f) остануться корректными вне зависимости от того, является ли o.f атрибутом или методом.
Если же кто-то делает d = &o.f, значит его интересует не возврашаемое f значение, а сам f. А это уже просто не попадает под действие uniform access principle, имхо.
По поводу примера с doSomething -- да, я что-то перепутал. Методы объектов в Nice всегда должны вызываться в форме target.method. Вне зависимости от того, происходит ли вызов внутри объекта или снаружи.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Klapaucius, Вы писали:
K>Учитывая, что "hello".length — сахар для length("hello") тут все вполне логично. K>Хуже другое — такая логика работает только в одну сторону: K>
K>class A {
K> int inc(int a ) = a + 1;
K>}
K>void main( String[] args ) {
K> let o = new A();
K> let i = o.inc(1);
K> let i2 = inc(o, 1); // так должно работать.
K> let f = inc;
K> let j = f(o, 1);
K> let j2 = o.f(1); // так тоже должно, но не работает.
K> println(i == j);
K>}
K>
K>Вот это для меня оказалось неожиданностью.
А это тоже логично. Ведь встретив запись o.f(1) компилятор Nice ищет функцию f, которую можно вызывать как f(o,1). Но такой фукнции нет. Есть переменная f, являющаяся ссылкой на функцию (aka delegate в D), но она все-таки не функция, поэтому компилятор функцию f и не находит.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
K>>class A {
K>> int inc(int a ) = a + 1;
K>>}
K>>void main( String[] args ) {
K>> let o = new A();
K>> let i = o.inc(1);
K>> let i2 = inc(o, 1); // так должно работать.
K>> let f = inc;
K>> let j = f(o, 1);
K>> let j2 = o.f(1); // так тоже должно, но не работает.
K>> println(i == j);
K>>}
K>>
E>А это тоже логично. Ведь встретив запись o.f(1) компилятор Nice ищет функцию f, которую можно вызывать как f(o,1). Но такой фукнции нет.
Вообще-то в случае с let j = f(o, 1) он находит функцию f без труда. Если бы компилятор просто вcегда преобразовывал x.y -> y(x) все бы работало. Вообще — это пример, который позволяет продемонстрировать разницу между функцией и методом. Функцию можно сконструировать в рантайме, а метод нет. Возможно, какая-то сермяжная правда в этом и есть, но при всем прочем, разница между методом и функцией в Nice выглядит как-то нелогично. Особенно, если учесть что это могут быть экземпляры одного и того же функционального типа.
... << 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>Я-то спрашивал, определение, из которого следует, какие средства необходимы. Мое определение заключается в том, что функциональный язык — это язык, в котором функции являются FCO.
Так тебе уже ответили, что не согласны, и привели своё определние, согласно которому ф-й ЯП это тот, который нативно поддерживает функциональную парадигму. FCO явно недостаточно для этого.
K>Нет, не поэтому. Слова "слишком" и "много" не имеют никакого смысла. Когда слишком много, а когда еще не слишком? И в сравнении с какими ООП языками? Каким образом происходит сравнение — по какой методике, чем измерим интервал между ООП и не ООП языком и на какой оси?
На банальной оси числа строк программы.
K>Я считаю, что C не считается ООП потому, что в нем нет объектов как FCO. Все.
определение объекта в студию... а то может оказаться, что это заявление преждевременно.
K>Мы -то говорим о классификации языков безотносительно их удобства.
почему ты отделяешь удобства от фич?
K>Действительно, не поняли. Функция в C не является первоклассным объектом. Указатель — является. Но вы, конечно, можете попробовать открыть для меня глубины C, продемонстрировав код на C соответствующий моему коду на Nice. Будет очень интересно.
Ну на C# можно, и согласно твоей логике, он является ФЯП.
K>По форме, но не по содержанию. Разница между D и Nice в том, что "лямбда" в D это литерал для делегата, а не для функции, как в Nice. Снова повторяю, то, что делегат — сущность первоклассная я не отрицал, не отрицаю и отрицать не собираюсь. Функция же — сущность не первоклассная — вернуть ее из функции нельзя. 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>
K>Что в этом непонятного?
Это игра терминов. То, что в D называется делегатом, во многих ФЯ называется функцией. Просто напомню, что для нас (программистов) ЯП — лишь инструмент, и в этом смысле делегаты в D и ф-ии в ФЯ — это абсолютно один и тот же инструмент, хоть и называется по-разному в рамках разных языков.
K>К чему все эти эмоционально окрашенные слова вроде "ущербности"? Явное конструирование является показателем того, что функцию нельзя вернуть без явного преобразования.
Уточню, функцию в терминах D, что не есть эквивалент ф-ии из семейства ML, а вот полученный делегат — эквивалент, с точностью до терминологии.
K>Также это показатель того, что функция и делегат — разные сущности.
Опять же, в рамках терминологии языка D.
K>В Nice никакие делегаты не нужны — как раз потому, что функции — первоклассные.
Потому что других типов ф-ий нет, лишь те, что аналоги делегатов.
K>И тип возвращаемого значения там — функциональный тип, а не тип делегата.
Ес-но, ведь типа "делегат" там нет.
K>Я считаю первоклассность функций не только необходимым, но и достаточным условием. Если вы так не считаете — сформулируйте свое определение.
Уже формулировали, необходима поддержка функциональной парадигмы. И тот же паттерн-матчинг в рамках парадигмы не синтаксический сахар, а необходимый инструмент для поддержки аспектов парадигмы.
E>>И защищаете правильность своего определения руководствуясь лишь проявлением внешней формы, на том лишь основании, что одно и то же понятие в разных языках называется или не называется функцией. Не желая видеть, что под разными названиями скрываются одни и те же вещи.
+1
K>Все это жонглирование псевдофилософскими понятиями вроде "формы" и "содержания" ничего не дает. Что есть форма — синтаксис? Но есть ли основания считать синтаксис менее важным в данном вопросе, чем, например, семантика?
Хм... Как раз-таки видна попытка проигнорировать эквивалентность семантик.
Здравствуйте, vdimas, Вы писали:
V>привели своё определние, согласно которому ф-й ЯП это тот, который нативно поддерживает функциональную парадигму.
Т.е. функциональный язык — это функциональный язык? Содержательное определение, что тут скажешь. Если вам так больше понравится можно сформулировать вопрос иначе:
Что есть нативная поддержка функциональной парадигмы языком?
Мой ответ — первоклассность функций в этом языке.
V>FCO явно недостаточно для этого.
Вы хотели сказать, что функций как FCO недостаточно?
С моей точки зрения — вполне достаточно.
А чего еще не хватает?
K>>Нет, не поэтому. Слова "слишком" и "много" не имеют никакого смысла. Когда слишком много, а когда еще не слишком? И в сравнении с какими ООП языками? Каким образом происходит сравнение — по какой методике, чем измерим интервал между ООП и не ООП языком и на какой оси? V>На банальной оси числа строк программы.
Что есть "число строк необходимое для поддержки ООП" и на каком числе строк находится граница между OO и неОО языком?
K>>Я считаю, что C не считается ООП потому, что в нем нет объектов как FCO. Все. V>определение объекта в студию...
Допустим, АТД с состоянием. Годится?
V>а то может оказаться, что это заявление преждевременно.
Если и преждевременно — мне все равно. Обсуждение объектной ориентированности языка C мне не интересно и в данном случае является оффтопиком.
K>>Мы -то говорим о классификации языков безотносительно их удобства. V>почему ты отделяешь удобства от фич?
Фича — характеристика языка. Удобство — характеристика системы язык-программист. Синтаксис с отступами — фича. С точки зрения Васи — это удобство, с точки зрения Пети — неудобство.
K>>Действительно, не поняли. Функция в C не является первоклассным объектом. Указатель — является. Но вы, конечно, можете попробовать открыть для меня глубины C, продемонстрировав код на C соответствующий моему коду на Nice. Будет очень интересно. V>Ну на C# можно, и согласно твоей логике, он является ФЯП.
Это уже обсуждалось. Да, со второй версии он соответствует моему определению ФЯП.
... << 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>Что есть нативная поддержка функциональной парадигмы языком? K>Мой ответ — первоклассность функций в этом языке.
K>Вы хотели сказать, что функций как FCO недостаточно? K>С моей точки зрения — вполне достаточно. K>А чего еще не хватает?
Функциональная парадигма в нынешнем виде — это не только первоклассность ф-ий и не столько. Когда-то обсуждали сам термин "парадигма" и пришли к выводу, что парадигма (относительно к IT) — это совокупность подходов, практик, идей и соответствующего инструментария, определяющих способ решения некоей задачи (среди бесконечного множества других способов). В интуитивном плане парадигма формирует точку зрения на проблему. Функциональная декомпозиция — это лишь один из кирпичиков этой парадигмы, как и первоклассность ф-ий. Считается, что в функциональной парадигме присутствует как минимум еще иммутабельность, и как следствие — инструментарий, типа туплов и прилагающегося к ним паттерн-матчинга, раскрутки рекурсии и встроенная возможность ленивости (не только при моделировании бесконечных списков, сам факт оперирования ф-иями как значениями предполагает отложенный вызов этих самых ф-ий). Т.е. вот минимальный "джентельменский" требований к инструментарию, для полной поддержки современной функциональной парадигмы.
K>>>Нет, не поэтому. Слова "слишком" и "много" не имеют никакого смысла. Когда слишком много, а когда еще не слишком? И в сравнении с какими ООП языками? Каким образом происходит сравнение — по какой методике, чем измерим интервал между ООП и не ООП языком и на какой оси? V>>На банальной оси числа строк программы.
K>Что есть "число строк необходимое для поддержки ООП" и на каком числе строк находится граница между OO и неОО языком?
т.к. ось бесконечна, то интересует лишь ее отрезок — суть разность строк, применительно к какой-либо задаче.
K>>>Я считаю, что C не считается ООП потому, что в нем нет объектов как FCO. Все. V>>определение объекта в студию...
K>Допустим, АТД с состоянием. Годится?
без "А" годится, ибо под классическое определение объекта попадает любой конечный автомат, разработанный (или смоделированный, не суть) на любом ЯП, например на том же С.
V>>а то может оказаться, что это заявление преждевременно.
K>Если и преждевременно — мне все равно. Обсуждение объектной ориентированности языка C мне не интересно и в данном случае является оффтопиком.
Ok, просто это как бы контрпример к тому, что наличие или отсутствие в инструменте какого-либо одного "кирпичика" не обязательно делает инструмент достаточно подходящим для использования в рамках какой-либо парадигмы, хотя и может сделать применение этой парадигмы с этим инструментом _возможным_. Дело, разумеется, лишь в количестве доп. приседаний, которые согласен делать применяющий, а так же в количестве _автоматически_ обнаруживаемых граблей, принадлежащих к парадигме генетически.
K>>>Мы -то говорим о классификации языков безотносительно их удобства. V>>почему ты отделяешь удобства от фич?
K>Фича — характеристика языка. Удобство — характеристика системы язык-программист. Синтаксис с отступами — фича. С точки зрения Васи — это удобство, с точки зрения Пети — неудобство.
Что-то мне подсказывает, что фичи языков, да и сами ЯП высокого уровня появились в ответ на требование "удобства". Набор реализованных взаимодействующих фич в языке является, по-сути, реализацией неких требований удобства с т.з. авторов языка.
V>>Ну на C# можно, и согласно твоей логике, он является ФЯП.
K>Это уже обсуждалось. Да, со второй версии он соответствует моему определению ФЯП.
Тогда неудивительно, что вышел такой длинный спор.