Pull to refresh
@commenterread⁠-⁠only

User

Send message
Хотя сам несколько зациклился — вроде нужны абстракции, но понимать хочу императивно, то есть без абстракций. Здесь видимо нужен компромисс. И этот компромисс проще находить в императивном выражении, когда уровень абстракций находится недалеко от уровня исполнения. А когда компилятор за меня додумывает массу деталей, вот тогда могут начаться пляски с бубном.
Под константой я понимаю выражение, определение значения которого не требует вычислений. В данном случае определение значения fibonachi вычислений требует и потому константой не является.
Я как раз и оперирую только абстрактными понятиями.

А откуда же берутся значения констант? Их кто-то обязательно вычисляет, самый минимум — переводит текст в число.

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

Мне не до фонаря. Я предпочитаю понимать, именно императивно, что там происходит. Потому что если понимать поверхностно — всегда найдётся случай, когда «понимание» оказывается непониманием.
В ведь понимаете разницу между константой и функцией без аргументов?

Понимаю не совсем так, как вы.

Мы декларируем некий идентификатор и указываем, что он равен значению, возвращаемому функцией. Наверняка вы читали статейки на тему «eqational reasoning», там как раз именно с такой точки зрения всё рассматривается. И выходит очень логично и очень математично. Мне тоже нравится такой подход.

Ну а если рассматривать реализацию, то вы тоже не сможете сказать что-то определённое до того момента, пока не изучите исходный код компилятора. Поэтому остаётся пользоваться абстракциями. Вот я и предлагаю использовать математические абстракции. В частности — константы, функции, уравнения. Вы же предлагаете смотреть на процесс исполнения кода, который скрыт внутри кода компилятора. То есть вы предлагаете пользоваться неявным знанием, а я же предлагаю использовать строгие и понятные со школы определения.
С функциональной точки зрения программа — не последовательность вызовов функций, а одна большая функция, которую нужно не «вычислить» в привычном нам понимании, а «упростить» с учетом того, какие значения получили ее переменные.

Ну опять же получается более сложная конструкция. Есть императивное (привычное) понимание. Есть школьно-математическое (функции, уравнения, константы). И есть лямбда-исчисление. Вы предлагаете смотреть на код как на пример лямбда-исчисления, но как раз при этом возникает та самая сложность. И зачем она?

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

Если вы о ленивости (как в статье, рассматривая её как часть лямбда-исчисления), то опять же, абстракция «частичного вычисления» внутри компилятора применима редко из-за сложности такого вычисления. А вот функция, у которой известен неполный набор аргументов — это гораздо более понятная абстракция, не требующая обязательных вычислений и простая в использовании. И я не уверен, что компиляторы идеально соответствуют именно принятой в лямбда-исчислении абстракции, а потому можно ошибиться, если начинать продумывать, до какого момента что-то там частично вычислено. И это тоже аргумент против вашей точки зрения.
Тем, что это не присвоение, а определение функции.

А чем тогда вас не устраивает определение константы? Её ведь тоже определяют.
Присвоения в ленивых языках как такового нет, поскольку это чистой воды побочный эффект.

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

Хотя если придираться к определениям, то в данном случае, согласен, не присвоение, а определение константы с указанием её значения, вычисляемого функцией.
И в этой строчке она не вызывается.

Ну ладно, не в этой строчке. Так вас устроит? Или вы считаете, что функции вообще не вызываются?
А творческая работа по изучению монад, do notation и прочего использованного в вашем коде? Ну и само введение поддержки do notation на уровне компилятора есть прямой путь к императивному стилю, но в функциональном языке.

Плюс можно поспорить с деталями реализации, но я в данном случае просто не понял происходящего. Вы использовали какое-то чудо вроде мутабельной монады? Что это за M? Ну и по другим моментам мне нужно лезть в справочник и разбираться (давно уже перестал интересоваться хаскелем).

Из того, что очевидно — в императивном языке достаточно массивов или списков, а у вас ещё монады. Само определение функции там проще (только вход-выход). Ну и функции у М явно не «один в один» с императивными языками, что опять усложняет понимание (не знаю, правда, сколь широко подобные функции используются активно пишущими на хаскеле, но я их не встречал, когда его изучал).
Все-таки нет, это функция

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

Определение «естественности образа» опять же получится размытым, поэтому и разделение концепций не выйдет.

Есть более базовые понятия, вроде рекурсии, вот они поддаются точному определению, а стиль изложения алгоритма — весьма зыбкая сущность.
Статья неплохая, но всё же присутствует однобокость. Качественный подход предполагает нечто более многостороннее. Вот примеры:
Функция fibonachi (а это именно функция) порождает бесконечный список чисел

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

Здесь неопытнй читатель наверняка подумает, что функциональные языки «лучше», раз автор так уверенно говорит про «требует дополнительной творческой работы». Но на самом деле ФП тоже «требует дополнительной творческой работы» во всех случаях, когда нужно просто последовательно (в императивном стиле) изложить алгоритм. И здесь важно сказать явно — императивный и функциональный — это лишь стили. Да, в каких-то местах они требуют поддержки компилятора (то есть без костылей абстракции не работают), но тем не менее — это лишь стили изложения алгоритмов, ну а та часть, что «излагается» компилятором, успешно может быть реализована и на самом языке (в рамках стиля), но потребует больших приложенных усилий.

И если понять, что всё это — лишь разговор о стилях, то и само противостояние ФП — ИП сразу становится противостоянием «стилистов». Либо тех, кто не понимает, с чем имеет дело.
Тезис: Функциональная программа — программа, состоящая из чистых функций

Здесь лучше не приводить «тезисы», взятые из обсуждений одних «знатоков» с другими. Изначально ФП ориентировалось на лямбда-исчисление (по сути — прямая реализация), значит можно попробовать его определить именно через поддержку операций лямбда-исчисления. Но потом к нему добавили расширений, что несколько размыло определение. И хотя расширения логически вытекают из положенного в основу лямбда-исчисления, но всё же само лямбда-исчисление было ограничено (бесконечных теорий не бывает), а потому, не смотря на дальнейшие логические связи, возможно, стоит строить определение ФП именно на основе соответствия лямбда-исчислению. Но тогда определение станет непонятным большинству потенциальных пользователей продукта «язык программирования». Значит стоит выделить некую характерную часть лямбда-исчисления, как например в статье выделена частичная редукция, и как следует её «разжевать». Правда и тогда опять будут ссылки на то, что «из этого логически вытекает ленивость».

То есть в целом я бы просто поставил проблему — дать по возможности однозначное (не допускающее множества толкований и расширений) определение ФП. И, поработав над таким определением, ФП-сообщество вполне могло бы самостоятельно прийти к идее стиля, который отличает одну программу от другой лишь личными пристрастиями конкретного программиста.
12 ...
8

Information

Rating
Does not participate
Registered
Activity