Здравствуйте, Курилка, Вы писали:
К>Здравствуйте, Perseus, Вы писали:
P>>Вот кусок примера, который я приводил выше:
P>>Interface* object1 = new A(); P>>Interface* object2 = new B();
P>>foo((A)object1); P>>foo((B)object2);
P>>Какой тип у object1? Interface! Какой же экзепляр соответсвует object1 на этапе выполнения? A! (в смысле экземпляр класса А). Компилятор подбирает сответствующую сигнатуру по ТИПУ объекта. Твоя проблема в том, что ты не понимаешь, что foo(A* a) и foo(B* a) — совершенно разные функции, и поиск нужной сигнатуры при вызове ничем не отличается от вызова любой другой ф-ции. Тебя смущает одинаковые название ТЕЛА этих ф-ций. А между прочим, компилятору реально пофиг на тело, он отличает ф-ции только по сигнатуре. Предположим, мы назвали наши ф-ции по-разному
К>По-моему ты запутался, Interface* — это тип указателя/ссылки, когда как у объекта, на который этот указатель/ссылка указывает, тип будет A.
Можно сказать и так. Неужели неочевидно равнозначность сказанного мной и вот этого утверждения. котрое представляет собой простую переформулировку? Тип объекта = типу ссылки. Само собой, РЕАЛЬНЫЙ тип объекта не имеет с эти ничего общего.
К>В традиционных языках нет диспетчеризации в рантайме по параметрам функции (в отличие, от лиспа, к примеру) и единственный метод — vtbl, но есть перегрузка, т.е. диспетчеризация времени компиляции, а там известен лишь тип ссылок, а не "живых" объектов. Ну а vtbl есть лишь один метод перегрузки, причём самый, имхо, простой, понятный, ну и эффективный.
Само собой. Что ты хотел этим сказать?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[11]: method(obj) то же самое, что и obj.method() ? Что за
Здравствуйте, Perseus, Вы писали:
P>Можно сказать и так. Неужели неочевидно равнозначность сказанного мной и вот этого утверждения. котрое представляет собой простую переформулировку? Тип объекта = типу ссылки. Само собой, РЕАЛЬНЫЙ тип объекта не имеет с эти ничего общего.
Нет, ты вот придумал какой-то "реальный" тип, а уже если у тебя своя собственная терминология, то обсуждать что-либо неинтересно, да и вообще смысла твоих претензий не просматривается (или ты что-то другое на системах типов вытеснить хочешь?). К примеру, возьмём любой динамический ООП язык — какого типа там будет ссылка? Как-то ты ограниченно смотришь, по-моему.
Re[13]: method(obj) то же самое, что и obj.method() ? Что за
Здравствуйте, Perseus, Вы писали:
SJA>>Я собственно не вижу причин почему объекты с состоянием нельзя хранить в виде ф-ий.
P>Прямо фантастика какая-то в стиле Г. Лавкрафта. P>Как же это выглядит, если не секрет?
В виде списка ф-ий, что-то делающих с immutable объектом и возвращающих новый immutable объект. Изменение состояния объекта будет сводится к добавлению ф-ии, принимающей как аргумент предыдущую ф-ию, и параметры требуемые для модификации в конец списка ф-ий.
f = [foo] // возвращает результат работы ф-ии foo. Например строку "foo"
приведение к верхнему регистру:
f = [foo, upper]
добавление строки "bar" (представленной ф-ией bar) в виде каррированой ф-ии concat(x, y) { return x + y };
f = [foo, upper, lambda x: concat (x bar())]
и т.д. текущее состояние получается путём выполнения всех ф-ий по списку.
Здравствуйте, Perseus, Вы писали:
DC>>Тогда ответь пожалуйста, что такое полиморфизм. Своими словами в вики не лезть .
P>Полиморфизм в применении к ООП — это свойство объектов реагировать по-разному на одно и то же входное воздействие.
В приведенном примере кто ведет себя полиморфно? Правильно параметр функции указатель на интерфейс, но никак не объект. И такой полиморфизм (параметрический) обеспечивается механизмом виртуальных функций. Ты все верно объяснил, как это реализовано в С++. Но замена obj.metod() на metod(obj) в плане полиморфизма ничего не меняет, просто С++ не умеет разруливать такие ситуации. (Есть языки, которые это умеют точно знаю умеет Хаскел. Ссылку я тебе давал.) То что подобная замена лишена смысла в таких языка, думаю очевидно, т.к. придеться делать полиморфное поведение ручками .
А сейчас я объясню более подробно, какую логическую ошибку совершаешь ты.
Я пытаюсь тебе объяснить, что ты прицепился к конкретной реализации полиморфизма в конкретном языке и не до конца понимаешь его смысл.
P>Вот кусок примера, который я приводил выше:
P>Interface* object1 = new A(); P>Interface* object2 = new B();
P>foo((A)object1); P>foo((B)object2);
P>Какой тип у object1? Interface! Какой же экзепляр соответсвует object1 на этапе выполнения? A! (в смысле экземпляр класса А). Компилятор подбирает сответствующую сигнатуру по ТИПУ объекта. Твоя проблема в том, что ты не понимаешь, что foo(A* a) и foo(B* a) — совершенно разные функции, и поиск нужной сигнатуры при вызове ничем не отличается от вызова любой другой ф-ции. Тебя смущает одинаковые название ТЕЛА этих ф-ций. А между прочим, компилятору реально пофиг на тело, он отличает ф-ции только по сигнатуре. Предположим, мы назвали наши ф-ции по-разному
P>foo1(A* a) P>foo2(B* a)
Вот тут я немного добавлю, полиморфным может быть не только интерфейс, а еще и функция!!!! Ты же считаешь нормальным что оператор '+' складывает различные типы чисел. Т.е. для разных типов функция ведет себя по разному, т.е. полиморфна, для программиста сущность 'функция' определяется её именем. Посему вызовы sqrt(12) и sqrt(12.0) мы считаем вызовами одной функции (квадрат возвращает в любом случае), но для разных типов поведение этой
функции совершенно разное. Т.е. функция ведет себя полиморфно.
P>Тогда вызов foo1(new A()) ты тоже сочтешь полиморфным?
Нет, функция то другая даже имя не то . Это для компилятора foo(A*) и foo(B*) разные функции, для меня это одна функция, т.к. делает она одно и тоже действие только с разными типами.
P>Тебе, очевидно, привденный выше пример представился в таком свете:
P>A* object1 = new A(); P>B* object2 = new B();
P>foo(object1); P>foo(object2);
P>Вот тут, действительно, компилятор выберет нужную сигнатуру, только это не будет связано ни с каким полиморфизмом. Это будет связано банально с совпадением сигнатур, не более того Совпадение имен ф-ций как раз тебя и запутало.
Меня ничего не запутало, я просто сначала не понял что ты так пытался изобразить.
P>В случае с виртуальными ф-циями, их сигнатуры совпадают. Как же компилятор находит нужную реализацию для вызова? Очень просто, используя информацию времени выполнения о КЛАССЕ, которому принадлежит ЭКЗЕМПЛЯР объекта.
Погоди а как компилятор узнает информацию времени выполнения? Он же не выполняет программу . Компилятор видит только vtbl, что является информацией о типе (весьма ограниченной), но времени компиляции .
Побеждающий других — силен,
Побеждающий себя — Могущественен.
Лао Цзы
Re[10]: method(obj) то же самое, что и obj.method() ? Что за
Здравствуйте, Sergey J. A., Вы писали: SJA>Интересно было бы посмотреть, как заменить immutable строку (считаную например с консоли) на функцию.
Как раз это — элементарно. Смотря что ты ожидаешь от строки. Например, можно представить строку как функцию, которая возвращает пару из (текущий символ, остаток строки), где остаток строки — такая же (по устройству) функция, либо null если символ был последним.
При вводе строки с консоли мы тупо строим дерево функций:
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Sergey J. A., Вы писали: SJA>>Интересно было бы посмотреть, как заменить immutable строку (считаную например с консоли) на функцию. S>Как раз это — элементарно. Смотря что ты ожидаешь от строки. Например, можно представить строку как функцию, которая возвращает пару из (текущий символ, остаток строки), где остаток строки — такая же (по устройству) функция, либо null если символ был последним. S>При вводе строки с консоли мы тупо строим дерево функций: S>
Здравствуйте, Sergey J. A., Вы писали: SJA>и т.д. текущее состояние получается путём выполнения всех ф-ий по списку.
Это будет другой объект. Существующие ссылки на старый объект никак не затронутся. В этом, собственно, одно из основных отличий ООП от ФП: в ООП мы можем передать объекту1 ссылку на объект2; объект1 будет регулярно "дергать" объект2 для каких-то своих целей. Затем внеший по отношению к объекту1 код может изменить состояние объекта2, и объект1 будет наблюдать другое поведение от того же самого объекта2. В ФП для этого потребуется создать объект1', который будет содержать ссылку на совсем другой объект2'.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[15]: method(obj) то же самое, что и obj.method() ? Что за
Здравствуйте, Sinclair, Вы писали:
SJA>>и т.д. текущее состояние получается путём выполнения всех ф-ий по списку. S>Это будет другой объект. Существующие ссылки на старый объект никак не затронутся. В этом, собственно, одно из основных отличий ООП от ФП: в ООП мы можем передать объекту1 ссылку на объект2; объект1 будет регулярно "дергать" объект2 для каких-то своих целей. Затем внеший по отношению к объекту1 код может изменить состояние объекта2, и объект1 будет наблюдать другое поведение от того же самого объекта2. В ФП для этого потребуется создать объект1', который будет содержать ссылку на совсем другой объект2'.
Вообще-то в моём примере изменяется список, но голова списка остаётся по одному и тому-же адресу. Этот адрес можно пеердать куда угодно. Причём при каждом доступе к объекту он должен пересоздаться заново (в коде приложения нельзя создать объект из ф-ии и сохранить на него ссылку).
Здравствуйте, Sergey J. A., Вы писали: SJA>А что нам в таком случае помешает тупо достраивать дерево ф-ий, что-бы представить модификацию этой строки и далее ?
То, что существующие указатели на эту строку никак не изменятся. Нельзя сделать из этой строки hello world, потому, что научить пятую функцию возвращать вместо ('o', null) что-то другое — нельзя. Это не объект, это неизменная функция.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[13]: method(obj) то же самое, что и obj.method() ? Что за
Здравствуйте, Sinclair, Вы писали:
S>То, что существующие указатели на эту строку никак не изменятся. Нельзя сделать из этой строки hello world, потому, что научить пятую функцию возвращать вместо ('o', null) что-то другое — нельзя. Это не объект, это неизменная функция.
А если хранить указатель на указатель на ф-цию ? Тогда привешивание доп. ф-ий повлияет на все указатели.
Здравствуйте, Sergey J. A., Вы писали:
SJA>Здравствуйте, Sinclair, Вы писали:
SJA>>>и т.д. текущее состояние получается путём выполнения всех ф-ий по списку. S>>Это будет другой объект. Существующие ссылки на старый объект никак не затронутся. В этом, собственно, одно из основных отличий ООП от ФП: в ООП мы можем передать объекту1 ссылку на объект2; объект1 будет регулярно "дергать" объект2 для каких-то своих целей. Затем внеший по отношению к объекту1 код может изменить состояние объекта2, и объект1 будет наблюдать другое поведение от того же самого объекта2. В ФП для этого потребуется создать объект1', который будет содержать ссылку на совсем другой объект2'.
SJA>Вообще-то в моём примере изменяется список, но голова списка остаётся по одному и тому-же адресу.
Этого не может быть.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[14]: method(obj) то же самое, что и obj.method() ? Что за
Здравствуйте, Sergey J. A., Вы писали:
SJA>А если хранить указатель на указатель на ф-цию ? Тогда привешивание доп. ф-ий повлияет на все указатели.
Что ты понимаешь под словом "привешивание"? Подумай внимательнее, и учти, что никаких модификаций у существующих структур/функций нет. "Добавление" в голову списка в ФП ничего на самом деле не добавляет; создается новый список, который ссылается на старый.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[15]: method(obj) то же самое, что и obj.method() ? Что за
Здравствуйте, Sergey J. A., Вы писали:
SJA>Здравствуйте, Sinclair, Вы писали:
SJA>>>и т.д. текущее состояние получается путём выполнения всех ф-ий по списку. S>>Это будет другой объект. Существующие ссылки на старый объект никак не затронутся. В этом, собственно, одно из основных отличий ООП от ФП:
Я бы сказал даже, что это единственное СУЩЕСТВЕННОЕ отличие ФП от процедурного программирования. Все остальное — рюшечки да шашечки, прямого отношения к ФП не имеющиеся. Те же замыкания — это хак для ФП, прямо нарушающий идеи ФП, чтобы с помощью ФП можно было написать что-нибудь поболее HelloWorld. То же самое можно сказать и про полиморфизм — это чрезвычайно полезная вещь для языков ФП, но вещь, прямого отношения к ФП не имеющая. А то, что существует привычка рассуждения "то что есть в языках ФП, то и есть ФП", — это факт общеизвестный, но нас-то не проведешь Те же лямбды существуют везде, где только можно, в Smalltalk — это codeblock, например. И их наличие никак не говорит о том, что это является признаком "функциональности" языка.
Все так называемые "достоинства функционального программирования" проистекают из-за принципиального отказа от хранения состояния. Это и некоторая декларативность и отсутствие необходимости придерживаться порядка вычислений. А большинство остальных отличий ФП — это попытки сгладить негативные последствия пункта 1.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[16]: method(obj) то же самое, что и obj.method() ? Что за
Здравствуйте, Sergey J. A., Вы писали:
SJA>Вообще-то в моём примере изменяется список, но голова списка остаётся по одному и тому-же адресу. Этот адрес можно пеердать куда угодно. Причём при каждом доступе к объекту он должен пересоздаться заново (в коде приложения нельзя создать объект из ф-ии и сохранить на него ссылку).
Списки вообще-то тоже должны быть immutable.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[16]: method(obj) то же самое, что и obj.method() ? Что за
Здравствуйте, LaPerouse, Вы писали:
LP>Я бы сказал даже, что это единственное СУЩЕСТВЕННОЕ отличие ФП от процедурного программирования.
Ну, я как-то стесняюсь назвать построение функций на лету несущественным Лямбды шарпа и анонимные классы не считаются, они как бы заранее один раз построены при компиляции. Рефлексия не считается — это не часть языка, то же самое, что вызвать внешний компилятор. Других существенных отличий именно ФП от ООП я и не знаю.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[17]: method(obj) то же самое, что и obj.method() ? Что за
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, LaPerouse, Вы писали:
LP>>Я бы сказал даже, что это единственное СУЩЕСТВЕННОЕ отличие ФП от процедурного программирования. S>Ну, я как-то стесняюсь назвать построение функций на лету несущественным Лямбды шарпа и анонимные классы не считаются, они как бы заранее один раз построены при компиляции.
Это опять-таки особенность реализации. Пусть и является хлебом и водой при программмировании на функциональном языке.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[16]: method(obj) то же самое, что и obj.method() ? Что за
Здравствуйте, LaPerouse, Вы писали:
LP>Здравствуйте, Sergey J. A., Вы писали:
SJA>>Здравствуйте, Sinclair, Вы писали:
SJA>>>>и т.д. текущее состояние получается путём выполнения всех ф-ий по списку. S>>>Это будет другой объект. Существующие ссылки на старый объект никак не затронутся. В этом, собственно, одно из основных отличий ООП от ФП:
LP>Я бы сказал даже, что это единственное СУЩЕСТВЕННОЕ отличие ФП от процедурного программирования. Все остальное — рюшечки да шашечки, прямого отношения к ФП не имеющиеся. Те же замыкания — это хак для ФП, прямо нарушающий идеи ФП, чтобы с помощью ФП можно было написать что-нибудь поболее HelloWorld. То же самое можно сказать и про полиморфизм — это чрезвычайно полезная вещь для языков ФП, но вещь, прямого отношения к ФП не имеющая. А то, что существует привычка рассуждения "то что есть в языках ФП, то и есть ФП", — это факт общеизвестный, но нас-то не проведешь Те же лямбды существуют везде, где только можно, в Smalltalk — это codeblock, например. И их наличие никак не говорит о том, что это является признаком "функциональности" языка.
Здрасьте! ФЯ и есть засахаренная лямбда. Лямбда-исчисление (или комбинаторное — они эквивалентны) — это и есть ассемблер для ФП. А про полиморфизм — никто и не утверждал, что это свойство исключительно ФП. Просто канонический ООП-полиморфизм — один из частных случаев полиморфизма в широком смысле: когда одна и та же синтаксическая конструкция годна для разных типов.
LP>Все так называемые "достоинства функционального программирования" проистекают из-за принципиального отказа от хранения состояния. Это и некоторая декларативность и отсутствие необходимости придерживаться порядка вычислений. А большинство остальных отличий ФП — это попытки сгладить негативные последствия пункта 1.
Современные ФЯ позволяют хранить состояния, не нарушая чистоты. Вопрос их изоляции решается, например, с помощью системы типов. Просто состояние — не предмет первой необходимости при функциональном подходе.
Re[17]: method(obj) то же самое, что и obj.method() ? Что за
Здравствуйте, deniok, Вы писали:
D>Современные ФЯ позволяют хранить состояния, не нарушая чистоты. Вопрос их изоляции решается, например, с помощью системы типов. Просто состояние — не предмет первой необходимости при функциональном подходе.
Нет. Не существует такого способа хранить состояние и при этом избежать side-эффектов. Не хотите же вы привести монады из Haskell, которые являются чистым костылем к оригинальному ФП?
Опять-таки, расхождение в терминологии. Вы под ФП, по всей видимости, имеете ввиду то, что реализовано в современных ФЯ. Я же под ФП понимаю его первоначальную трактовку, которая как раз начисто отрицает всякое состояние.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[17]: method(obj) то же самое, что и obj.method() ? Что за
Здравствуйте, deniok, Вы писали:
D>Здрасьте! ФЯ и есть засахаренная лямбда.
Как известно по крайней мере с 1965 года, практически любой ЯП есть засахаренная лямбда.
Re[17]: method(obj) то же самое, что и obj.method() ? Что за