Здравствуйте, novitk, Вы писали:
N>Очень интересно,
спасибо!
N>но имхо мало место уделенно lisp-у. Или без статики жизни нет?
типа того, это история довольно специфического подмножества фя. в предисловии более подробно написано почему это не история лиспа, но вообще про лисп там довольно много написано. в основном, правда, для объяснения того, почему нельзя было вот так просто взять компилятор лиспа и использовать для имплементации фя из этого специфического подмножества.
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Здравствуйте, Klapaucius, Вы писали:
K>типа того, это история довольно специфического подмножества фя. в предисловии более подробно написано почему это не история лиспа, но вообще про лисп там довольно много написано. в основном, правда, для объяснения того, почему нельзя было вот так просто взять компилятор лиспа и использовать для имплементации фя из этого специфического подмножества.
Прочитал только самое начало. Надеюсь потом найти время, чтобы дочитать. Это большой труд. Спасибо, что поделился с нами!
В защиту лиспа (который CL). Может быть, у тебя в статье есть.
Простейшие АТД легко пишутся на CL средствами самого языка. Что-то типа такого (слегка измененный мой собственный код):
То есть, тип данных — это просто тегированный список, где в начале сидит ключевое слово (тег), а поля сидят по plist. При сопоставлении с образцом вытаскиваем тег, натравливаем ecase, а потом вытаскиваем данные через destructuring-bind. Это покрывают многие и многие случаи, хотя немного многословно.
Я так понимаю, что АДТ — это одно из твоих личных требований к твоему личному пониманию ФЯ. И вот, АДТ хоть в каком-то варианте, но есть. Пусть в очень упрощенном, но есть. Покрывает 90% вариантов использования.
Тут нужно понимать, что та же clojure очень и очень многое взяла из CL. Если не считать специфическую работу с состоянием, то clojure гораздо ближе по духу тому же CL, чем к scheme (как минимум внешне, но без CLOS, да и контейнеры иммутабельны). В clojure очень сильно чувствуется наследие CL. Там сохранили очень бережное отношение к CL. А я так понимаю, что ни у кого не будет возражений считать clojure как ФЯ (из-за особенностей работы с состоянием. Говоря проще, чем больше вставляют палок в колеса при работе с мутабельным состоянием, тем больше шансов считать язык ФЯ. И тут у того же ocaml и F# все не так просто, а про Scala я вообще молчу, где ООП с мутабельным состоянием встречается не реже, чем ФП. Если бы не иммутабельные коллекции, то я даже не знаю, как много бы осталось в этих языках от ФЯ).
Здравствуйте, Klapaucius, Вы писали:
K>типа того, это история довольно специфического подмножества фя. в предисловии более подробно написано почему это не история лиспа, но вообще про лисп там довольно много написано. в основном, правда, для объяснения того, почему нельзя было вот так просто взять компилятор лиспа и использовать для имплементации фя из этого специфического подмножества.
Более того, критерии того, что считать ФЯ, а что не считать, они не отлиты еще в бронзе.
Допустим, мы вполне можем считать за ФЯ тот язык, где есть полная оптимизация хвостового вызова. А чем не критерий? Да, и не сильно разойдется с привычным списком языков ФП.
Так вот, в такой реализации Common Lisp как SBCL есть полноценная оптимизация хвостового вызова. Это означает, что бесконечный цикл, записанный через макрос cl-cont, будет работать бесконечно долго в этой реализации CL.
Для сравнения, в clojure и Scala никакой бесконечный цикл, записанный через CPS (continuation passing style), работать бесконечно долго не может, и скорее всего, что никогда не будет. Там просто сожрет весь стек. Кстати, пожалуй, это главная причина, почему в Scala прикрыли плагин продолжений.
Так что, не будем делать окончательных выводов. Впрочем, у тебя свое собственное определение ФЯ. Скажем, язык такой-то удовлетворяет необходимым требованиям называться "ФЯ по Клапацию". Вот, к такому определению у меня вопросов никаких нет
Здравствуйте, dsorokin, Вы писали:
D>Я так понимаю, что АДТ — это одно из твоих личных требований к твоему личному пониманию ФЯ.
Это требование к тому, чтоб принадлежать к семейству языков, которое обычно называют "ML-подобные". Но решил писать историю в первую очередь языков этого семейства решил лично я. Почему — я объяснил в предисловии.
D>А я так понимаю, что ни у кого не будет возражений считать clojure как ФЯ
Конечно. Но сегодня большая часть языков — ФЯ. В этом-то и проблема. Писать историю почти всех языков достаточно подробно — это слишком много работы. В предисловии я так и написал.
'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
Здравствуйте, dsorokin, Вы писали:
D>Более того, критерии того, что считать ФЯ, а что не считать, они не отлиты еще в бронзе.
Конечно. Я так и написал.
D>Так вот, в такой реализации Common Lisp как SBCL есть полноценная оптимизация хвостового вызова.
И я, кстати, пишу про историю SBCL (пока того, от чего он произошел, потому что сейчас пишу про вторую половину 80-х), как и про значительную часть лиспов, которые имеют отношение к функциональному программированию даже в довольно широком смысле. Но это не основная тема истории.
D>Впрочем, у тебя свое собственное определение ФЯ. Скажем, язык такой-то удовлетворяет необходимым требованиям называться "ФЯ по Клапацию". Вот, к такому определению у меня вопросов никаких нет
Я прямо в начале указал, что пишу в основном про определенное, специфическое подмножество ФЯ, как обычно и делают те, кто пишет про историю ФЯ, но назвал это подмножество не в честь себя, конечно, а в честь Эдинбурга.
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Здравствуйте, Klapaucius, Вы писали:
D>>Впрочем, у тебя свое собственное определение ФЯ. Скажем, язык такой-то удовлетворяет необходимым требованиям называться "ФЯ по Клапацию". Вот, к такому определению у меня вопросов никаких нет
K>Я прямо в начале указал, что пишу в основном про определенное, специфическое подмножество ФЯ, как обычно и делают те, кто пишет про историю ФЯ, но назвал это подмножество не в честь себя, конечно, а в честь Эдинбурга.
Да чего скромничать? Ты же фигура очень известная в узких кругах!
Ладно, постараюсь найти время прочитать все.
Тут такая фишка. Что чем больше знакомишься с этими ФЯ, чем больше на них пишешь программ, то тем размытее границы становятся. По крайней мере, у меня так. После шока от первого знакомства с Хаскелем, потом как-то все более-менее устаканивается, и уже нет таких резких суждений, не видно резких границ. И уже не хочется кидаться копьями за чистоту идей ФП. По сравнению со многими другими живыми языками ФЯ тот же CL не так и сильно вырывается вперед в уходе от идеи о чистом ФП. Но тут, наверное, очень большую роль в отлучении CL от сонма языков ФЯ сыграли сами лисперы, а почему — это уже тема отдельной дискуссии.
Вообще, я тут такую вещь скажу. Вот есть в Scala фьючи. Так вот, эти фьючи чаще всего используют как stateful даже там, где можно как stateless. То есть, первый подход ближе к ООП, и используют чаще его даже там, где можно было и написать в более функциональном стиле через stateless. Поэтому все эти деления на черное и белое — это все-таки больше умозрительная вещь, хотя, конечно, каждый язык имеет тенденцию к преобладающему использованию тем или иным стилем, но именно тенденцию, а не жесткое правило.