1
Fork 0
mirror of https://github.com/thegeneralist01/fphistoryru synced 2026-01-10 14:10:24 +01:00

july upd.

This commit is contained in:
klapaucius 2025-08-10 01:16:29 +05:00
parent 9e267eb7cb
commit e73f9e2cb2
2 changed files with 287 additions and 19 deletions

304
hopes.md
View file

@ -20,6 +20,17 @@
- [Façadisme](#façadisme)
- [Fasadrenovering](#fasadrenovering)
- [Standard ML 85.9](#standard-ml-859)
- [Le ML](#le-ml)
- [Неравенство уравнений](#неравенство-уравнений)
- [Edinburgh ML, SML/NJ, ML Kit](#edinburgh-ml-smlnj-ml-kit)
- [ANU ML](#anu-ml)
- [Poly/ML](#polyml)
- [POPLOG ML](#poplog-ml)
- [Rutherford ML](#rutherford-ml)
- [Да, fib](#да-fib)
- [Пираты Кремниевой Долины](#пираты-кремниевой-долины)
- [Дети Дюны](#дети-дюны)
- [Отец с атомным сердцем](#отец-с-атомным-сердцем)
- [Литература](#литература)
@ -376,7 +387,7 @@ map (fun x. x + y, [1; 2; 3]) where y <- 2
Это, по видимому, означает, что может труд и коллективный, но с явным лидером. Скорее, как работа над CPL, но не как работа над Common Lisp, которую направлял "Квинкивират", он же "Банда пяти".
Это, конечно, не какая-то особенность разработки языка, которая мешает считать, что язык разработан комитетом. Или мешает языку являться языком, разработанным комитетом. Не стоит и преувеличивать желание Милнера направлять разработку.
Существует более сильный и необычный довод в пользу того, чтоб не считать SML языком, разработанным комитетом. Но к тому, какое желание Милнера, наоборот, не стоит приуменьшать и чем на самом деле является SML мы вернемся позднее. Когда будем писать о временах, в которых все это оказывало более существенное влияние на развитие SML.
С помощью "некомитета" Милнер, в июне 83-го подготовил второй черновик описания SML [Miln83b]. Пока писал его, Милнер "убедился, что проблемы ML можно исправить сохранив характер ML". И что из себя представляет этот самый "характер ML"? Опять таки, не совсем ожидаемо, но это HOPE.
С помощью "не-комитета" Милнер, в июне 83-го подготовил второй черновик описания SML [Miln83b]. Пока писал его, Милнер "убедился, что проблемы ML можно исправить сохранив характер ML". И что из себя представляет этот самый "характер ML"? Опять таки, не совсем ожидаемо, но это HOPE.
```sml
type rec 'a list == nil | op :: of 'a # 'a list;
@ -389,18 +400,18 @@ map (fun x. x + y, [1; 2; 3]) where val y == 2 end
Делает ли добавление АлгТД и ПМ в любой ФЯ HOPE из этого языка? Нет. Мы еще увидим такую модификацию ML, которая не мешает языку быть узнаваемым ML. И увидим не одну. Даже предыдущий черновик описания SML представляет некоторую альтернативу настолько тотальной хопификации.
SML 83.4 выглядел более своеобразным языком, в котором в ISWIM-образный язык выражений добавлены АлгТД и паттерн матчинг. Но SML 83.6 довольно обычный в описываемое время язык уравнений.
К этому добавляется и множество совсем необязательных деталей, характерных для HOPE вроде более тяжелого синтаксиса со множеством ключевых слов и некоторого предпочтения туплов в ущерб каррированию. Объявление каррированных функций с помощью нескольких уравнений "некомитет" обсуждал, но решил что это не понятно и ненужно. Исключили и каррированные лямбды, которые в 83.4 сосуществовали с лямбдами с многоветочным ПМ, как позднее будут сосуществовать в OCaml. Теперь только одна разновидность лямбд с многоветочным ПМ, как в HOPE. Упрощенная декларация каррированных именованных функций с помощью одного уравнения, правда, осталась.
Множество авторов и пользователей ML в "некомитете" не особенно помогло стандартному ML больше походить на ML. Похоже, что многие участники не любят не только VAX ML, но и LCF/ML, включая и многих его авторов. Разумеется, нелюбовь авторов Standard ML к ML не единодушна и те, кому нравится LCF/ML еще заявят о себе позднее.
К этому добавляется и множество совсем необязательных деталей, характерных для HOPE вроде более тяжелого синтаксиса со множеством ключевых слов и некоторого предпочтения туплов в ущерб каррированию. Объявление каррированных функций с помощью нескольких уравнений "не-комитет" обсуждал, но решил что это не понятно и ненужно. Исключили и каррированные лямбды, которые в 83.4 сосуществовали с лямбдами с многоветочным ПМ, как позднее будут сосуществовать в OCaml. Теперь только одна разновидность лямбд с многоветочным ПМ, как в HOPE. Упрощенная декларация каррированных именованных функций с помощью одного уравнения, правда, осталась.
Множество авторов и пользователей ML в "не-комитете" не особенно помогло стандартному ML больше походить на ML. Похоже, что многие участники не любят не только VAX ML, но и LCF/ML, включая и многих его авторов. Разумеется, нелюбовь авторов Standard ML к ML не единодушна и те, кому нравится LCF/ML еще заявят о себе позднее.
Большинство участников обсуждения предпочитают туплы из нескольких элементов как в HOPE `(x,y,z)` неоднородным спискам из пар как до того было принято в ML. Перечислениям через запятую там соответствуют такие конструкции: `(x,(y,z))`. Но не в SML. Там теперь туплы будут как в HOPE, плоские структуры с `n` безымянных полей.
В LCF/ML и первом черновике абстрактные типы данных были одной из основных конструкций, но Бурсталл и другие придумали энкодинг через АлгТД, которые Милнер называет более мощными. Так что в SML 83.6 абстрактные типы больше не в ядре языка. Это расширение, определенное через обычные АлгТД с одним конструктором, видимость которого ограничена телом АТД.
Но SML 83.6, конечно, не HOPE - это HOPE 2. Многие отличия от HOPE - это реализация планов Эдинбургских авторов и имплементаторов HOPE, с которыми мы уже знакомы. Вроде императивных фич, таких как мутабельность и исключения. Отказ от поддержки ленивых списков, которые в Эдинбурге посчитали бесполезными. Радикальное сокращение перегрузки, но все еще наличие перегрузки для некоторых операций вроде сравнения. Важное отличие от ML в котором перегрузки не было вообще.
Другие отличия от HOPE до этого момента в статьях о HOPE не обсуждались, но все равно продвигаются его авторами и имплементаторами. Так, МакКвин продвигает смену ПМ со своеобразного (и, по видимому, своеобразного и из-за особенностей имплементации) на привычный, зависящий от порядка паттернов как в SASL, Прологе и современных ФЯ. Но все равно линейный как в HOPE, переменные не могут повторяться для обозначения равенства как они могут в SASL и Prolog.
На заседаниях "некомитета" много обсуждали ограничения ПМ и последовательность сопоставления с образцами. Неназываемые обсуждающие считают, что сопоставление от более конкретного к менее конкретному можно имплементировать эффективнее, хотя порядок слева направо и проще для программиста. Но МакКвин как раз разбирался с имплементацией ПМ для своего компилятора HOPE и убедил Милнера, что эффективную имплементацию можно получить и для порядка слева направо.
Акцентируем внимание на то, что воплощались планы на будущее HOPE именно от его Эдинбургских авторов и имплементаторов, не Лондонских, у которых совсем другие, часто противоположные планы. Но Лондон не имеет представителей в "некомитете". Правда, неназываемые участники обсуждения хотели запретить в SML изменяемые ссылки и исключения, но они оказались в меньшинстве.
На заседаниях "не-комитета" много обсуждали ограничения ПМ и последовательность сопоставления с образцами. Неназываемые обсуждающие считают, что сопоставление от более конкретного к менее конкретному можно имплементировать эффективнее, хотя порядок слева направо и проще для программиста. Но МакКвин как раз разбирался с имплементацией ПМ для своего компилятора HOPE и убедил Милнера, что эффективную имплементацию можно получить и для порядка слева направо.
Акцентируем внимание на то, что воплощались планы на будущее HOPE именно от его Эдинбургских авторов и имплементаторов, не Лондонских, у которых совсем другие, часто противоположные планы. Но Лондон не имеет представителей в "не-комитете". Правда, неназываемые участники обсуждения хотели запретить в SML изменяемые ссылки и исключения, но они оказались в меньшинстве.
Делает ли добавление в HOPE мутабельных ссылок (не таких как в LCF/ML) и абстрактных типов данных (не таких как в LCF/ML) из HOPE ML с элементами HOPE? С точки зрения Милнера - да. Но с нашей точки зрения HOPE, уже в момент своего создания получивший главную особенность и основное нововведение ML - вывод типов Хиндли-Милнера, больше похож на объединение двух Эдинбургских школ ФП-строения, чем Standard ML.
И NPL/HOPE линейка всегда отличалась от ML переработками синтаксиса, которые потребовали бы редактировать практически каждую строку кода. SML прошел через несколько таких переделок.
Уже во втором черновике многие детали синтаксиса снова изменились. Милнер не хочет использовать `_` в качестве паттерна, который матчит все. Потому, что можно использовать `_` и в именах. Поэтому в предыдуще черновике вместо `_` использовалось `any`, а в этом используется `$`. Некоторые "некомитетчики" хотят использовать `,` больше, например не только в туплах, но для списков как в HOPE. Но все равно пока для разделения элементов списка используется `;` как в LCF/ML.
Выражения `let` и `where` теперь с `end`. "Некомитет" достаточно много спорит о виде `let` и дополнительных ключевых словах для декларации типов и значений. Но большинство определенно считает, что `val` лучше, чем `var` из прошлого черновика.
Уже во втором черновике многие детали синтаксиса снова изменились. Милнер не хочет использовать `_` в качестве паттерна, который матчит все. Потому, что можно использовать `_` и в именах. Поэтому в предыдуще черновике вместо `_` использовалось `any`, а в этом используется `$`. Некоторые "не-комитетчики" хотят использовать `,` больше, например не только в туплах, но для списков как в HOPE. Но все равно пока для разделения элементов списка используется `;` как в LCF/ML.
Выражения `let` и `where` теперь с `end`. "Не-комитет" достаточно много спорит о виде `let` и дополнительных ключевых словах для декларации типов и значений. Но большинство определенно считает, что `val` лучше, чем `var` из прошлого черновика.
`<-` вместо `=` из прошлого черновика тоже никому не нравится, так что теперь будет `==`. Почему не хотят специальный оператор для сравнения, а не для байндингов? Сколько они собираются сравнений писать? Не понятно. Карделли не против того, чтоб использовать `=` и как сравнения и в синтаксисе объявлений. Пока что эта идея не победила. Может быть потому, что Карделли не против неё.
Карделли заявлял, что скоро структурные редакторы освободят программистов от заботы о конкретном синтаксисе, так что нужно описывать абстрактный синтаксис, а конкретный только рекомендовать. Но всех остальных конкретный синтаксис волнует гораздо больше и они спорят о нем до озверения, утверждает Милнер.
Решено, что язык будет полностью специфицирован. Очень важное для дальнейшей истории SML решение. Точнее важно то, что этому решению будут следовать. Как мы увидим в дальнейшем, не все создатели единых ФЯ способны на такое.
@ -408,10 +419,10 @@ SML 83.4 выглядел более своеобразным языком, в
Новая система исключений придумана Майкрофтом, с использованием идей Монахана. Да, новая система исключений нигде не испытана, пишет Милнер, мы собирались избегать таких фич, но, вроде бы фича простая, работающая и безопасная.
Так что некоторые эксперименты возможны. Даже для экспериментов Дамаша с полиморфными изменяемыми ссылками появляется какая-то надежда. В SML 83.6 они не попали, но это уже не исключено в будущих редакциях. МакКвин пообещал разобраться с этим вопросом, пишет Милнер.
Эксперименты, которые все еще недопустимы - это, разумеется, эксперименты Карделли с рекордами. Этому ход в SML закрыт. АлгТД и ПМ как в HOPE поддерживает большинство участников обсуждений. Милнер пишет, что их можно было бы объединить с системой Карделли, добавив к конструкторам именованные поля. Но объединять не стали. Милнер опасается, что от такого богатства фич у пользователей языка глаза разбегутся.
Личное участие Карделли в заседаниях "некомитета" не помогло сделать язык SML больше похожим на VAX ML. Но это не касается его стандартной библиотеки. Библиотеку потоков для ввода-вывода для SML теперь разрабатывает Карделли. Наработки Милнера по вводу-выводу выброшены, и Милнер передумал добавлять в ML перегруженные для любого АлгТД функции `read` и `write` потому, что их имплементация потребует "сложного и деликатного" взаимодействия с компилятором.
Личное участие Карделли в заседаниях "не-комитета" не помогло сделать язык SML больше похожим на VAX ML. Но это не касается его стандартной библиотеки. Библиотеку потоков для ввода-вывода для SML теперь разрабатывает Карделли. Наработки Милнера по вводу-выводу выброшены, и Милнер передумал добавлять в ML перегруженные для любого АлгТД функции `read` и `write` потому, что их имплементация потребует "сложного и деликатного" взаимодействия с компилятором.
Но, конечно, когда сегодня один из тех (немногих), кто знает Standard ML читает, что ядро этого языка не задумывалось для экспериментирования с фичами, то экспериментальная фича, о которой он немедленно думает - это, скорее всего, не исключения и не рекорды. Это параметризованные модули.
И, разумеется, модули, не только простые модули, но и параметризованные и первоклассные уже обсуждаются комитетом. Простите, "некомитетом", конечно же. Модулей нет в LCF/ML, но простые модули есть в HOPE и уже позаимствованы Карделли для VAX ML. Мы также помним, что одна из самых амбициозных идей для следующей версии NPL/HOPE (Эдинбургской, не Лондонской, конечно) - это параметризованные модули на основе CLEAR.
Так что многие участники "некомитета" хотят модули в SML, особенно имплементаторы ФЯ МакКвин, Карделли, Митчелл и Полсон, которым они нужны для раздельной компиляции, необходимой для практически полезной имплементации языка общего назначения.
И, разумеется, модули, не только простые модули, но и параметризованные и первоклассные уже обсуждаются комитетом. Простите, "не-комитетом", конечно же. Модулей нет в LCF/ML, но простые модули есть в HOPE и уже позаимствованы Карделли для VAX ML. Мы также помним, что одна из самых амбициозных идей для следующей версии NPL/HOPE (Эдинбургской, не Лондонской, конечно) - это параметризованные модули на основе CLEAR.
Так что многие участники "не-комитета" хотят модули в SML, особенно имплементаторы ФЯ МакКвин, Карделли, Митчелл и Полсон, которым они нужны для раздельной компиляции, необходимой для практически полезной имплементации языка общего назначения.
Но Милнер не хочет модулей. Отказываясь от них он вспоминает о "консолидации" и отказа от экспериментирования. Как будто не делает тут же рядом исключений для экспериментирования. И как будто модули, по крайней мере простые, не проверены уже в HOPE не меньше, чем ПМ и АлгТД.
Но, конечно, сторонники разных модулей мешают друг другу добавить их в SML. Простые модули как в Hope и MODULA 2, за которые выступает Карделли, не добавляют, чтоб оставить место для параметризованных модулей МакКвина. Не понятно, правда, почему простые модули исключают добавление параметризованных, которые могут стать просто расширением простых. Но у модулей вообще, всех их видов, есть и другие, неназванные Милнером противники.
Правда, как и в случае с типизацией ссылок по Дамашу, Милнер против модулей только временно. Он не только допускает, но и ожидает, что модули будут добавлены, но не сейчас и не Милнером.
@ -419,7 +430,7 @@ SML 83.4 выглядел более своеобразным языком, в
Но способ раздельной компиляции, который не обязательно является модулями, нужен уже сейчас, для SML.
Для этого используются система директив `spec` для декларации без имплементации. Эти декларации функций и типов в тех файлах, где их используют позволяют проверять типы и компилировать файлы по отдельности. Имплементации этих сигнатур должны быть в окружении в момент загрузки скомпилированного файла.
Типы в сигнатурах могут быть более общими. Если для АлгТД не используется ПМ и автоматически генерируемое равенство, то декларировать можно только часть конструкторов и "конструкторы" могут быть имплементированы как функции.
Для объявления синонимов для типов, `deftype` в LCF/ML (или `type` в Haskell) тоже используются директивы. Почему директивы? В SML 83.4 синонимов не было вовсе. Но все "некомитетчики", которые писали код какого-то заметного размера на ФЯ говорили Милнеру, что они очень нужны. Но даже они по какой-то причине считают их сомнительным хаком, так что они добавлены в язык не как обычная конструкция для объявления типа, а как директива вроде тех, что для раздельной компиляции.
Для объявления синонимов для типов, `deftype` в LCF/ML (или `type` в Haskell) тоже используются директивы. Почему директивы? В SML 83.4 синонимов не было вовсе. Но все "не-комитетчики", которые писали код какого-то заметного размера на ФЯ говорили Милнеру, что они очень нужны. Но даже они по какой-то причине считают их сомнительным хаком, так что они добавлены в язык не как обычная конструкция для объявления типа, а как директива вроде тех, что для раздельной компиляции.
Итак, процесс стандартизации ML продолжает отторгать идеи Карделли. Но Карделли был "достаточно добр, чтоб принять это" - продолжает хвалить его Милнер. Карделли написал детальный черновик мануала по VAX ML. И "щедро предложил" приостановить работу над мануалом для VAX ML пока описание SML не будет закончено. Но почему Карделли приостанавливает описание собственного языка? Что он "принимает", в чем его жертва, за которую его продолжает благодарить Милнер?
### Карделли против Карделли
@ -437,7 +448,7 @@ SML 83.4 выглядел более своеобразным языком, в
Уже в следующем месяце девятого сентября [Card83b] Карделли начал серию компиляторов SML и переработанных руководств пользователя. Эти версии Карделли называл "позициями". Но, в отличие от танцевальных позиций, позиции у Карделли нумеруются с нуля (Pose O).
Трудно сказать, когда была выпущена первая позиция, в руководстве [Card83c] указана явно неправильная дата - 1-е августа - т.е. раньше, чем нулевая позиция и даже последняя версия VAX ML. Вторая позиция [Card83d] и последняя, (частично) имплементирующая SML 83.6, вышла десятого октября 83-го.
Разница между этими тремя версиями компилятора и их описаниями незначительная.
Разница между ними и последним компилятором VAX ML очень значительная. Карделли не добавил SML как дополнительный фронтенд, как делал в это время автор Poly Метьюз. Карделли заменил один фронтенд на другой. Просто удалил имплементацию своего собственного языка из своего собственного компилятора. Даже разработчики форка его компилятора в Эдинбурге этого не сделали, так что это еще не конец VAX ML. Но, определенно, конец его развития. Карделли пожертвовал своим основным экспериментом - рекордами и вариантами [MacQ14], которые заменены на алгебраические типы данных как в HOPE. Та самая жертва, за которую его благодарит Милнер в своем черновике.
Разница между ними и последним компилятором VAX ML очень значительная. Карделли не добавил SML как дополнительный фронтенд, как делал в это время автор Poly Мэттьюз. Карделли заменил один фронтенд на другой. Просто удалил имплементацию своего собственного языка из своего собственного компилятора. Даже разработчики форка его компилятора в Эдинбурге этого не сделали, так что это еще не конец VAX ML. Но, определенно, конец его развития. Карделли пожертвовал своим основным экспериментом - рекордами и вариантами [MacQ14], которые заменены на алгебраические типы данных как в HOPE. Та самая жертва, за которую его благодарит Милнер в своем черновике.
Язык, который имплементируют Pose 0/1/2 отличается от SML 83.6, но предполагается, что отличия временные. Карделли пишет [Card83e], что не собирается больше поддерживать имплементацию собственного диалекта ML. Со временем, или его компилятор измениться чтоб соответствовать стандартному ML или стандартный ML изменится, чтоб соответствовать компилятору. Трудно сказать, почему Карделли все еще надеется на второй исход.
Отклонения имплементации Карделли от SML 83.6 можно разделить на две разновидности [Card83e]. Во-первых, не все эксперименты Карделли с ML закончены. Ввод-вывод частично имплементирует предложенный Карделли новый ввод-вывод для SML. Вместо системы деклараций сигнатур для раздельной компиляции из SML 83.6 в имплементации Карделли простые, непараметризованные модули. Они имплементируют идеи Карделли не полностью и работают не совсем хорошо.
Проверка типов для изменяемых ссылок осталась такой же как в VAX ML, более обобщенной, чем в черновике описания SML. В компиляторе Карделли осталась и поддержка массивов, которых нет в SML 83.6. Надежды на то, что это все может попасть в SML не считаются безнадежными.
@ -478,7 +489,7 @@ val rec map ($, nil) == nil |
Революционное предложение использовать ПМ-лямбду из HOPE и новая система исключений, как видим, не помогли Майкрофту попасть в основные авторы.
Главными результатом обсуждений второго черновика, пишет (печатает?) Милнер, было решение о разделении описания SML.
Двумя самыми обсуждаемыми частями языка о которых меньше всего согласия стали ввод-вывод и раздельная компиляция. Но все разногласия о том, каким должно быть ядро языка, касаются мелких деталей. Так что Милнер концентрирует усилия на описании ядра языка без ввода-вывода и модулей. Тем более, что ни выбор того, как именно будет устроен ввод-вывод, ни какие именно модули будут в ML, практически не повлияет на вид ядра языка, утверждает Милнер.
Тут можно было бы предположить, что разделение современного SML на язык модулей и язык функций - это результат действия закона Конуэя и дизайн SML воспроизводит структуру "некомитета", в котором собираются разрабатывать модули отдельно, а ядро языка - отдельно. Но мы уже выяснили в предыдущих частях, что еще в CLEAR, от которого модули МакКвина происходят, уже было явное разделение на язык модулей и язык функций. И оба языка составляющих CLEAR разрабатывали одни и те же люди в одно и то же время.
Тут можно было бы предположить, что разделение современного SML на язык модулей и язык функций - это результат действия закона Конуэя и дизайн SML воспроизводит структуру "не-комитета", в котором собираются разрабатывать модули отдельно, а ядро языка - отдельно. Но мы уже выяснили в предыдущих частях, что еще в CLEAR, от которого модули МакКвина происходят, уже было явное разделение на язык модулей и язык функций. И оба языка составляющих CLEAR разрабатывали одни и те же люди в одно и то же время.
Описания ввода-вывода от Карделли и модулей от МакКвина должны быть готовы одновременно с третьим черновиком описания ядра SML и все вместе составят полное его описание.
Имплементатор может имплементировать все три описания или только часть из них, пишет Милнер, но "надеется", что все три компонента будут приняты имплементаторами.
Полиморфные изменяемые ссылки все еще считаются недостаточно проверенными временем и Милнер все еще ждет хорошего описания от Дамаша или МакКвина.
@ -807,7 +818,7 @@ import map: ((*a->*b)->((List *a)->(List *b)));
1. Специальные скобки и символы. Скобки решили делать `(| |)` как были сделаны у Карделли в VAX ML, а `#` в начале имен полей `#foo` не нужно.
1. Имена полей в типах. Будут.
1. Что будет основной формой, а что - производной. Туплы - производная форма. Это рекорды с полями, названными по их порядковому номеру.
1. Полиморфизм и подтипирование рекордов. Милнер против, считает что эти проблемы еще не решены. И потому такого в SML не будет. А значит, что перегрузка полей будет такой же ограниченной как и вся прояая перегрузка в SML в это время.
1. Полиморфизм и подтипирование рекордов. Милнер против, считает что эти проблемы еще не решены. И потому такого в SML не будет. А значит, что перегрузка полей будет такой же ограниченной как и вся прочая перегрузка в SML в это время.
1. Можно ли писать `(| x |)` вместо `(| x=x |)` в паттернах? Карделли заявил, что это он изобрел такой синтаксис и он ему больше не нравится. Решили, что так делать нельзя.
Получилось так, что Карделлиевские рекорды из VAX ML попали таки в SML. Но, справедливости ради нужно отметить, что принятие не-полиморфных рекордов в SML с самого начала, скорее всего, не решило бы проблему потери Карделли интереса к имплементации SML. Принятие на этом этапе определенно не решило. С не-полиморфными рекордами он уже поэкспериментировал до того.
@ -832,16 +843,238 @@ let val y = 2 in map (fn x => x + y) [1, 2, 3] end
На этом история адаптации изобретений 70-х закончилась и началась история формального описания Standard ML и решения проблем, которые были в 70-х в основном только сформулированы: разработка и имплементация параметризованных модулей, перегрузки и интеграции изменяемых ссылок в ФЯ. Но это уже другая история.
### Le ML
В том же 84-ом году, когда Кузино добавил в Cambridge ML паттерн-матчинг и АлгТД, в INRIA начали работу над более амбициозной имплементацией ML [Maun86]. На этот раз ML не стали транслировать в Лисп. Le Lisp считается хорошей имплементацией Лиспа, но его компилятору нужно пытаться компенсировать проблемы Лиспа с производительностью, вроде особенностей (отсутствия) типизации, которых в ML просто нет. Так что решено использовать виртуальную машину LLM3, которую Le Lisp использует для облегчения портирования. Она достаточно низкоуровневая для этого.
Из-за использования рантайма и бэкенда Le Lisp новый компилятор сначала называли Le ML. Позднее его стали называть CAML по имени другой виртуальной машины уровнем выше [Cous90].
Уровнем выше над LLM3 в новой имплементации ML - виртуальная машина CAM (Categorical Abstract Machine) [Cous87]. Почему "categorical"? Набор её инструкций основывался на исчислении категорных комбинаторов Курьена (Pierre-Louis Curien). Кузино посчитал, что набор инструкций на основе формализма поможет доказывать корректность оптимизаций.
Как основные операции тернеровского SK-интерпретатора соответствуют инстансу `Applicative` для функций, основные операции CAM соответствуют операциям из Хаскельного модуля `Control.Arrow` над функциями и парами вроде `(<<<)` и `(&&&)`. Но главное отличие CAM от комбинаторного интерпретатора в том, что она-то не комбинаторная.
CAM собирает окружения из пар указателей. Как мы выяснили в предыдущих частях, имплементаторы ФЯ или хотя-бы мечтали, как Стил, или даже успешно смогли, как Карделли, отказаться от такого подхода и сделать окружение массивом, чтоб оптимизировать время доступа к нему. Но Кузино и др. считают, что лучше оптимизировать конструирование замыкания. И новые развесистые окружения-деревья из пар быстрее склеивать из уже имеющихся конструированием пар. По крайней мере асимптотически.
Быстрое конструирование замыканий, например, частичных применений, посчитали авторы новой виртуальной машины, лучше подходит для функционального программирования вообще и для имплементации ленивости в частности. Помимо компилятора строгого по умолчанию языка Le ML/CAML, над которым работал Аскандер Суарес (Ascander Suarez), Мишель Мони (Michel Mauny) писал и компилятор ленивого ФЯ Le LML/Lazy CAML. И даже в строгом по умолчанию языке были конструкции для опциональной ленивости.
В INRIA уже с лета 86-го стали использовать для написания доказателя. Версию CAML 2.5, используемую не позднее ноября 87-го, в INRIA считали более-менее стабильной [Huet15] и не позднее весны 88-го начали писать о ней в рассылках [Maun88]. Версию 2.6 в 90-ом предлагали [Neum90] выслать желающим за $300 ($740 в 2025).
Этот CAML все еще не тот язык, который сегодня ассоциируется с этим названием. Но современный OCaml уже вполне узнаваем в нем, как и современный SML узнаваем в SML 85.9.
Что в CAML узнать гораздо сложнее - это LCF/ML. Синтаксис комментариев и строк в CAML теперь как в SML. Больше нет соединений ключевых слов вроде `letrec` и `whererec`. Типы-произведения становятся `*` как в SML. Конструктор списка теперь `::` как в SML. Точки в лямбдах и `case`-выражениях заменили на стрелки, но одинарные `->`, а не двойные `=>` как в SML [Cous90].
Да, незадолго до того в INRIA бережно добавили фичи HOPE в LCF/ML так, чтоб не потребовалось править каждую строку их кода на LCF/ML. И теперь там же спроектировали язык, который потребовал править практически каждую строку их кода на LCF/ML++, которого стало только больше. Мы не знаем, почему так произошло.
CAML стал больше походить на SML в деталях, но остались отличия важные для представителей INRIA на заседаниях не-комитета. В CAML нет групп уравнений, обычных для HOPE-фицированных языков того времени, CAML - язык выражений, а не уравнений, в большей степени ISWIM, чем NPL. `let` остался как в LCF/ML, не похожим на тот, что в SML, и пока что никуда не делось выражение `where`.
Есть различия, которые не обозначали как важные. Элементы в списках перечисляются через `;`, а туплы не плоские как в HOPE и SML, а состоят из пар.
Основная причина несовместимости CAML с процессом стандартизации SML, по видимому, не желание сохранить побольше LCF/ML, как в случае с модифицированным Кузино Cambridge ML. CAML несовместим с SML-процессом из-за обилия новых фич. Они не ограничиваются опциональной ленивостью.
В CAML множество экспериментов с паттерн-матчингом. Два вида лямбд. Одна лямбда - `function`, позволяющая многоветочный паттерн-матчинг, но не позволяющая упрощенной декларации каррированных функций. Как лямбда в HOPE, SML, одна из двух лямбд в OCaml и `\case` в Haskell.
Но второй вид лямбд - `fun` - соответствовал не современным `fun`-лямбдам OCaml или `\`-лямбдам в Haskell, поддерживающим простую декларацию каррированной функции, но не многоветочный ПМ. `fun` в CAML поддерживает и то и другое, приблизительно как `\cases` в GHC 9.4.
```ocaml
let chop_list = (fun n l -> chop_aux n ([],l))
where rec chop_aux =
fun 0 (l1,l2) -> rev l1,l2
| n ->
fun (_,[]) -> failwith "chop_list"
| (l1,h::t) -> chop_aux (pred n) (h::l1,t);;
```
Но код на CAML развивается в сторону соглашения, соответствующего ролям `fun` и `function`, которые в OCaml устанавливаются самим языком.
CAML большой и избыточный язык, в нем сосуществовали два синтаксиса для ПМ-выражений. И `case` `of` и более привычный программисту на OCaml `match` `with`. Но вторая конструкция использовалась чаще и к версии 3 осталось только выражение `match` `with`.
Там появляются как более-менее знакомые нам сегодня или-паттерны, менее обычные версии обычных вещей, такие как `as`-паттерны в которых сложные паттерны могут быть с обеих сторон `as` одновременно, так и более необычные вещи, вроде парсеров, объявляемых как ПМ. Как этот ПМ-парсер, разбирающий код с ПМ [Caml261]:
```ocaml
and Fnexpr =
parse Literal "fun"; Match m -> MLmatch m
| Literal "function"; Umatch um -> MLmatch um
| Literal "match"; Expr e; Literal "with"; Umatch um
-> MLapply (MLmatch um, e, [])
| Literal "case"; Expr e; Literal "of"; Umatch um
-> MLapply (MLmatch um, e,[]) ...
```
Важная причина того, что разработчики доказателей не спешили использовать VAX ML и SML, а продолжали выбирать Cambridge ML или собственную имплементацию ML - это средства метапрограммирования. В мета-языке для доказателя хотелось бы иметь средства для манипуляции кодом на языке для доказателя. И в CAML они есть.
```
let rec MAP f =
function (<<[]>> as S) -> S
| <<#x::#L>> -> <<(#f #x)::#(MAP f L)>>
```
Можно и конструировать AST с помощью цитат, и разбирать в ПМ.
Но довольно привычные и ожидаемые теми, кто знаком с OCaml, гарды появились там не сразу, только в третьей версии в начале 90-х. Позже, чем в LML, но намного раньше, чем в SML.
Наш обычный пример выглядит так:
```ocaml
type 't list = [] | prefix :: of 't * 't list;;
let rec map f = fun [] -> []
| (h::l) -> f h::map f l;;
map (fun x -> x + y) [1; 2; 3] where y = 2
```
Его можно сделать еще более похожим на код на OCaml, но мы старались подчеркнуть различия.
### Неравенство уравнений
Так в INRIA создали свою, узнаваемую разновидность HOPE-фицированных ML-ей. С паттерн-матчингом, но без групп уравнений. Это довольно привычно сегодня, но не в середине 80-х. Для большинства HOPE-фикаторов, добавление уравнений было чем-то самим собой разумеющимся. На каждый компилятор французского ML-я приходилось несколько имплементаций ФЯ с уравнениями. Несколько одних только имплементаций SML, которые в эти времена делали один за другим. И до того, как завершилось формальное описание его семантики, так что нельзя приписать успех решению эту семантику формально описывать.
#### Edinburgh ML, SML/NJ, ML Kit
После того, как Карделли забросил свой компилятор, следующей главной экспериментальной имплементацией для SML не-комитетчиков стал его ранний форк Edinburgh ML. Разделение произошло, по видимому, задолго до начала переделывания компилятора Карделли из компилятора VAX ML в компилятор SML, так что наработки Карделли использованы не были. Тем более, что Митчелл с коллегами в Эдинбурге переписали Edinburgh ML с Паскаля на другой язык. В Edinburgh ML не заменили поддержку VAX ML на SML как сделал Карделли, а продолжили поддерживать VAX ML вместе с SML. Правда, VAX ML потерял статус ФЯ с нативным компилятором потому, что Edinburgh ML переделали из нативного компилятора в интерпретатор байт-кода. Справедливости ради нужно отметить, что переделали в интерпретатор нового поколения с заметно более высокой производительностью, чем у первой волны интерпретаторов ФЯ вроде LCF/ML, обеих основных SASL и Edinburgh HOPE. Почему из компилятора сделали интерпретатор? Об этом в следующей части.
Эстафету главной песочницы SML-не-комитетчиков Edinburgh ML передал новому компилятору, который был компилятором SML с самого начала, написанному вернувшимся к имплементации ФЯ МакКвином и новым героем нашей истории Аппелем. Работа над этим новым компилятором Standard ML of New Jersey (SML/NJ) началась в Принстоне, в марте 86-го [MacQ14]. Осенью 87-го вышел первый доступный публично релиз.
В 89-ом году в Эдинбурге Мадс Тофте и др. начали писать еще один экспериментальный компилятор ML Kit [MLKit2002].
Все эти компиляторы сами являются важными экспериментами по написанию реальных программ на ML и будут подробно рассмотрены в следующей части.
Но было еще несколько компиляторов SML, которые или стали экспериментами по написанию кода на ML не сразу. Или не стали уже никогда.
Начнем с компилятора SML, написанного на самом нефункциональном языке - Паскале. Да, после стольких лет, нашлись еще имплементаторы ML кроме Карделли, готовые писать имплементацию ML на Паскале.
#### ANU ML
Написанный на Pascal компилятор Карделли не пропал, после того, как Карделли забросил работу над ним. Один из первых авторов и имплементаторов LCF/ML Малкольм Ньюи, который после работы в Эдинбурге вернулся в Австралию работать в Австралийском национальном университете (Australian National University), создал там еще один форк компилятора Карделли, предпоследней его версии Pose 3. Этот компилятор, получивший название ANU ML [Berr90], был портирован на рабочие станции и даже на Макинтош. ANU ML имплементировал более новую версию SML и более полно, чем Pose 4. Но имплементация все же была не полной, не были имплементированы параметризованные модули и она отставала от самых последних представлений о том, как SML должен работать. Что не является нетипичным для имплементаций SML того времени.
Интересно, что Ньюи, еще один "ядерный" разработчик LCF/ML, в отличие от своих французских и шведских коллег, похоже предпочел не LCF/ML, а что-то более HOPE-образное.
SML-не-комитет узнал об ANU ML не позднее мая 88-го [Miln88], но он не перечисляется как доступная имплементация SML до 90-го года [Moss89] [Berr90]. К концу 80-х производительность генерируемого кода все еще оценивают как хорошую, а требования к памяти как более скромные, чем у новых компиляторов.
#### Poly/ML
На заре HOPE-фикации Гордон и Полсон [Gord82] рассматривали Poly как перспективный источник идей для развития ML и даже как потенциальный язык для объединения в один с ML. Мэттьюз в дальнейшем писал, что неплохо было бы добавить в Poly паттерн-матчинг и конструкторы исключений с параметрами [Matt88], но ничего из этого не было сделано.
Poly не был хопифицирован добавлением ПМ и АлгТД как VAX ML, Lazy ML, Cambridge ML. Компилятор Poly был использован как основа для компилятора SML. Но, поскольку Poly использовался для разработки самого компилятора (и, по видимому, ни для чего другого), возможность компилировать код на Poly осталась. Так же как поддержка VAX ML осталась в Edinburgh ML, имплементирующем SML.
Первая экспериментальная версия Poly/ML была сделана до конца 83-го года [Matt89] и была пригодна для написания реальных проектов не позднее 86-го года. По мнению Полсона, Poly/ML был, на протяжении ряда лет единственной эффективной имплементацией SML. Что не удивительно, Полсон с самого начала не считал компилирующиеся через Лисп ML-и серьезными имплементациями по сравнению с Poly и VAX ML [Paul22b]. И в это время одна ветка VAX ML была заброшена, другая переделана в интерпретатор и третья пропадала на другом конце Земли и, по видимому, не была известна европейским и американским эмелистам до конца 80-х [Berr90].
Дэвид Мэттьюз работал в Кембридже над Poly/ML один, по видимому, до конца 89-го года [Moss89]. Компилятор был портирован на популярные рабочие станции SUN 3, где требовал 3-6Мб памяти, но VAX-версия была заброшена [Berr90]. Распространяла компилятор компания Cambridge University Technical Services, занимающаяся коммерциализацией того, что делали академики в Кембридже. А именно, другие академики получали компилятор за 100 фунтов ($333 в 2025) [Wolf89], а коммерческий пользователь мог договориться во сколько ему обойдется лицензия. Но не позднее весны 1990-го CUTS передала права на разработку и распространение Poly/ML компании Abstract Hardware Limited, в которой Мэттьюз продолжил работу, но уже не один [Matt2000] [Berr90]. Abstract Hardware Ltd. продавала компилятор академикам за 500 фунтов ($1664 в 25-ом), а коммерческим пользователям за две тысячи фунтов ($6655 в 2025).
#### POPLOG ML
POPLOG - система, разработчики которой старались сделать ее удобной основой для имплементации ФЯ. Разумеется ее использовали и для имплементации SML.
С появлением популярных рабочих станций, POPLOG [Slom89] сделали более удобным для портирования на новые машины, для этого в нем теперь два промежуточных языка, с которыми работают имплементаторы расширений: PVM (Poplog Virtual Machine) - в это компилируют новые языки писатели фронтендов, PIM (Poplog Implementation Machine) - это имплементируют на новой машине писатели новых бэкендов. Весь конвейер между PVM и PIM машино- и языконезависим.
С середины 84-го POPLOG работает на 4BSD, сначала на VAX, а позднее и на машинах с MC68K вроде рабочих станций SUN и Apollo, c 386 и менее важных.
Университет Сассекса продавал POPLOG с 82-го года [POP19], с существенными скидками для прочих академиков, с 83-го года продажами занялась компания Systems Designers Ltd. (позднее SD). В ней имплементацию MACLISP-диалекта Каннингема на основе POPLOG посчитали не соответствующей ожиданиям от коммерческого продукта и профинансировали новую, более серьезную имплементацию Common LISP. Деньги на это выделил и S(E)RC. Над имплементацией работал в основном Джон Уильямс (John Williams) под руководством Каннингема. Для этой имплементации как и для имплементации Пролога, в POPLOG добавили новые фичи. Гибсон внес изменения в виртуальную машину для лучшей поддержки статической видимости и исключений.
В 86-ом году, в POPLOG версии 12, Common Lisp был уже имплементирован процентов на 90% [POPLOG], а в феврале 87-го состоялся релиз версии 1.0 Common Lisp фронтенда. К осени 88-го заработала даже оптимизация хвостовой рекурсии.
Добавленная в POPLOG статическая видимость стала использоваться и в POP-11, сначала как опциональная, летом 86-го с версии 10.3 [POPLOG], а позднее и по-умолчанию. В последних версиях POPLOG пример Поплстоуна, демонстрирующий проблемы с возвращением функций больше проблемы не демонстрирует. Но превращение POP-11 в полноценный ФЯ Эдинбургской программы не состоялось, как и превращение Poly. Вместо этого Роберт Дункан (Robert Duncan) и Саймон Николс (Simon Nichols) написали на основе POPLOG имплементацию Standard ML, для которой улучшенная поддержка статической видимости как раз пригодилась.
Версия 1.0 PML, как назывался Standard ML на основе POPLOG, появилась в октябре 88-го года, но не поставлялась в комплекте с POPLOG (в это время 13.6). Первоначальная имплементация SML доросла до версии 1.3 и в декабре 90-го сменилась версией 2.0, вошедшей в основной комплект поставки POPLOG 14 в 91-ом году.
Считалось, что POPLOG SML генерировал код, который исполнялся немного помедленнее Poly/ML, но компилировал побыстрее [Appe91].
В 90-ом году счастливым обладателем POPLOG можно было стать заплатив 7.5тыс. фунтов (25тыс. долларов в 2025-ом) [Berr90]. Для академиков скидка 85%!
#### Rutherford ML
Standard ML получил поддержку от программы-наследника STI и Лаборатория Резерфорда - Эплтона подключилась к его разработке и имплементации. В 85-ом Вадсворт принял участие во встречах комитета, а в самой лаборатории занялись доведением Cambridge ML до полной и окончательной HOPE-фикации.
Эта имплементация называлась Rutherford ML или Rutherford SML.
Филип Микаэль Хедлунд (Philip Mikael Hedlund) начал работу в лаборатории в январе 85-го [Witt85]. К февралю 86-го Хедлунд под руководством Вадсворта [RAL87] написал новые парсер и проверку типов, которые сделали Rutherford ML компилятором подмножества Standard ML без модулей. Сделав это он приступил к улучшению генератора кода и рантайма [Duce86]. Заявляется, что оптимизации в новом генераторе кода на Лиспе улучшили время выполнения некоторых программ в 10 раз [RAL87], но нам не известно каких программ.
Имплементация Rutherford SML была закончена в июне 1986. Тестировал новый компилятор SML Полсон в Кембридже [RAL87]. После этого Хедлунд начал работу над генератором парсеров для ML, но летом 87-го его работа в ЛРА закончилась и он вернулся в Швецию [Danc87].
Cambridge LCF и, естественно, Cambridge ML и Rutherford SML в ЛРА заработали на IBM-совместимом мэйнфрейме с UNIX - Atlas 10 [Faul84] [Duce86]. Так в середине 80-х мечты Стрейчи и Уилкса осуществились уже полностью, Реально-Существующий-CPL (ML) заработал на пригодном для его использования Atlas (но 10, а не 1 и не 2 и разработанный Fujitsu).
Машина с одним ЦПУ в 15 MIPS и, что более важно, с 16Мб памяти, так что нужно было меньше ждать когда страницы поднимут в память с диска. Так что Кембриджский Университет проверял на этой машине за минуты доказательства, которые требовали ночь работы VAX [GEC63] с процессором всего-то раз в 15 медленнее.
И когда Кембридж использует очередной реальный CPL на очередном Atlas, то понятно, что другая организация мечтателей о CPL не остается в стороне. Королевский Радиолокационный Институт тоже захотел компилятор SML, но на этот раз не разрабатывал компилятор самостоятельно, а заказал [Berr90] его компании Harlequin Ltd. (Кембридж, СК), разработчику коммерческой имплементации Common Lisp.
Но Cambridge ML с нестандартно HOPE-фицированным французским ML, даже заброшенный французами и с новоявленным стандартным форком-конкурентом не погиб и оставался, по видимому, более популярным, чем Rutherford ML, количество пользователей которого стало заметно падать уже через пару-тройку лет после первого релиза [RAL89].
Жизнь Cambridge ML продлило и то, что в отличие от Rutherford ML, так и оставшегося компилятором ML через Franz LISP и прочие нестандартные и уже умирающие в эти годы Лиспы, Hewlett-Packard профинансировал [Gord2000] создание Кэрроллом (John Carroll) версии нестандартного Cambridge ML, компилирующего через стандартный Common Lisp.
#### Да, fib
Давайте посмотрим, насколько быстро работает код, который генерируют компиляторы HOPE-фицированных ML-ей. Таблица показывает насколько больше вызовов функций делается за единицу времени по сравнению с интерпретатором LCF/ML.
| | nfib |
| :------------------------------------ | :------: |
| Le ML (CAML) [Maun86] | 197 |
| SML/NJ 0.18 [Augu89] | 115 |
| _C_ [Augu84] | 100 |
| ANU ML (VAX ML) [Augu84] | 92.0 |
| Lazy ML [Augu89] | 59.0 |
| Cambridge ML V6.2 Franz Lisp [Maun86] | 31.5 |
| Poly/ML [Maun86] | 25.8 |
| Poplog ML [Berr90] | 25 ? |
| Le LML [Maun86] | 16.0 |
| Edinburgh ML [Augu89] | 13.5 |
| _LCF/ML_ [Augu84] | **1.00** |
Le ML (CAML) [Maun86]
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
SML/NJ 0.18 [Augu89]
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_C_ [Augu89]
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
ANU ML (VAX ML) [Augu84]
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
Lazy ML [Augu89]
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
Cambridge ML V6.2 Franz Lisp [Maun86]
░░░░░░░░░░░░░░░░
Poly/ML [Maun86]
░░░░░░░░░░░░░
Poplog ML ? [Berr90]
░░░░░░░░░░░░░
Le LML [Maun86]
░░░░░░░░
Edinburgh ML [Augu89]
░░░░░░░
_LCF/ML_ [Augu84]
Разумеется, основной микробенчмарк для оценки производительности ФЯ 80-х не особенно хорошо подходит для такой оценки. С появлением более-менее серьезного кода на этих языках стало возможно более качественное сравнение, которое поменяло взаимное расположение имплементаций в этом рейтинге. Но это уже тема следующей части.
### Пираты Кремниевой Долины
Академия стала переписывать свой Лисп-код с MacLisp-диалектов на Common Lisp. Видимо предполагая, что прочие Лиспы теперь не имеют будущего. В некоторых случаях так и вышло.
InterLisp для имплементации ФЯ и до того не использовался, но Standard Lisp использовался, имел компилятор PSL, производящий быстрый код и получил поддержку HP. Для Standard Lisp разрабатывался новый экспериментальный компилятор EPIC [Kess86], компилирующий в семь стадий, больше похожий на оптимизирующие компиляторы S-1 Lisp и BLISS-11. Но Standard Lisp не поддерживал лексическую видимость и потому был не особенно удобен и эффективен для использования в качестве бэкенда компилятора ФЯ.
Ожидалось, что этот недостаток будет преодолен, но преодолен одновременно с превращением в компилятор Common Lisp, что было еще одним поводом использовать CL, а не Standard Lisp.
Сконвертировать наработки по имплементации хорошего компилятора Standard Lisp в хороший компилятор Common Lisp не удалось. Сделать хороший компилятор Common Lisp было вообще не легко, как это и было задумано, по крайней мере некоторыми, авторами его стандарта. Так что HP прекратил поддержку разработки PSL и Standard Lisp, заказав компилятор Common Lisp у коммерческой компании, основанной авторами стандарта [Stee96].
Но не все нестандартные Лиспы прекратили существование, работы над Le Lisp продолжались.
Торжество Common Lisp, тем временем, оборачивалось не самым удачным развитием событий для академии. Создание стандартного (со строчной буквы) Лиспа было использовано для того, чтоб перезапустить экосистему и превратить её из экосистемы насыщенной доступным для академии кодом, на основе которого можно строить что-то свое, в экосистему, в которой практически все работающее коммерциализировано и закрыто и академику не за что ухватиться.
Эта новая коммерциализированная экосистема состояла из Лисп-машинистов, уступающих под натиском обычных рабочих станций, и использующих их остальных лисперов. Проблемы Лисп-машинистов мы изложили подробнее в прошлой части.
Лисп-машинисты со временем придумали, как использовать победоносное шествие обычных рабочих станций. Не нужно пытаться продавать свои персональные мини-компьютеры величиной с холодильник, нужно продавать плату расширения - Лисп-акселератор, который лиспер будет вставлять в свои новые, все более мощные рабочие станции и даже простые ПК из верхнего ценового сегмента вроде Макинтоша. Эта идея несколько продлила жизнь Лисп-машинизма, но, по видимому, не стала достаточно релевантной для того, чтоб сыграть важную роль в нашей истории функционального программирования. Рабочие станции развивались быстро и акселератор для Лиспа был не так уж и нужен.
Основными коммерческими имплементаторами Common LISP для рабочих станций были Lucid Inc. и Franz Inc. Некоторые производители обычного железа начали с разработки собственных имплементаций, но, со временем, отказывались от них в пользу продуктов Lucid, которая выступала OEM имплементатором для них. Franz больше работала с небольшими компаниями и индивидуальными программистами.
Franz - это уже знакомые нам разработчики Franz LISP, самой популярной имплементации MACLISP-образного Лиспа, являющейся общественным достоянием. Для разработчиков ФЯ в академии это подходило, но группа Фейтмана в Беркли положила этому конец, став коммерческой компанией, которая сначала продавала новые версии Franz LISP, а с конца 86-го стала продавать ExCL (Extended Common Lisp), переименованный в 88-ом году в Allegro CL [Franz].
Lucid основали важные разработчики Common LISP, которые написали компилятор с нуля в 85-ом. Компания привлекла 16 (49.5 в 2025) миллионов долларов венчурного финансирования [Gabr96]. Их соперники из Franz считают, что вместе с господдержкой набиралось 25 (77 в 2025) миллионов [Franz].
Franz существовала на совсем другом уровне. Джон Фодераро тоже написал имплементацию Common LISP с нуля, но один, сидя дома за рабочей станцией, полученной от SUN или какого-то другого клиента из первых, как плата за портирование Franz LISP. Хотя Фодераро и писал код какое-то время один у себя дома, у него были коллеги. Офис располагался дома у другого со-основателя Фрица Кунце (Fritz Kunze), Фодераро просто не хотел "отвлекаться" на какое-то взаимодействие с ними.
То, что Franz мог конкурировать с Lucid, по видимому, объясняется не какой-то необычной эффективностью Franz, а скорее необычной неэффективностью Lucid. И мы знаем, что они могли конкурировать потому, что даже SUN, отношения с которой считались ключевыми [Stee96] для выживания Lucid с 86 по 87-ой годы переключалась на сотрудничество с Franz.
Сам CTO Lucid вспоминает [Gabr96], что программисты часто предпочитали Franz, но их руководство предпочитало Lucid. Например, основатели SUN из-за знакомства с основателями Lucid по университету.
Он же считает, что Franz мог конкурировать с ними потому, что SUN предоставила тем альфы и беты ПО Lucid. Но это может быть проекцией. Потому, что он же вспоминает, как они сами пытались получить такой доступ к ПО Franz, но те пригрозили им судом.
Их соперники из Franz называют причиной своей конкурентоспособности то, что из-за нищеты они разрабатывали свой софт на дешевых рабочих станциях, похожих на те, что использовали их клиенты [Stee96]. В Lucid писали на Лиспе сначала на Лисп-машинах Symbolics [Gabr96], а затем на топовых рабочих станциях SUN.
Имплементаторы ФЯ в академии, которые стали переключаться с MACLISP-вариантов на Common LISP обычно делали свои проекты собираемыми как Lucid CL так и Allegro CL. Но этого было недостаточно. По понятным причинам важно, чтоб проект мог использовать и имплементацию с открытым кодом, может быть не такую качественную как коммерческая, но как-то работающую. И с этим дела обстояли не особенно хорошо.
### Дети Дюны
Как мы выяснили в предыдущей главе, Spice Lisp стал эталонной имплементацией Common Lisp, код которой был общественным достоянием.
Несколько имплементаторов коммерческих Лиспов воспользовались этим. В DEC использовали код Spice Lisp для имплементации Лиспа на своих машинах вроде VAX. В TI - для MC68K [Stee96]. Самые важные платформы для имплементации ФЯ в это время. Но ни эти разработчики, ни прочие, из тех что использовали Spice Lisp не отдали никакого кода в Spice Lisp. Ни VAX, ни MC68K бэкенда он не получил.
Сегодня коммерческие разработчики развивают проекты вроде LLVM даже если их не обязывает лицензия. Но у Столлмана были все основания ожидать, что без такого принуждения не обойтись. Коммерциализаторы Лиспа в 80-е это убедительно продемонстрировали.
Тем временем, в 1985-ом году финансирование проекта SPICE прекратилось [MacL15], проект закрылся.
Но разработка бывшего SPICE LISP продолжилась, только теперь он назывался CMU Common Lisp (CMUCL) и был небольшой автономной [CMUCL] частью нового проекта университета Карнеги-Меллона. Этот проект был представителем успешного направления по созданию параллельных машин с разделяемой памятью, которое привело к созданию обычных современных компьютеров. А именно проект по написанию ядра ОС для таких машин, совместимого с 4BSD - Mach (так Джуизе записал произнесенный Рашидом придуманный Тевоняном акроним MUCK, Multiprocessor Universal Communication Kernel).
Нужно отметить, что роль имплементации Лиспа на Mach была существенно менее важной, чем имплементация Лиспа на 3BSD в Беркли несколькими годами ранее, о которой мы писали в нулевой части нашей истории. 3BSD для VAX создавался практически для того, чтоб использовать Franz LISP и написанные на нем программы. Позднее, 4BSD для MC68K уже не был так связан с Лиспом, и получил Franz LISP с некоторым опозданием. Но это не идет ни в какое сравнение с тем, насколько неважным был CMUCL для проекта Mach. Разработчики Mach заявляли поддержку Common Lisp [Acce86], но ни на популярных и важных для истории ФП VAX и MC68K ни на остальных, поддерживаемых Mach платформах, CMUCL в 80-е так и не появился [Rash89] [McDo89]. Кроме одной.
Нашлась одна коммерческая компания, которая не просто взяла общественное достояние - код SPICE LISP/CMUCL - и использовала для своих нужд, ничего не вернув в CMUCL, но решила поучаствовать именно в развитии его кода и сделать свою платформу первым обычным компьютером на котором он будет работать. И так получилось, что единственной на все оставшиеся 80-е. Этой компанией была IBM.
Платформа была не той, о которой вы, скорее всего, подумали. В IBM решили выйти на рынок рабочих станций со своей новой платформой RT, поконкурировать с SUN и Apollo.
Но лисперы нашли ответ на эту новую угрозу появления открытой имплементации Лиспа. Руководитель группы разработчиков SPICE LISP/CMUCL Фалман был одновременно и основателем Lucid. И он воспользовался своим положением руководителя группы для того, чтоб убедить IBM заказать разработку имплементации Лиспа для их новой рабочей станции у Lucid. И ему это удалось. Но дальше события развивались не очень благоприятно для Lucid, и хитрый план Фалмана был источником многих проблем, большинство из которых не выглядит такими уж неожиданными.
Для начала, этичность и даже законность действий Фалмана показалась IBM сомнительной. Возникли опасения, что кто-то из переигранных Фалманом может обратиться в суд. В IBM решили обстоятельно изучить такие риски и потратили на это от полугода до года. Только после этого IBM заключил договор с Lucid.
Это не только задержало деньги от IBM. Фалману удалось уговорить IBM давать эти деньги ему, а не университету Карнеги-Меллона в числе прочего и потому, что дедлайн не изменился. И до него теперь оставался только один год.
Тут дала о себе знать следующая проблема. У Lucid уже был собственный компилятор, но не было инструментов вроде редактора, отладчика и библиотек, например для графического интерфейса пользователя. К счастью, все это было написано в УКМ в рамках проекта SPICE и Lucid просто взяла написанный в университете код в надежде доработать его до индустриального уровня. Но написанный в университете код оказался не таким уж хорошим, а требования IBM к индустриальному уровню повыше, чем ожидали лисперы.
Наконец, IBM почему-то не понравилось, что Lucid хочет продать им как документацию написанные на деньги DARPA руководство пользователя и репорт по Common LISP. Представьте себе, пришлось в Lucid еще и документацию писать. Которая была, в основном, копией репорта. Гэбриел называет её "редакцией Пьера Менара" и тратит на объяснение шутки страницу своей книги, сопровождая пояснение обширной цитатой из Борхеса.
Короче говоря, как и в случае с лисп-машинами, с приватизацией прибылей поторопились, еще не все убытки были национализированы.
Проблема, которая оказалась неожиданной (для 80-х годов) заключалась в том, что новая рабочая станция IBM провалилась.
Вся эта история нанесла Lucid значительный ущерб, пишет Гэбриел, "возможно, что невосполнимый".
Как видно, у лисперов не было недостатка решимости ударить других лисперов ножом в спину. Но, обычно, недоставало способности сконвертировать этот удар в свою победу или выгоду для себя.
Забавно, что эта история описана не какими-то злопыхателями из Franz, а одним из основателей Lucid Гэбриелем [Gabr96], который неиронично считает себя, Фалмана и других своих коллег по Lucid жертвами IBM.
Что успели сделать для IBM RT в университете Карнеги-Меллона [MacL15] - это рантайм в шесть тысяч строк ассемблера и раскрытие команд SPICE-Lisp байт-кода в стиле компиляторов Уоррена и Карделли. Что наверное было не очень хорошо для байт-кода, который планировалось интерпретировать микрокодовым интерпретатором на PERQ. Но насколько это было плохо было бы важно в том случае, если б IBM RT была хоть сколько-нибудь популярна, а она не была.
В 85-ом году один из разработчиков CMU CL (из тех, у кого не было собственной Лисп-компании) Маклахлан (Rob MacLachlan) начал работу над более серьезным компилятором для этой имплементации Лиспа под названием Python [MacL15]. Компилятор для Лисп-системы часто носит отдельное название. Так компилятор Franz Lisp назывался liszt, а компилятор Le Lisp назывался Complice.
Но до конца 80-х компилятор CMUCL Python не генерировал код ни для каких релевантных для нашей истории платформ. В 90-е генерировал, но это уже другая история.
### Отец с атомным сердцем
Как видно, в это время в США было не много лисперов, желающих разрабатывать имплементации Common Lisp с открытыми исходниками. Возможно, что это объясняет, почему последнюю версию Franz Lisp, являющуюся общественным достоянием не попытались превратить в компилятор Common LISP, например, использовав CMU CL как фронтэнд.
Помощь пришла из Исследовательского Института Математических Наук Киотского Университета (Research Institute for Mathematical Sciences, Kyoto University).
Юаса Тайити (Yuasa Taiichi) и Хагия Масами (Hagiya Masami) написали имплементацию [Yuas85] Common Lisp под названием Kyoto Common Lisp без особого взаимодействия со своими американскими коллегами, просто по описанию Стила [Stee84]. На 60% на C и на 40% на Лиспе. Это было не ново, Franz Lisp тоже имел портируемый рантайм на C. Новым было то, что компилятор KCL транслировал Common Lisp в C-код для последующей компиляции компилятором C. Европейские и американские имплементаторы Лиспов и ФЯ считали такой подход бесперспективным [Stee96]. И появление этого компилятора изменило их мнение, в конце 80-х и начале 90-х многие попробовали этот подход. Но это уже другая история.
Компилирование через C означало медленную компиляцию и легкость портирования. Лисперы вспоминают, что и конкурирующие с KCL компиляторы тоже не отличались высокой скоростью компиляции. А вот легкость портирования была важной.
Первой машиной, для которой написали KCL был миникомпьютер Data General Eclipse MV, но не позднее ноября 85-го появились версии для более актуальных миникомпьютеров VAX-11 и рабочих станций SUN с BSD 4.2.
Портирование KCL на первую Unix-машину заняло три дня до первой работающей версии и еще несколько дней на устранение ошибок. Портирование на следую Unix-машину было сделано уже "за три вечера".
Как компилирование через C сказалось на производительности? К этому мы еще вернемся.
Конечно же, последняя версия KCL вышла уже в июне 87-го. И эту имплементацию коммерциализировали как Ibuki Common Lisp. Но, как и в случае с компиляцией через C, произошло некоторое отклонение от американской лисперской нормы. Киотский университет продолжал раздавать последнюю версию бесплатно всем академикам, которые напишут им обычное, не электронное письмо [Boye92]. Так что академик мог продолжать выпускать патчи для этого последнего KCL но не мог потом основать собственную фирму, которая будет продавать этот код, как уже поступили многие коллеги с кодом-общественным достоянием.
Теоретически, развивать KCL таким способом мог любой желающий академик, но на практике нашелся только один, по крайней мере в 80-е.
В прошлой части мы писали, как МТИ сделал из MACSYMA-общественного достояния MACSYMA-коммерческий продукт, который должен обеспечить преимущества для Лисп-машинистов из Symbolics. И что департаменту (министерству) энергетики США не особенно понравилось, что их многолетние вложения стали чьим-то там коммерческим продуктом. И МТИ передал им код MACSYMA на мертворожденном Лиспе NIL с некоторыми ограничениями для распространения. Для начала, эту DoE MACSYMA нужно было переписать на язык поживее и энергетики нашли для этого подходящего человека [Fate2003].
Уильям Шелтер (William Frederick Schelter) с 79-го года работал в Университете Остина вместе с нашим старым знакомым по нулевой части Бойером. Шелтер поддерживал код DoE MACSYMA с 82-го года и со временем переписал его на Common Lisp. Ожидалось что этот Лисп будет поживее NIL, в академии стали писать на нем, вот и очередная версия доказателя Бойера-Мура на нем, и очередная производная LCF с Cambridge ML, будут на нем писать и другие программы о которых мы еще планируем рассказать подробнее в другой раз.
И когда KCL перестал обновляться, пришлось Шелтеру разрабатывать набор патчей для него - Austin Kyoto Common Lisp. Пока CMUCL не начал поддерживать хоть какие-то актуальные для академии платформы, вся экосистема открытого кода на Common Lisp держалась на одном человеке.
Так что технически компиляция ФЯ через Common Lisp была возможна, но возможность эта была пока что не особенно привлекательна. Так что имплементаторы ФЯ желающие использовать Лисп рассматривали и другие варианты. Но это уже другая история.
ПРОДОЛЖЕНИЕ СЛЕДУЕТ
Литература
==========
[Acce86]: Accetta, Mike, Robert Baron, William Bolosky, David Golub, Richard Rashid, Avadis Tevanian, and Michael Young. "Mach: A new kernel foundation for UNIX development." (1986): 93-112.
[Alle78]: John Allen. 1978. Anatomy of LISP. McGraw-Hill, Inc., USA.
[Alle2005]: John Allen. History, Mystery, and Ballast https://international-lisp-conference.org/2005/media/allen-slides.pdf https://international-lisp-conference.org/2005/media/allen-audio.mp3
[Appe91]: Appel, Andrew W. "Compiling with Continuations." (1991). DOI:10.1017/CBO9780511609619
[Augu84]: Lennart Augustsson, A compiler for lazy ML. LFP '84: Proceedings of the 1984 ACM Symposium on LISP and functional programming August 1984 Pages 218227 doi:10.1145/800055.802038
[Augu85]: Augustsson, L. (1985). Compiling pattern matching. In: Jouannaud, JP. (eds) Functional Programming Languages and Computer Architecture. FPCA 1985. Lecture Notes in Computer Science, vol 201. Springer, Berlin, Heidelberg. doi:10.1007/3-540-15975-4_48
[Berr90]: Dave Berry, COMP.LANG.ML Frequently Asked Questions and Answers 19 Apr 1990
[Boye92]: Robert S. Boyer. Frequently Asked Questions about KCL and AKCL. https://web.cecs.pdx.edu/~mperkows/=LISP/kcl
[Burs80]: R. M. Burstall, D. B. MacQueen, and D. T. Sannella. 1980. HOPE: An experimental applicative language. In Proceedings of the 1980 ACM conference on LISP and functional programming (LFP '80). Association for Computing Machinery, New York, NY, USA, 136143. DOI:10.1145/800087.802799
[Caml261]: CAML V2-6.1
[Card82a]: EDINBURGH ML by Luca Cardelli, March, 1982. A README file accompanying the distribution of Cardelli's ML Compiler for VAX-VMS. https://smlfamily.github.io/history/Cardelli-Edinburgh-ML-README-1982_03.pdf
[Card83]: Luca Cardelli, Pre-Standard ML under Unix, August 14 1983. http://lucacardelli.name/Papers/MLUnix.pdf
[Card83b]: Luca Cardelli, ML under Unix Pose 0. 9/9/83 http://lucacardelli.name/Papers/MLUnix%20Pose%200.pdf
@ -855,17 +1088,22 @@ let val y = 2 in map (fn x => x + y) [1, 2, 3] end
[Card86]: Luca Cardelli. Amber. In Guy Cousineau, Pierre-Louis Curien, and Bernard Robinet, editors, Combinators and Functional Programming Languages, Lecture Notes in Computer Science, Vol. 242, pp 21-70. Springer-Verlag, 1986.
[Card86b]: Luca Cardelli. The amber machine. In Guy Cousineau, Pierre-Louis Curien, and Bernard Robinet, editors, Combinators and Functional Programming Languages, Lecture Notes in Computer Science, Vol. 242, pp 21-70. Springer-Verlag, 1986.
[Clar81]: Keith L. Clark and Steve Gregory. 1981. A relational language for parallel programming. In Proceedings of the 1981 conference on Functional programming languages and computer architecture (FPCA '81). Association for Computing Machinery, New York, NY, USA, 171178. doi:10.1145/800223.806776
[CMUCL]: CMUCL: Project history & who's who (2020) https://cmucl.org/credits.html
[Cous87]: Cousineau, Guy, P-L. Curien, and Michel Mauny. "The categorical abstract machine." Science of computer programming 8, no. 2 (1987): 173-202.
[Cous90]: Cousineau, Guy, and Gérard Huet. "The CAML primer." Version 2.6.1, INRIA, 1990.
[Danc87]: Gill Dancey, INFORMATICS DIVISION NEWSLETTER No. 10 May 1987 https://www.chilton-computing.org.uk/inf/pdfs/inf_newsletters.pdf
[Darl76]: Darlington, J., & Burstall, R. M. (1976). A system which automatically improves programs. Acta Informatica, 6(1). doi:10.1007/bf00263742  
[Darl81]: John Darlington and Mike Reeve. 1981. ALICE a multi-processor reduction machine for the parallel evaluation CF applicative languages. In Proceedings of the 1981 conference on Functional programming languages and computer architecture (FPCA '81). Association for Computing Machinery, New York, NY, USA, 6576. doi:10.1145/800223.806764
[Darl82]: Darlington J, Henderson P, Turner DA, editors. Functional programming and its applications: an advanced course. CUP Archive; 1982 Feb 18.
[Dijk81] Dijkstra, E. (1981). Trip report E.W. Dijkstra, Newcastle, 19-25
July 1981. Dijkstra working note EWD798. https://www.cs.utexas.edu/~EWD/transcriptions/EWD07xx/EWD798.html
[Duce86]: D. A. Duce, Software Engineering Research at RAL, 13 February 1986 https://www.chilton-computing.org.uk/inf/pdfs/seg/seg101.pdf
[Fate2003]: Souza, Paulo Ney de, Richard J. Fateman, Joel Moses and Clifford W Yapp. “The Maxima Book.” (2003). https://maxima.sourceforge.io/docs/maximabook/maximabook-19-Sept-2004.pdf
[Faul84]: Faulkner, T. L., & Pavelin, C. J. (1984). Atlas 10 computer. ICL technical journal, 4, 13-32.
[Franz]: History of Franz Inc. https://franz.com/about/company.history.lhtml
[GEC63]: GEC Series 63 https://www.chilton-computing.org.uk/inf/alvey/p003.htm
[Gord82]: Mike Gordon, Larry Paulson, 1982-11-03 in Polymorphism Vol 1 part 1 Jan 83
[Gord2000]: Gordon M. From LCF to HOL: a short history. In Proof, language, and interaction 2000 Jul 24 (pp. 169-186).
[Jenk80]: James H. Davenport and Richard D. Jenks. 1980. MODLISP. In Proceedings of the 1980 ACM conference on LISP and functional programming (LFP '80). Association for Computing Machinery, New York, NY, USA, 6574. doi:10.1145/800087.802791
[John85]: Johnsson, T. (1985). Lambda lifting: Transforming programs to recursive equations. In: Jouannaud, JP. (eds) Functional Programming Languages and Computer Architecture. FPCA 1985. Lecture Notes in Computer Science, vol 201. Springer, Berlin, Heidelberg. doi:10.1007/3-540-15975-4_37
[John86]: Johnsson, T. (1987). Target code generation from G-machine code. In: Fasel, J.H., Keller, R.M. (eds) Graph Reduction. GR 1986. Lecture Notes in Computer Science, vol 279. Springer, Berlin, Heidelberg. doi:10.1007/3-540-18420-1_53
[John87]: Johnsson, Thomas. "Compiling Lazy Functional Language." PhD Thesis, Chalmers University of Technology (1987).
[Gutt81]: John Guttag, James Horning, and John Williams. 1981. FP with data abstraction and strong typing. In Proceedings of the 1981 conference on Functional programming languages and computer architecture (FPCA '81). Association for Computing Machinery, New York, NY, USA, 1124. doi:10.1145/800223.806758
[Harp85]: Robert Harper, Report on the Standard ML Meeting, Edinburgh, May 23-25, 1985. https://smlfamily.github.io/history/Harper-SML-meeting-1985_05.pdf
[Hend80]: Henderson, Peter B.. “Functional programming - application and implementation.” Prentice Hall International Series in Computer Science (1980).
@ -874,13 +1112,25 @@ July 1981. Dijkstra working note EWD798. https://www.cs.utexas.edu/~EWD/transcri
[Hoar22]: Krzysztof R. Apt and Tony Hoare (Eds.). 2022. Edsger Wybe Dijkstra: His Life,Work, and Legacy (1st. ed.). ACM Books, Vol. 45. Association for Computing Machinery, New York, NY, USA. doi:10.1145/3544585
[HOL88]: HOL88 https://github.com/theoremprover-museum/HOL88
[Huda07]: Paul Hudak, John Hughes, Simon Peyton Jones, and Philip Wadler. 2007. A history of Haskell: being lazy with class. In Proceedings of the third ACM SIGPLAN conference on History of programming languages (HOPL III). Association for Computing Machinery, New York, NY, USA, 1211255. DOI:10.1145/1238844.1238856
[McJo24]: Paul McJones, John Allen (1937-2022) and Anatomy of LISP https://mcjones.org/dustydecks/archives/2024/04/11/1249/
[Huet15]: Gérard Huet, Thierry Coquand and Christine Paulin. Early history of Coq, September 2015 https://coq.inria.fr/refman/history.html
[Jenk80]: James H. Davenport and Richard D. Jenks. 1980. MODLISP. In Proceedings of the 1980 ACM conference on LISP and functional programming (LFP '80). Association for Computing Machinery, New York, NY, USA, 6574. doi:10.1145/800087.802791
[John85]: Johnsson, T. (1985). Lambda lifting: Transforming programs to recursive equations. In: Jouannaud, JP. (eds) Functional Programming Languages and Computer Architecture. FPCA 1985. Lecture Notes in Computer Science, vol 201. Springer, Berlin, Heidelberg. doi:10.1007/3-540-15975-4_37
[John86]: Johnsson, T. (1987). Target code generation from G-machine code. In: Fasel, J.H., Keller, R.M. (eds) Graph Reduction. GR 1986. Lecture Notes in Computer Science, vol 279. Springer, Berlin, Heidelberg. doi:10.1007/3-540-18420-1_53
[John87]: Johnsson, Thomas. "Compiling Lazy Functional Language." PhD Thesis, Chalmers University of Technology (1987).
[Kess86]: R. R. Kessler, J. C. Peterson, H. Carr, G. P. Duggan, and J. Knell. 1986. EPIC - a retargetable, highly optimizing Lisp compiler. In Proceedings of the 1986 SIGPLAN symposium on Compiler construction (SIGPLAN '86). Association for Computing Machinery, New York, NY, USA, 118130. doi:10.1145/12276.13323
[MacL15]: Rob MacLachlan, History of the CMUCL Project (2015) https://www.cons.org/cmucl/doc/cmucl-history.html
[MacQ85]: David MacQueen and Robin Milner. 1985. Record of the Standard ML Meeting, Edinburgh, 68 June 1984. Polymorphism: The ML/LCF/Hope Newsletter II, 1 (Jan.), 16. http://lucacardelli.name/Papers/Polymorphism%20Vol%20II,%20No%201.pdf
[MacQ14]: Luca Cardelli and the Early Evolution of ML, by David MacQueen. A paper presented at the Luca Cardelli Fest at Microsoft Research Cambridge on Sept. 8, 2014.
[MacQ15]: MacQueen, David B. The History of Standard ML: Ideas, Principles, Culture https://www.youtube.com/watch?v=NVEgyJCTee4
[MacQ20]: MacQueen, David B., Robert Harper and John H. Reppy. “The history of Standard ML.” Proceedings of the ACM on Programming Languages 4 (2020): 1 - 100.DOI:10.1145/3386336
[MacQ22]: D. MacQueen, A New Match Compiler for Standard ML of New Jersey https://icfp22.sigplan.org/details/mlfamilyworkshop-2022-papers/3/A-New-Match-Compiler-for-Standard-ML-of-New-Jersey
[Matt88]: Matthews D.C.J. (1988) An Overview of the Poly Programming Language. In: Atkinson M.P., Buneman P., Morrison R. (eds) Data Types and Persistence. Topics in Information Systems. Springer, Berlin, Heidelberg. doi:10.1007/978-3-642-61556-6_4
[Matt89]: Matthews, David CJ. Papers on Poly/ML. No. UCAM-CL-TR-161. University of Cambridge, Computer Laboratory, 1989.
[Matt2000]: David Matthews, History and Acknowledgements https://polyml.org/FAQ.html#history
[Maun86]: Mauny, M., & Suárez, A. (1986). Implementing functional languages in the Categorical Abstract Machine. Proceedings of the 1986 ACM Conference on LISP and Functional Programming - LFP 86. doi:10.1145/319838.319869
[Maun88]: Michel Mauny, A new functional language: CAML Release 2.5 in comp.lang.misc, 05/09/88
[McDo89]: D. McDonald, editor. CMU Common Lisp User's Manual: Mach/IBM RT PC edition. Carnegie Mellon University. CMU-CS-89-132, April 1989. https://doi.org/10.1184/R1/6604121.v1
[McJo24]: Paul McJones, John Allen (1937-2022) and Anatomy of LISP https://mcjones.org/dustydecks/archives/2024/04/11/1249/
[Meir83]: Meira, S. R. L. 1983 Sorting algorithms in KRC: implementation, proof and performance. Computing Laboratory rep. no. 14. University of Kent at Canterbury.
[Meir83b]: recursion -- again from net.lang srlm@ukc.UUCP (S.R.L.Meira) (08/16/83) https://usenet.trashworldnews.com/?thread=132780
[Miln82]: Milner, Robin. “How ML evolved.” (1982).
@ -891,22 +1141,35 @@ July 1981. Dijkstra working note EWD798. https://www.cs.utexas.edu/~EWD/transcri
[Miln84b]: Robin Milner. 1984. A proposal for standard ML. In Proceedings of the 1984 ACM Symposium on LISP and functional programming (LFP '84). Association for Computing Machinery, New York, NY, USA, 184197. doi:10.1145/800055.802035
[Miln84c]: Robin Milner, The Standard ML Core Language, October, 1984. The second draft of the "Core Language" design. https://smlfamily.github.io/history/SML-proposal-10-84.pdf
[Miln85]: Robin Milner, The Standard ML Core Language (Revised), September, 1985. The third draft of the "Core Language" design. https://smlfamily.github.io/history/SML-proposal-9-85.pdf
[Miln88]: Harper, R.M., Milner, R., Tofte, M., The Definition of Standard ML, Version 2 Report ECS-LFCS-88-62, Laboratory for Foundations of Computer Science, Computer Science Department, Edinburgh University, 1988.
[Mitc84]: John C. Mitchell. 1984. Coercion and type inference. In Proceedings of the 11th ACM SIGACT-SIGPLAN symposium on Principles of programming languages (POPL '84). Association for Computing Machinery, New York, NY, USA, 175185. https://doi.org/10.1145/800017.800529
[MLKit2002]: About the ML Kit https://web.archive.org/web/20020827144153/http://www.itu.dk/research/mlkit/about.html
[Moss89]: A. E. Mossberg, Edinburgh ML (summary) comp.lang.misc, Dec 18, 1989
[Mosses]: Peter Mosses, Affiliations https://pdmosses.github.io/affiliations/
[Muss81]: D. Kapur, D. R. Musser, and A. A. Stepanov. 1981. Operators and algebraic structures. In Proceedings of the 1981 conference on Functional programming languages and computer architecture (FPCA '81). Association for Computing Machinery, New York, NY, USA, 5964. doi:10.1145/800223.806763
[Neum90]: Pierre-Louis Neumann, New Caml version in comp.lang.misc, 03/29/90
[Nuprl94]: Nuprl 3.2 (26-MAY-94) https://github.com/owo-lang/nuprl-3 https://web.archive.org/web/20220630143027/http://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/areas/reasonng/atp/systems/nuprl/0.html
[Paul96]: Paulson, Lawrence Charles. “ML for the working programmer (2. ed.).” (1996).
[Paul22b]: Lawrence Paulson. Memories: Edinburgh ML to Standard ML https://lawrencecpaulson.github.io/2022/10/05/Standard_ML.html
[PERQ1]: PERQ History, 1.3. EARLY DAYS http://www.chilton-computing.org.uk/acd/sus/perq_history/part_1/c3.htm
[POP19]: INFORMATION ABOUT POPLOG AND POP-11 2019 https://poplogarchive.getpoplog.org/poplog.info.html
[POPLOG]: Poplog https://github.com/poplog/poplog
[RAL83]: DISTRIBUTED INTERACTIVE COMPUTING NOTE 893, RUTHERFORD APPLETON LABORATORY, 3 October 1983 http://www.dataweb.clrc.ac.uk/acd/pdfs/dic/dic841.pdf
[RAL84]: The Software Technology Initiative Final Report 1981-1984
October 1984 http://www.dataweb.stfc.ac.uk/inf/literature/reports/sti_report/p001.htm
[RAL87]: Informatics Annual Report 1986-87 http://www.chilton-computing.org.uk/inf/literature/inf_annual_reports/p003.htm
[RAL89]: Informatics Annual Report 1988-9 http://www.chilton-computing.org.uk/inf/literature/inf_reports/p005.htm
[Rash89]: Rashid, Richard, Robert Baron, Alessandro Forin, David Golub, Michael Jones, Douglas Orr, and Richard Sanzi. "Mach: a foundation for open systems (operating systems)." In Proceedings of the Second Workshop on Workstation Operating Systems, pp. 109-113. IEEE, 1989.
[Rich85]: Richards, H. (1985). Applicative programming. Systems Research, 2(4), 299306. doi:10.1002/sres.3850020409 
[Ryde82]: Rydeheard, David Eric. "Applications of category theory to programming and program specification." (1982).
[Schmidt]: CV https://people.cs.ksu.edu/~schmidt/vita.html
[Slom89]: Sloman, Aaron. "The Evolution of Poplog and Pop-11 at Sussex University." POP-11 Comes of Age: The Advancement of an AI Programming Language (1989): 30-54.
[Sokolowski]: CV https://prabook.com/web/stefan_andrzej.sokolowski/90807
[SPJ82]: Simon L Peyton Jones. 1982. An investigation of the relative efficiencies of combinators and lambda expressions. In Proceedings of the 1982 ACM symposium on LISP and functional programming (LFP '82). Association for Computing Machinery, New York, NY, USA, 150158. doi:10.1145/800068.802145
[SPJ85]: Jones, S. L. P. (1985). Yacc in sasl — an exercise in functional programming. Software: Practice and Experience, 15(8), 807820. doi:10.1002/spe.4380150807
[Stee82b]: Guy L. Steele. 1982. Report on the 1980 LiSP Conference Stanford University. August 25-27, 1980. SIGPLAN Not. 17, 3 (March 1982), 2236. doi:10.1145/947912.1361218
[Stee84]: Steele, Guy L. "Common LISP. The language." Bedford: Digital Press (1984).
[Stee96]: Guy L. Steele and Richard P. Gabriel. 1996. The evolution of Lisp. Uncut draft.
[Stra67]: Strachey, Christopher S.. “Fundamental Concepts in Programming Languages.” Higher-Order and Symbolic Computation 13 (2000): 11-49.
DOI:10.1023/A:1010000313106
[Turn79]: Turner, D. A. (1979). A new implementation technique for applicative languages. Software: Practice and Experience, 9(1), 3149. doi:10.1002/spe.4380090105 
@ -920,3 +1183,6 @@ DOI:10.1023/A:1010000313106
[Warr77b]: David H D Warren. 1977. Prolog - the language and its implementation compared with Lisp. Slides https://www.softwarepreservation.org/projects/prolog/edinburgh/doc/slides-ACM1977.pdf
[Whit77]: White, Jon L. "Lisp: Program is Data: A historical perspective on MACLISP." In Proceedings of the 1977 MACSYMA Users' Conference, MIT Laboratory for Computer Science, Cambridge, Mass, pp. 181-189. 1977.
[Whit79]: Jon L. White. NIL: A perspective. Proceedings of 1979 MACSYMA Users' Conference, Washington, D.C., June 1979. https://www.softwarepreservation.org/projects/LISP/MIT/White-NIL_A_Perspective-1979.pdf
[Witt85]: R. W. Witty, SEG ANNUAL REPORT September 84-September 85, 30 September 1985 https://www.chilton-computing.org.uk/inf/pdfs/seg/seg74.pdf
[Wolf89]: David Wolfram, ACE Version 1.3 Distribution comp.lang.misc, Jun 20, 1989
[Yuas85]: Yuasa, Taiichi, and Masami Hagiya. "Kyoto Common Lisp Report." Research Institute for Mathematical Sciences, Kyoto University (1985.11.13).

View file

@ -14,6 +14,8 @@
---------------------------
[Обновление 2025-08-09](hopes.md#le-ml)
[Обновление 2025-06-30](hopes.md#fasadrenovering)
[Обновление 2025-05-31](hopes.md#любой-принц-в-янтаре)