Re[71]: Мнение: объектно-ориентированное программирование — катастрофа на трилли
От: samius Япония http://sams-tricks.blogspot.com
Дата: 28.10.19 18:37
Оценка: +1
Здравствуйте, AlexRK, Вы писали:

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


ARK>Ты не можешь без документации по языку судить о чистоте написанных на нем функций. Если можешь, то скажи, является ли чистой вот эта функция: "funktion Main % print Hello World \ @Q". Что это за язык, неважно, ведь ты не будешь руководствоваться документацией при проверке чистоты.

Для неизвестного мне языка — даже пытаться не буду.

S>>Если при этом тип результата функции будет int, а не Task<int> или IO int, то мне кашлять, что написано в документации.


ARK>А, то есть computation должно быть обязательно явно записанным, а неявно выражено оно быть не может? Это твое личное мнение?

Это так для обсуждаемых мной здесь языков. Все что там записано между строк кода морзянкой из пробелов и табуляций — оставлю экспертам в этой области.

S>>Какая цель в этом? Это поможет выполнить оптимизацию или упростить рассуждения о программах?


ARK>В чем "этом"? В изменении трактовки слов? Ну, у создателей хаскеля цель, очевидно, любой ценой натянуть сову на глобус и доказать, что у их языка грязные функции как будто чистые.

Мне это не очевидно. Но судя по тому, что это многих задевает лично — да, их хохма удалась на славу.

S>>Хорошо, твоя чистота называет функции хаскеля грязными. Но это не отменяет рассуждения и возможности оптимизации хаскеля в терминах обычной чистоты.


ARK>В том-то и дело, что отменяет. Грязные функции в хаскеле не приобретают никаких свойств чистых только от того, что их назвали таковыми. Они по-прежнему не являются ссылочно прозрачными, их невозможно выкинуть или переупорядочить. Это типичная грязь.

Можно узнать, о каких именно грязных функциях речь? putStr, например, о которой мы говорили — чистая.

S>>А что дает твой вариант кроме разоблачения хаскеля? Может быть он позволяет лучше заниматься оптимизацией в C++?


ARK>По моему мнению, он позволяет упростить рассуждение о тексте программы. Грязные функции обладают своими особенностями, которые надо учитывать. В хаскеле можно легко обосраться, вызвав IO за пределами do-нотации и получив в итоге вызовы в случайном порядке.

Это полная чушь. do-нотация это синтаксический сахар, рассахаренный код — это цепочка вызовов IO вне do-нотации. Переупорядочить их не дает именно IO, а не do-нотация.

S>>Но называя int действием ты ничего не достигаешь в плане возможностей оптимизации и уж точно ухудшаешь понимание программы.


ARK>Так и в хаскеле — называя IO "действием", мы ничего не достигаем в плане оптимизации и не улучшаем понимание программы.

Обобщение тут неуместно.
ARK>В языке D есть pure функции и обычные — всегда видно, с чем имеешь дело, однако при всем при этом грязные функции за чистые не выдаются.
Напомню, у тебя отдельное понимание чистой функции, ничего общего общепринятым определением чистоты не имеющее.

ARK>>>Каким образом из википедийного определения читателю становится ясно, что evaluation в разных языках означает совершенно разные вещи и что чистота напрямую зависит от этого?

S>>Да блин, почему они разные-то? Evaluation в С++ возвращает int и гадит в мир. В хаскле evaulation main вместо int возвращает композицию действий. Это одинаковые evaluation. Разница не в evaluation, а в организации кода.

ARK>Я понял, что для тебя камнем преткновения является синтаксическая метка. Но допустить ее неявное присутствие ты почему-то не можешь. Хотя создатель языка имеет полное право заложить любую семантику и описать ее с помощью любого синтаксиса. В том числе и неявного.

Имеет. А я имею право устраниться от обсуждения чистоты функций в языке с любой семантикой и любым синтаксисом, в том числе неявного.

S>>>>У меня суждения вполне однозначны с точностью до заранее заданного перечня сайдэффектов. Заметь, терминами evaluate/invoke я не жонглирую и оперирую лишь обозримыми сайдэффектами (зафиксированными заранее).

ARK>>>Ну вот есть обозримый сайд-эффект: печать "Hello, World". У тебя есть исполняемый файл, который печатает это предложение. У тебя есть код программы, который содержит в себе визуально видимое наименование системной функции печати с параметром "Hello, World". Что говорит твое суждение относительно чистоты данной программы, если: a) документация по языку говорит тебе, что все функции языка возвращают computation;
S>>Откуда это взялось? нет, не все функции языка возвращают computation и чисты только по этому.

ARK>Это взялось из семантики языка. Создатель определил семантику именно так — ВСЕ функции языка возвращают computation, при этом никаких синтаксических меток для этого нет.

ARK>Что говорит твое суждение, чиста программа или нет?
О каком языке речь? О сфероконическом?

ARK>>>б) документация по языку говорит тебе, что все функции языка "выполняются напрямую"?

S>>Так они напрямую и выполняются. Но если в сигнатуре функции написано что она должна вернуть структуру данных, выполнение ее приведет к возврату структуры данных (либо ошибке). С пониманием этого есть проблемы?

ARK>Без документации по языку мы не знаем, что записывается в сигнатуре функции. И что вообще означает сигнатура функции. В сигнатуре может быть голый int, но компилятор будет создавать "computation" для каждой функции (аналогия — см. checked/unchecked exception).

Вот когда C++ будет создавать computation для каждой функции, вернемся к этому вопросу.

S>>main в C++ возвращает int. main в Haskell возвращает IO a. int и IO a здесь структуры данных.


ARK>ОК, функция возвращает структуру данных QWERTY. Что говорит твое суждение, эта функция чистая или нет?

Я не сужу о чистоте по типу результата. Функция возвращающая int вполне может быть чиста, как и функция, возвращающая IO a, может быть грязной.
Re[65]: Мнение: объектно-ориентированное программирование — катастрофа на трилли
От: samius Япония http://sams-tricks.blogspot.com
Дата: 28.10.19 18:40
Оценка:
Здравствуйте, Mamut, Вы писали:

M>>>
M>>>Action main() = () => { System.sudo.remove_all_files_k_chertyam(); }
M>>>

S>>И эта функция чиста.

M>Если она чиста, почему она приводит к сайд-эффектам?


Вызов такой main не приводит к сайд эффектам.

S>>Т.е. то, что ты подверг сомнению этим примером — не мои слова, а уровень своего восприятия моих слов.


M>Нет никакого уровня восприятия слов, кроме одного:


M>

M>Она будет чиста, если не будет до возврата действия производить сайд-эффекты.


M>Это строго эквивалентно следующему:


M>

M>Хаскель из кожи вон лезет, чтобы притвориться, что он чистый, а внешнего мира не существует.

Имеешь право так считать. У меня другое мнение.
Re[72]: Мнение: объектно-ориентированное программирование — катастрофа на трилли
От: AlexRK  
Дата: 28.10.19 20:19
Оценка:
Здравствуйте, samius, Вы писали:

ARK>>Ты не можешь без документации по языку судить о чистоте написанных на нем функций. Если можешь, то скажи, является ли чистой вот эта функция: "funktion Main % print Hello World \ @Q". Что это за язык, неважно, ведь ты не будешь руководствоваться документацией при проверке чистоты.

S>Для неизвестного мне языка — даже пытаться не буду.

Отчего же? Значит, документация по языку таки нужна для суждения о чистоте написанных на нем функций?

S>>>Если при этом тип результата функции будет int, а не Task<int> или IO int, то мне кашлять, что написано в документации.

ARK>>А, то есть computation должно быть обязательно явно записанным, а неявно выражено оно быть не может? Это твое личное мнение?
S>Это так для обсуждаемых мной здесь языков. Все что там записано между строк кода морзянкой из пробелов и табуляций — оставлю экспертам в этой области.

Так все-таки: может ли _в принципе_ семантика быть выраженной неявно? Я создаю форк С++ под названием C++PURE и заявляю, что в нем семантика computation выражена неявно. И, стало быть, все его функции автоматически становятся чистыми. Верно?

S>>>Хорошо, твоя чистота называет функции хаскеля грязными. Но это не отменяет рассуждения и возможности оптимизации хаскеля в терминах обычной чистоты.

ARK>>В том-то и дело, что отменяет. Грязные функции в хаскеле не приобретают никаких свойств чистых только от того, что их назвали таковыми. Они по-прежнему не являются ссылочно прозрачными, их невозможно выкинуть или переупорядочить. Это типичная грязь.
S>Можно узнать, о каких именно грязных функциях речь? putStr, например, о которой мы говорили — чистая.

putStr невозможно заменить на значение, нельзя выкинуть при оптимизации, нельзя спекулятивно вычислить, нельзя поменять местами с другой putStr. Это типичная грязная функция.

putStr "чистая" только в случае вольной интерпретации термина "evaluation" ("считать computation результатом evaluation"). Эта интерпретация из определения чистоты НЕ следует, она записана в документации хаскеля. При стандартной интерпретации — без каких-либо дополнительных сущностей а-ля "внешний вычислитель" — putStr чистой не является.

S>>>А что дает твой вариант кроме разоблачения хаскеля? Может быть он позволяет лучше заниматься оптимизацией в C++?

ARK>>По моему мнению, он позволяет упростить рассуждение о тексте программы. Грязные функции обладают своими особенностями, которые надо учитывать. В хаскеле можно легко обосраться, вызвав IO за пределами do-нотации и получив в итоге вызовы в случайном порядке.
S>Это полная чушь. do-нотация это синтаксический сахар, рассахаренный код — это цепочка вызовов IO вне do-нотации. Переупорядочить их не дает именно IO, а не do-нотация.

Да, вот здесь я неправ. Побег из IO возможен разве что через unsafe.

ARK>>В языке D есть pure функции и обычные — всегда видно, с чем имеешь дело, однако при всем при этом грязные функции за чистые не выдаются.

S>Напомню, у тебя отдельное понимание чистой функции, ничего общего общепринятым определением чистоты не имеющее.

Нет, во всем разговоре я руководствуюсь только тем определением, которое в википедии. Так вот, в D есть разделение на чистые и нечистые функции, которое дает не меньше информации о побочных эффектах, чем хаскелевый IO.

ARK>>Я понял, что для тебя камнем преткновения является синтаксическая метка. Но допустить ее неявное присутствие ты почему-то не можешь. Хотя создатель языка имеет полное право заложить любую семантику и описать ее с помощью любого синтаксиса. В том числе и неявного.

S>Имеет. А я имею право устраниться от обсуждения чистоты функций в языке с любой семантикой и любым синтаксисом, в том числе неявного.

Имеешь. Но определение чистоты не привязано ни к какому языку, оно универсально и должно быть применимо к чему угодно. В том числе и к языкам с неявным "computation".

S>>>>>У меня суждения вполне однозначны с точностью до заранее заданного перечня сайдэффектов. Заметь, терминами evaluate/invoke я не жонглирую и оперирую лишь обозримыми сайдэффектами (зафиксированными заранее).

ARK>>>>Ну вот есть обозримый сайд-эффект: печать "Hello, World". У тебя есть исполняемый файл, который печатает это предложение. У тебя есть код программы, который содержит в себе визуально видимое наименование системной функции печати с параметром "Hello, World". Что говорит твое суждение относительно чистоты данной программы, если: a) документация по языку говорит тебе, что все функции языка возвращают computation;
S>>>Откуда это взялось? нет, не все функции языка возвращают computation и чисты только по этому.
ARK>>Это взялось из семантики языка. Создатель определил семантику именно так — ВСЕ функции языка возвращают computation, при этом никаких синтаксических меток для этого нет.
ARK>>Что говорит твое суждение, чиста программа или нет?
S>О каком языке речь? О сфероконическом?

Да, о сфероконическом. Скажи, пожалуйста, что говорит твое суждение, чиста ли программа в описанном мной случае или нет?
Надеюсь, твое суждение не ограничено строго двумя языками — хаскелем и С++?

S>>>main в C++ возвращает int. main в Haskell возвращает IO a. int и IO a здесь структуры данных.

ARK>>ОК, функция возвращает структуру данных QWERTY. Что говорит твое суждение, эта функция чистая или нет?
S>Я не сужу о чистоте по типу результата. Функция возвращающая int вполне может быть чиста, как и функция, возвращающая IO a, может быть грязной.

То есть по сигнатуре функции в хаскеле нельзя сказать, является ли функция чистой?
Тогда почему ты считаешь, что putStr — чистая функция? Так написано в документации хаскеля?
Re[65]: Мнение: объектно-ориентированное программирование — катастрофа на трилли
От: · Великобритания  
Дата: 28.10.19 20:41
Оценка: 12 (1) :)
Здравствуйте, Mamut, Вы писали:

M> M>>
M> M>>Action main() = () => { System.sudo.remove_all_files_k_chertyam(); }
M> M>>

M> S>И эта функция чиста.
M> Если она чиста, почему она приводит к сайд-эффектам?
Ты наверное что-то путаешь, абсолютизируя понятие чистоты. Говорят о чистоте именно _функций_. Эта _функция_ чиста и к сайд-эффектам не приводит. Однако, эта функция возвращает выражение, которое будет изменять внешний с т.з. _функций_ мир.
avalon/2.0.6
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[73]: Мнение: объектно-ориентированное программирование — катастрофа на трилли
От: samius Япония http://sams-tricks.blogspot.com
Дата: 28.10.19 21:34
Оценка: +1
Здравствуйте, AlexRK, Вы писали:

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


S>>Для неизвестного мне языка — даже пытаться не буду.


ARK>Отчего же? Значит, документация по языку таки нужна для суждения о чистоте написанных на нем функций?

Представления о языке — нужны. Документация, которую ты предлагаешь — нет. От такой надо держаться подальше.

S>>Это так для обсуждаемых мной здесь языков. Все что там записано между строк кода морзянкой из пробелов и табуляций — оставлю экспертам в этой области.


ARK>Так все-таки: может ли _в принципе_ семантика быть выраженной неявно? Я создаю форк С++ под названием C++PURE и заявляю, что в нем семантика computation выражена неявно. И, стало быть, все его функции автоматически становятся чистыми. Верно?

Нет, не верно. Одних заявлений о семантике недостаточно для чистоты функций.

S>>Можно узнать, о каких именно грязных функциях речь? putStr, например, о которой мы говорили — чистая.


ARK>putStr невозможно заменить на значение, нельзя выкинуть при оптимизации, нельзя спекулятивно вычислить, нельзя поменять местами с другой putStr. Это типичная грязная функция.

Ничего из перечисленного не имеет отношения к putStr и определению чистоты. С какого перепугу она стала грязной?

ARK>putStr "чистая" только в случае вольной интерпретации термина "evaluation" ("считать computation результатом evaluation"). Эта интерпретация из определения чистоты НЕ следует, она записана в документации хаскеля. При стандартной интерпретации — без каких-либо дополнительных сущностей а-ля "внешний вычислитель" — putStr чистой не является.

Ты все-таки посмотри на сигнатуру функции. Не нужно считать ее результат computation_ом, если он и есть computation. Это такая же правда, как и то, что результат main из C++ имеет тип int.

S>>Напомню, у тебя отдельное понимание чистой функции, ничего общего общепринятым определением чистоты не имеющее.


ARK>Нет, во всем разговоре я руководствуюсь только тем определением, которое в википедии.

Так покажи что есть нечистого в putStr согласно определению из википедии.
ARK>Так вот, в D есть разделение на чистые и нечистые функции, которое дает не меньше информации о побочных эффектах, чем хаскелевый IO.
Хаскелевый IO не дает информации о побочных эффектах. Ведь можно продемонстрировать функцию putStr2, которая при той же сигнатуре IO a будет генерировать computation без побочных эффектов. Смысл IO лишь в упорядочивании действий, как у точки с запятой в C++.

ARK>Имеешь. Но определение чистоты не привязано ни к какому языку, оно универсально и должно быть применимо к чему угодно. В том числе и к языкам с неявным "computation".

Хорошо, должно. Но я не достаточно хорошо представляю, что такое неявный "computation", что бы судить о чистоте языка с заявлениями автора об этом.

S>>О каком языке речь? О сфероконическом?


ARK>Да, о сфероконическом. Скажи, пожалуйста, что говорит твое суждение, чиста ли программа в описанном мной случае или нет?

ARK>Надеюсь, твое суждение не ограничено строго двумя языками — хаскелем и С++?
Я в достаточной мере владею несколькими языками, о чистоте которых могу рассуждать. Но не совсем четко представляю, что такое computation без семантических меток и какая там модель вычислений. Потому — нет, судить не могу и не хочу.

S>>Я не сужу о чистоте по типу результата. Функция возвращающая int вполне может быть чиста, как и функция, возвращающая IO a, может быть грязной.


ARK>То есть по сигнатуре функции в хаскеле нельзя сказать, является ли функция чистой?

Конечно, одна лишь сигнатура не дает оснований для заявлений о чистоте.
ARK>Тогда почему ты считаешь, что putStr — чистая функция? Так написано в документации хаскеля?
Потому, что она выполняется на стадии выполнения main, когда computation всей программы еще не построен, ему еще не передано управление. Никакого смысла там что-то пачкать нет. Потому, что реализация putStr вызывает другую IO функцию, создающую вычисление. И кроме создания вычисления на этапе выполнения putStr больше ничего не происходит. Ничего вне контекста IO, который будет создан лишь для того, что бы передать его вычислению-результату main.

void Main()
{
    Action<IO> computation = putStr("Hellow");
}

abstract class IO {}

static Action<IO> putStr(string str)
{
    return io => Console.Write(str);
}

В момент выполнения функции putStr у нас нет ни мира, ни IO экземпляра. Можно испачкать putStr? Конечно, достаточно перед return насрать в консоль. И тогда сайд эффект проявит себя еще до передачи управления computation-у. Оно это кому надо? Ради чего?
Ну и разумеется, в исходниках видно, что кроме построения computation-а в putStr ничего не происходит.
Re[73]: Мнение: объектно-ориентированное программирование — катастрофа на трилли
От: Sinclair Россия https://github.com/evilguest/
Дата: 29.10.19 06:54
Оценка:
Здравствуйте, AlexRK, Вы писали:
ARK>Так все-таки: может ли _в принципе_ семантика быть выраженной неявно? Я создаю форк С++ под названием C++PURE и заявляю, что в нем семантика computation выражена неявно. И, стало быть, все его функции автоматически становятся чистыми. Верно?
Отож. Правда, на эту работу уйдёт несколько лет, т.к. придётся очень сильно перепахать спецификацию языка, и
1. Не факт, что существующие программы на С++ продолжать компилироваться компилятором, написанным по этой новой спецификации, и
2. Не факт, что семантика существующих компилирующихся программ будет сохранена.


На всякий случай поясню очевидное: если у нас теперь любая int-функция возвращает не int, а computation, то вот такая программа:
int a()
{
  printf("Hello,");  
  return 42;
}
int b()
{
  printf(" world!);
}


int main()
{
  auto varA = a();
  auto varB = b();
  return (rand() > 50) ? varA : varB;
}


Выведет только половину фразы. Почему это так — понятно? Почему недостаточно просто "переобозвать" функции чистыми — понятно?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[65]: Мнение: объектно-ориентированное программирование — катастрофа на трилли
От: Sinclair Россия https://github.com/evilguest/
Дата: 29.10.19 07:04
Оценка:
Здравствуйте, Mamut, Вы писали:
M>Если она чиста, почему она приводит к сайд-эффектам?
Вы смотрите не туда.
Для упрощения восприятия давайте себе представим генерацию SQL-стейтментов на языке типа C#.
У нас может быть весьма-весьма сложная программа, которая занимается компоновкой SQL-батча.
Всякие условия, ветвления, циклы, ООП, прочая сложность. Но вся эта программа всего лишь порождает набор insert, update, и delete стейтментов.
Сколько бы раз мы её ни запускали, никаких изменений в базе происходить не будет. Она вообще может подключения к базе не иметь.
А вот потом, когда программа отработала, мы получаем готовый батч, который скармливаем в SQL Server, и уже он внезапно изменяет состояние базы.
Ясно, что это гораздо выгоднее, чем в каждом месте, где мы хотели сделать return from g in goods select g.Name, g.Price where g.VendorID = vendorId, сразу писать var r = db.ExecuteQuery("select g.Name, g.Price from goods g where g.VendorID = @vendorId", vendorId).
Во-первых, у нас могут быть "тупиковые" ветки, которые будут выброшены в процессе построения батча на основе условий, которые обнаружатся "в будущем".
Во-вторых, удерживать транзакцию открытой — плохо; поэтому перемежать обращения к базе с выполнением дорогостоящей client-side логики — дорого.

Ну, и в-третьих, у нас появляется феноменальная возможность выполнять регрессионное тестирование: вместо мучительных сравнений состояний базы, мы просто сравниваем тексты батчей "до" и "после".

Примерно так же поступает Хаскел с "внешним миром".
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[74]: Мнение: объектно-ориентированное программирование — катастрофа на трилли
От: AlexRK  
Дата: 29.10.19 07:06
Оценка:
Здравствуйте, samius, Вы писали:

ARK>>Отчего же? Значит, документация по языку таки нужна для суждения о чистоте написанных на нем функций?

S>Представления о языке — нужны.

Нужны для чего именно? По-моему, для работы вряд ли может быть достаточно "представления", без глубокого понимания, которое может дать только документация по языку.

S>Документация, которую ты предлагаешь — нет. От такой надо держаться подальше.


Я предлагаю спецификацию языка и описание стандартной библиотеки. Это то место, которое содержит информацию, которую невозможно или затруднительно извлечь из кода.

ARK>>putStr невозможно заменить на значение, нельзя выкинуть при оптимизации, нельзя спекулятивно вычислить, нельзя поменять местами с другой putStr. Это типичная грязная функция.

S>Ничего из перечисленного не имеет отношения к putStr и определению чистоты. С какого перепугу она стала грязной?

Перечисленное — это не определение чистоты, это следствие чистоты. Ничего из этого сделать с putStr нельзя, посему она не имеет никаких преимуществ чистых функций.

S>Так покажи что есть нечистого в putStr согласно определению из википедии.


Согласно определению в википедии, функция является грязной, если ее "evaluation" вызывает "performing IO". Я считаю, что "evaluation" функции "putStr" вызывает "performing IO", поэтому она грязная.

Ты трактуешь слово "evaluation" как создание computation. Но это жонглирование терминами. Потому что ты не можешь отличить "прямое evaluation" и "создание computation". На C# я могу создать computation и вызвать его, когда хочу. В хаскеле у меня нет выбора — ты можешь говорить, что создаешь computation, но нет разницы с тем, чтобы назвать это просто грязной функцией.

Вот программа:
import System.IO
import System.IO.Unsafe

test :: [Char]
test = unsafePerformIO $ do
    putStrLn "CCC"
    return "BBB"

main = do
    putStrLn "AAA"
    content <- getLine
    putStrLn test
    content <- getLine
    putStrLn content


Вывод:

GHCi, version 8.6.5

AAA
33
CCC
BBB
2
=> 2


Так вот, если бы СНАЧАЛА на экран вывелось бы "CCC", которое идет через unsafePerformIO, то я бы согласился, что есть "промежуточный этап" — создание computation:
1) в момент создания computation выполняется unsafePerformIO и на экран выводится "CCC";
2) ЗАТЕМ внешний вычислитель выполняет созданный computation, и на экране появляется "AAA".

Но это не так. Создание computation — это фикция.

ARK>>То есть по сигнатуре функции в хаскеле нельзя сказать, является ли функция чистой?

S>Конечно, одна лишь сигнатура не дает оснований для заявлений о чистоте.

Хорошо, зафиксируем этот момент.

ARK>>Тогда почему ты считаешь, что putStr — чистая функция? Так написано в документации хаскеля?

S>Потому, что она выполняется на стадии выполнения main, когда computation всей программы еще не построен, ему еще не передано управление. Никакого смысла там что-то пачкать нет. Потому, что реализация putStr вызывает другую IO функцию, создающую вычисление. И кроме создания вычисления на этапе выполнения putStr больше ничего не происходит. Ничего вне контекста IO, который будет создан лишь для того, что бы передать его вычислению-результату main.
S>Ну и разумеется, в исходниках видно, что кроме построения computation-а в putStr ничего не происходит.

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

Тогда такой вопрос: каким образом, глядя в исходники, ты понимаешь, что функция putStr чиста? Она не вызывает никаких "грязных" функций, не так ли?
Re[74]: Мнение: объектно-ориентированное программирование — катастрофа на трилли
От: AlexRK  
Дата: 29.10.19 07:14
Оценка:
Здравствуйте, Sinclair, Вы писали:

ARK>>Так все-таки: может ли _в принципе_ семантика быть выраженной неявно? Я создаю форк С++ под названием C++PURE и заявляю, что в нем семантика computation выражена неявно. И, стало быть, все его функции автоматически становятся чистыми. Верно?

S>Отож.

Странно, а samius говорит, что нет.

S>На всякий случай поясню очевидное: если у нас теперь любая int-функция возвращает не int, а computation, то вот такая программа:

S>
int a()
S>{
S>  printf("Hello,");  
S>  return 42;
S>}
S>int b()
S>{
S>  printf(" world!);
S>}


S>int main()
S>{
S>  auto varA = a();
S>  auto varB = b();
S>  return (rand() > 50) ? varA : varB;
S>}


S>Выведет только половину фразы. Почему это так — понятно? Почему недостаточно просто "переобозвать" функции чистыми — понятно?


Нет, не понятно по обоим пунктам.

Получившийся код эквивалентен следующему (псевдокод):
int main(IO io) -> (IO, int)
{
  auto (varA, io1) = a(io);
  auto (varB, io2) = b(io1);
  return (io2, (rand() > 50) ? varA : varB);
}


Понятно, почему будет выведена фраза целиком? Понятно, почему _достаточно_ "переобозвать" функции чистыми?
Re[66]: Мнение: объектно-ориентированное программирование — катастрофа на трилли
От: Mamut Швеция http://dmitriid.com
Дата: 29.10.19 09:11
Оценка:
S>Вызов такой main не приводит к сайд эффектам.

Не приводит, а все файлы в системе удаляются через sudo. Парадокс-с


dmitriid.comGitHubLinkedIn
Re[66]: Мнение: объектно-ориентированное программирование — катастрофа на трилли
От: Mamut Швеция http://dmitriid.com
Дата: 29.10.19 09:36
Оценка: +2
·>Ты наверное что-то путаешь, абсолютизируя понятие чистоты. Говорят о чистоте именно _функций_. Эта _функция_ чиста и к сайд-эффектам не приводит. Однако, эта функция возвращает выражение, которое будет изменять внешний с т.з. _функций_ мир.

Я про это и говорю: Хаскель из кожи вон лезет, чтобы притвориться, что он чистый, а внешнего мира не существует.

Функция чистая, сайд эффектов нет, а в итоге сайд эффекты проявляются. Потому что если сильно зажмурить глаза, назвать внешний мир экшнами и притвориться, что наш язык не имеет к этим экшнам никакого отношения, то можно назвать язык чистым. Ведь это не функции меняют мир, как мы могли подумать, а некий магический внешний экзекьютор.

Так любой язык является чисто функциональным.


dmitriid.comGitHubLinkedIn
Re[67]: Мнение: объектно-ориентированное программирование —
От: · Великобритания  
Дата: 29.10.19 09:39
Оценка:
Здравствуйте, Mamut, Вы писали:


M>·>Ты наверное что-то путаешь, абсолютизируя понятие чистоты. Говорят о чистоте именно _функций_. Эта _функция_ чиста и к сайд-эффектам не приводит. Однако, эта функция возвращает выражение, которое будет изменять внешний с т.з. _функций_ мир.

M>Я про это и говорю: Хаскель из кожи вон лезет, чтобы притвориться, что он чистый, а внешнего мира не существует.
Это только в твоём воображении.

M>Функция чистая, сайд эффектов нет, а в итоге сайд эффекты проявляются.

Ты говоришь как будто это что-то плохое.

M>Потому что если сильно зажмурить глаза, назвать внешний мир экшнами и притвориться, что наш язык не имеет к этим экшнам никакого отношения, то можно назвать язык чистым. Ведь это не функции меняют мир, как мы могли подумать, а некий магический внешний экзекьютор.

Язык называют чистым, т.к. по спеке там функции — чистые, просто терминология такая. Ты же обобщаешь чистоту как некую самоцель и она должна быть вообще везде. Это бред.

Чистота функций это же не самоцель, а такое свойство функций, которое позволяет ими манипулировать определённым образом с сохранением определённых гарантий.

M>Так любой язык является чисто функциональным.

Не является.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Отредактировано 29.10.2019 9:42 · . Предыдущая версия .
Re[66]: Мнение: объектно-ориентированное программирование — катастрофа на трилли
От: Mamut Швеция http://dmitriid.com
Дата: 29.10.19 09:43
Оценка: +2
S>Примерно так же поступает Хаскел с "внешним миром".

Всю эту аргументацию я знаю. Вся она сводится, по сути к «кто и когда в итоге выполняет код
Автор: Mamut
Дата: 29.10.19
».

Возвращаясь к

Грубо говоря, функция вида

Action main() = () => { Console.WriteLine("Hello"); }


чиста, т.к. не делает побочных эффектов


Если мы скомпилируем эту функцию и запустим получившуюся программу, мы будем наблюдать сайд-эффект. Хаскелисты при этом утверждают, что Хаскель не виноват. Есть какой-то внешний экзекьютор, который, конечно, к Хаскелю не имеет отношения, но без которого Хаскель не существует, как язык, который и занимается выполнением этих экшнов. Но тогда любая программа — чистый ФП. Потому никаких сайд эффектов не происходит ровно до момента запуска программы сторонним экзекьютором.


dmitriid.comGitHubLinkedIn
Re[66]: Мнение: объектно-ориентированное программирование — катастрофа на трилли
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 29.10.19 09:57
Оценка:
Здравствуйте, samius, Вы писали:

S>Это подход (один из), позволяющий писать абсолютно чистые программы. И я не могу запретить называть его мастурбацией, если так нравится.

S>Надеюсь, разобрались с отрицанием существования чистых программ.

Абсолютно чистая — это без IO ? Или под этим подразумевается "чуточку грязная" ?
Re[67]: Мнение: объектно-ориентированное программирование — катастрофа на трилли
От: MadHuman Россия  
Дата: 29.10.19 10:08
Оценка:
Здравствуйте, Mamut, Вы писали:


M>Я про это и говорю: Хаскель из кожи вон лезет, чтобы притвориться, что он чистый, а внешнего мира не существует.

и да и нет.

M>Функция чистая, сайд эффектов нет, а в итоге сайд эффекты проявляются. Потому что если сильно зажмурить глаза, назвать внешний мир экшнами и притвориться, что наш язык не имеет к этим экшнам никакого отношения, то можно назвать язык чистым. Ведь это не функции меняют мир, как мы могли подумать, а некий магический внешний экзекьютор.


в хаскеле не экшинами внешний мир меняется, там чистая функция на вход принимает RealWorl и на выходе возвращает новый инстанс RealWorl как бы модифицированный ею относительно входного. ментальная модель именно такая.
далее придуманы разные штуки (монады, do-нотация) для упрощения работы таким образом.
вообщем-то интересный трюк чтоб сохранить чистость функций.
Re[75]: Мнение: объектно-ориентированное программирование — катастрофа на трилли
От: Sinclair Россия https://github.com/evilguest/
Дата: 29.10.19 10:09
Оценка:
Здравствуйте, AlexRK, Вы писали:
ARK>Странно, а samius говорит, что нет.
Он более строг к формулировке утверждения "функция чиста".

S>>На всякий случай поясню очевидное: если у нас теперь любая int-функция возвращает не int, а computation, то вот такая программа:

S>>
int a()
S>>{
S>>  printf("Hello,");  
S>>  return 42;
S>>}
S>>int b()
S>>{
S>>  printf(" world!);
S>>}


S>>int main()
S>>{
S>>  auto varA = a();
S>>  auto varB = b();
S>>  return (rand() > 50) ? varA : varB;
S>>}


S>>Выведет только половину фразы. Почему это так — понятно? Почему недостаточно просто "переобозвать" функции чистыми — понятно?


ARK>Нет, не понятно по обоим пунктам.

Спрашивайте, что именно непонятно.

ARK>Получившийся код эквивалентен следующему (псевдокод):

ARK>
ARK>int main(IO io) -> (IO, int)
ARK>{
ARK>  auto (varA, io1) = a(io);
ARK>  auto (varB, io2) = b(io1);
ARK>  return (io2, (rand() > 50) ? varA : varB);
ARK>}
ARK>


ARK>Понятно, почему будет выведена фраза целиком?

Понятно.
ARK>Понятно, почему _достаточно_ "переобозвать" функции чистыми?
В том-то и дело, что если бы функции возвращали вычисление, то вся фраза бы не выводилась. У нас была бы возможность вычислить только то из вычислений, которое нам нужно.
Ваша программа не позволяет скомпоновать вычисления сколь-нибудь другим способом, чем указанный порядок исполнения.
Поэтому подобное изменение спецификации С++ бессмысленно. А хаскелл тем временем вводит практически полезное определение чистоты функций.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[67]: Мнение: объектно-ориентированное программирование — катастрофа на трилли
От: Sinclair Россия https://github.com/evilguest/
Дата: 29.10.19 10:20
Оценка:
Здравствуйте, Mamut, Вы писали:

M>Если мы скомпилируем эту функцию и запустим получившуюся программу, мы будем наблюдать сайд-эффект. Хаскелисты при этом утверждают, что Хаскель не виноват. Есть какой-то внешний экзекьютор, который, конечно, к Хаскелю не имеет отношения, но без которого Хаскель не существует, как язык, который и занимается выполнением этих экшнов. Но тогда любая программа — чистый ФП. Потому никаких сайд эффектов не происходит ровно до момента запуска программы сторонним экзекьютором.

Не совсем. Хаскел — это попытка официально разделить программы на "чистую" и "грязную" части, чтобы можно было безопасно рассуждать хотя бы об одной из этих частей.
Ну, вот продолжая нашу аналогию с SQL — понятно, что не всякая программа может построить полный батч "с нуля", не заглядывая в БД.
Но мы можем построить её так, что все точки взаимодействия с СУБД явно выделены, и вместо каши с перемешанными вызовами db.ExecuteXXX, внешних веб сервисов, и тяжёлых вычислительных задач, мы имеем явную цепочку readFromDb-Compute->readFromDb->Compute->WriteToDB.
Это по-прежнему предоставляет полезные гарантии по сравнению с лапшой. В частности, что джуниор не сможет вставить внезапное чтение или запись в середину очередного Compute и, например, поставить СУБД раком из-за дедлока.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[76]: Мнение: объектно-ориентированное программирование — катастрофа на трилли
От: AlexRK  
Дата: 29.10.19 10:21
Оценка:
Здравствуйте, Sinclair, Вы писали:

ARK>>Получившийся код эквивалентен следующему (псевдокод):

ARK>>
ARK>>int main(IO io) -> (IO, int)
ARK>>{
ARK>>  auto (varA, io1) = a(io);
ARK>>  auto (varB, io2) = b(io1);
ARK>>  return (io2, (rand() > 50) ? varA : varB);
ARK>>}
ARK>>


ARK>>Понятно, почему _достаточно_ "переобозвать" функции чистыми?

S>В том-то и дело, что если бы функции возвращали вычисление, то вся фраза бы не выводилась. У нас была бы возможность вычислить только то из вычислений, которое нам нужно.

Почему же, именно что при возврате вычислений все равно выводится фраза целиком. Ведь вызовы a и b имеют теперь зависимость друг от друга через IO.

S>Ваша программа не позволяет скомпоновать вычисления сколь-нибудь другим способом, чем указанный порядок исполнения.


Верно. Как и в хаскеле для всех функций с IO.

S>Поэтому подобное изменение спецификации С++ бессмысленно.


Подобное изменение спецификации С++ приведет к тому, что _формально_ все функции будут считаться чистыми. Что, на мой взгляд, есть лютый бред, обесценивающий все понятие чистоты функций.

S>А хаскелл тем временем вводит практически полезное определение чистоты функций.


Разница с хаскелем состоит только в том, что в хаскеле еще есть и "действительно чистые" функции, для которых возможны все полезные оптимизации и рассуждения. Вопрос состоит в том, зачем "онанировать вприсядку" (с), называя грязные функции чистыми, когда можно просто явно выделить чистые функции, как в D.
Re[68]: Мнение: объектно-ориентированное программирование — катастрофа на трилли
От: AlexRK  
Дата: 29.10.19 10:25
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Ну, вот продолжая нашу аналогию с SQL — понятно, что не всякая программа может построить полный батч "с нуля", не заглядывая в БД.

S>Но мы можем построить её так, что все точки взаимодействия с СУБД явно выделены, и вместо каши с перемешанными вызовами db.ExecuteXXX, внешних веб сервисов, и тяжёлых вычислительных задач, мы имеем явную цепочку readFromDb-Compute->readFromDb->Compute->WriteToDB.

Для этого не обязательно делать то самое вприсядку, достаточно ввести понятие "pure function" (или наоборот — "io function"). Часть функций чистая, часть грязная. Все ОК.
Re[75]: Мнение: объектно-ориентированное программирование — катастрофа на трилли
От: samius Япония http://sams-tricks.blogspot.com
Дата: 29.10.19 10:52
Оценка:
Здравствуйте, AlexRK, Вы писали:

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


S>>Представления о языке — нужны.


ARK>Нужны для чего именно? По-моему, для работы вряд ли может быть достаточно "представления", без глубокого понимания, которое может дать только документация по языку.


Ты прав, документация нужна.

S>>Документация, которую ты предлагаешь — нет. От такой надо держаться подальше.


ARK>Я предлагаю спецификацию языка и описание стандартной библиотеки. Это то место, которое содержит информацию, которую невозможно или затруднительно извлечь из кода.

Первое твое предложение было таким: давайте ка заявим что там вместо int неявные computation. Такая документация заведомо противоречит другой документации того же языка и модели вычислений. Значит, одна из них будет врать.

ARK>>>putStr невозможно заменить на значение, нельзя выкинуть при оптимизации, нельзя спекулятивно вычислить, нельзя поменять местами с другой putStr. Это типичная грязная функция.

S>>Ничего из перечисленного не имеет отношения к putStr и определению чистоты. С какого перепугу она стала грязной?

ARK>Перечисленное — это не определение чистоты, это следствие чистоты. Ничего из этого сделать с putStr нельзя, посему она не имеет никаких преимуществ чистых функций.

Здесь ты говоришь не о putStr, а о том, что она возвращает.

S>>Так покажи что есть нечистого в putStr согласно определению из википедии.


ARK>Согласно определению в википедии, функция является грязной, если ее "evaluation" вызывает "performing IO". Я считаю, что "evaluation" функции "putStr" вызывает "performing IO", поэтому она грязная.

Чуть ниже....

ARK>Ты трактуешь слово "evaluation" как создание computation. Но это жонглирование терминами. Потому что ты не можешь отличить "прямое evaluation" и "создание computation". На C# я могу создать computation и вызвать его, когда хочу. В хаскеле у меня нет выбора — ты можешь говорить, что создаешь computation, но нет разницы с тем, чтобы назвать это просто грязной функцией.


ARK>Вот программа:

ARK>
ARK>import System.IO
ARK>import System.IO.Unsafe

ARK>test :: [Char]
ARK>test = unsafePerformIO $ do
ARK>    putStrLn "CCC"
ARK>    return "BBB"

ARK>main = do
ARK>    putStrLn "AAA"
ARK>    content <- getLine
ARK>    putStrLn test
ARK>    content <- getLine
ARK>    putStrLn content
ARK>


ARK>Вывод:

ARK>

ARK>GHCi, version 8.6.5

ARK>AAA
ARK> 33
ARK>CCC
ARK>BBB
ARK> 2
ARK>=> 2


ARK>Так вот, если бы СНАЧАЛА на экран вывелось бы "CCC", которое идет через unsafePerformIO, то я бы согласился, что есть "промежуточный этап" — создание computation:

ARK>1) в момент создания computation выполняется unsafePerformIO и на экран выводится "CCC";
ARK>2) ЗАТЕМ внешний вычислитель выполняет созданный computation, и на экране появляется "AAA".

ARK>Но это не так. Создание computation — это фикция.


Вот здесь я должен сказать тебе спасибо. Даже не так, а СПАСИБО! Без иронии и сарказма. Твой пример кода заставил меня обратиться к документации и переосмыслить свое понимание. Ну а до этого толкнул штангу, в связи с чем должен принести извинения перед участниками за попытки (местами успешные) ввести в заблуждение. Относительно причин чистоты putStr.

Action в том виде, в котором я представлял реализацию putStr на C#, обладает фатальным недостатком. Он не может быть построен перед выполнением main, т.к. то значение строки, которое он должен вывести в консоль, может быть получено в результате работы программы. Оно не известно до начала проигрывания главного computation, точнее, не всегда известно.

Причины формальной чистоты putStr заключаются в частичном применении. Т.е. принимая строку в качестве единственного своего аргумента, она возвращает грязную функцию IO(), которая возьмет world1 и вернет world2, который уже со строкой в консоли.
Action никуда не делся. Я ошибался в месте и времени его формирования. Конечно, он формируется внутри цепочки action-ов main, а не заранее.

ARK>>>То есть по сигнатуре функции в хаскеле нельзя сказать, является ли функция чистой?

S>>Конечно, одна лишь сигнатура не дает оснований для заявлений о чистоте.

ARK>Хорошо, зафиксируем этот момент.


ARK>>>Тогда почему ты считаешь, что putStr — чистая функция? Так написано в документации хаскеля?

S>>Потому, что она выполняется на стадии выполнения main, когда computation всей программы еще не построен, ему еще не передано управление. Никакого смысла там что-то пачкать нет. Потому, что реализация putStr вызывает другую IO функцию, создающую вычисление. И кроме создания вычисления на этапе выполнения putStr больше ничего не происходит. Ничего вне контекста IO, который будет создан лишь для того, что бы передать его вычислению-результату main.
Сорри, это бред ^^^^^^

S>>Ну и разумеется, в исходниках видно, что кроме построения computation-а в putStr ничего не происходит.


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

Судить могу, но как показывает опыт, не вполне адекватно. Заключение мое верно, но не его обоснование.

ARK>Тогда такой вопрос: каким образом, глядя в исходники, ты понимаешь, что функция putStr чиста? Она не вызывает никаких "грязных" функций, не так ли?

Не вызывает, хотя и создает грязный action, чернее мазута.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.