Re[47]: Функциональный/нефункциональный
От: Klapaucius  
Дата: 04.03.08 13:05
Оценка:
Здравствуйте, 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
Re[63]: Функциональный/нефункциональный
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 04.03.08 13:38
Оценка:
Здравствуйте, 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++.
Re[48]: Функциональный/нефункциональный
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 04.03.08 13:42
Оценка:
Здравствуйте, Klapaucius, Вы писали:

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

K>Т.е. мы имеем дело с необъективностью следующего порядка.

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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[64]: Функциональный/нефункциональный
От: Klapaucius  
Дата: 04.03.08 14:03
Оценка:
Здравствуйте, 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
Re[49]: Функциональный/нефункциональный
От: Klapaucius  
Дата: 04.03.08 14:08
Оценка: :)
Здравствуйте, 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
Re[50]: Функциональный/нефункциональный
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 04.03.08 14:19
Оценка:
Здравствуйте, Klapaucius, Вы писали:

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


E>>При большом количестве использующих язык программистов накопится достаточная статистика для того, чтобы считать какие-то усилия "особыми", а какие-то "ординарными". Соответственно, язык приобритет репутацию "функционального" или не приобритет ее.


K>При таком подходе, функциональность языков вроде Nice принципиально непозноваема. Не смотря на это, вы уверенно вынесли суждение о функциональности Nice,


Я вынес это суждение после того, как попробовал поработать на Nice. Мне показалось, что работа на нем мало отличается от работы на D или Eiffel. В отличии от, например, Scala или OCaml, которые заставляют программировать в ином ключе.

Так что, если я составлял на тот момент значительную часть от программирующих на Nice программистов, то...


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[65]: Функциональный/нефункциональный
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 04.03.08 14:28
Оценка:
Здравствуйте, 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++.
Re[46]: Функциональный/нефункциональный
От: WolfHound  
Дата: 04.03.08 16:34
Оценка:
Здравствуйте, eao197, Вы писали:

DC>>Это уточнение меняет смысл моей фразы . Т.к. в этих языках сущность одна, а то что там есть ссылка, дык это деталь реализации.

E>От этой детали много чего зависит. Например, нельзя получить ссылку на переменную.
В C# можно. См ref и out параметры у функций.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[66]: Функциональный/нефункциональный
От: Klapaucius  
Дата: 04.03.08 17:41
Оценка:
Здравствуйте, 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
Re[51]: Функциональный/нефункциональный
От: Klapaucius  
Дата: 04.03.08 18:02
Оценка:
Здравствуйте, 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
Re[67]: Функциональный/нефункциональный
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 04.03.08 19:23
Оценка:
Здравствуйте, 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++.
Re[68]: Функциональный/нефункциональный
От: Klapaucius  
Дата: 04.03.08 20:47
Оценка:
Здравствуйте, 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
Re[69]: Функциональный/нефункциональный
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 05.03.08 07:17
Оценка:
Здравствуйте, 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++.
Re[65]: Функциональный/нефункциональный
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 05.03.08 07:21
Оценка:
Здравствуйте, 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++.
Re[70]: Функциональный/нефункциональный
От: Klapaucius  
Дата: 05.03.08 13:01
Оценка:
Здравствуйте, eao197, Вы писали:

E>Опять не понял. Если речь идет о properties, то они в D реализуются через методы.


Это понятно, но в 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
Re[66]: Функциональный/нефункциональный
От: Klapaucius  
Дата: 05.03.08 13:01
Оценка:
Здравствуйте, eao197, Вы писали:

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>>

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
Re[9]: Функциональный/нефункциональный
От: vdimas Россия  
Дата: 06.03.08 04:15
Оценка:
Здравствуйте, Klapaucius, Вы писали:

K>Я-то спрашивал, определение, из которого следует, какие средства необходимы. Мое определение заключается в том, что функциональный язык — это язык, в котором функции являются FCO.


Так тебе уже ответили, что не согласны, и привели своё определние, согласно которому ф-й ЯП это тот, который нативно поддерживает функциональную парадигму. FCO явно недостаточно для этого.


K>Нет, не поэтому. Слова "слишком" и "много" не имеют никакого смысла. Когда слишком много, а когда еще не слишком? И в сравнении с какими ООП языками? Каким образом происходит сравнение — по какой методике, чем измерим интервал между ООП и не ООП языком и на какой оси?


На банальной оси числа строк программы.

K>Я считаю, что C не считается ООП потому, что в нем нет объектов как FCO. Все.


определение объекта в студию... а то может оказаться, что это заявление преждевременно.


K>Мы -то говорим о классификации языков безотносительно их удобства.


почему ты отделяешь удобства от фич?


K>Действительно, не поняли. Функция в C не является первоклассным объектом. Указатель — является. Но вы, конечно, можете попробовать открыть для меня глубины C, продемонстрировав код на C соответствующий моему коду на Nice. Будет очень интересно.


Ну на C# можно, и согласно твоей логике, он является ФЯП.
Re[41]: Функциональный/нефункциональный
От: vdimas Россия  
Дата: 06.03.08 09:53
Оценка: 6 (1)
Здравствуйте, Klapaucius, Вы писали:


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>Все это жонглирование псевдофилософскими понятиями вроде "формы" и "содержания" ничего не дает. Что есть форма — синтаксис? Но есть ли основания считать синтаксис менее важным в данном вопросе, чем, например, семантика?


Хм... Как раз-таки видна попытка проигнорировать эквивалентность семантик.
... << RSDN@Home 1.2.0 alpha rev. 786>>
Re[10]: Функциональный/нефункциональный
От: Klapaucius  
Дата: 06.03.08 13:10
Оценка:
Здравствуйте, 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
Re[11]: Функциональный/нефункциональный
От: vdimas Россия  
Дата: 06.03.08 13:56
Оценка: 20 (2) +2
Здравствуйте, 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>Это уже обсуждалось. Да, со второй версии он соответствует моему определению ФЯП.


Тогда неудивительно, что вышел такой длинный спор.
... << RSDN@Home 1.2.0 alpha rev. 786>>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.