Compare commits

..

10 commits

Author SHA1 Message Date
klapaucius
a2ee293144
Add update links to index.md 2026-01-02 02:24:51 +05:00
klapaucius
0be98c050d
dec. upd. 2026-01-02 02:22:13 +05:00
klapaucius
c71ca51881
index 2025-12-13 18:59:58 +05:00
klapaucius
ea1ac1fca1
citations 2025-12-13 18:56:55 +05:00
klapaucius
4ddb4ca404
TOC 2025-12-13 18:52:52 +05:00
klapaucius
1677b0dbcf
nov. upd. GRIP 2025-12-13 18:50:18 +05:00
klapaucius
4133565bd7
Add update links to index.md 2025-11-16 23:05:29 +05:00
klapaucius
2c94b28d7a
TOC 2025-11-16 23:02:32 +05:00
klapaucius
5e3dfb9d59
October update 2025-11-16 22:51:40 +05:00
klapaucius
305f859eb9
Add new update link for 2025-10-30 2025-10-30 21:50:40 +05:00
2 changed files with 306 additions and 1 deletions

297
hopes.md
View file

@ -34,6 +34,11 @@
- [Big in Japan](#big-in-japan)
- [Успели забыть о Прологе больше, чем японцы успели узнать](#успели-забыть-о-прологе-больше-чем-японцы-успели-узнать)
- [Новая надежда](#новая-надежда)
- [Граф 0](#граф-0)
- [Барендрегт против лямбды](#барендрегт-против-лямбды)
- [Самый известный птеродактиль на Панталасском театре](#самый-известный-птеродактиль-на-панталасском-театре)
- [Негативное пространство](#негативное-пространство)
- [День зависимости](#день-зависимости)
- [Литература](#литература)
@ -1233,11 +1238,303 @@ filter(p,xs) <= {x | x in xs : p x}
В функциональных языках Эдинбургской исследовательской программы такие расширения не прижились. Они сыграли более заметную роль в HOPE-фикации Пролога. Но это уже другая история.
### Граф 0
В апреле 84-го при поддержке директората Alvey состоялась встреча представителей академии и индустрии на которой обсуждали общую вычислительную модель для параллельных вычислений. Участники встречи разделились на два лагеря. Одни считали, что общий промежуточный язык будет иметь достаточно плюсов чтоб скомпенсировать возможные проблемы с производительностью. Другие считали, что производительность слишком важна для таких компромиссов. Сторонники единого промежуточного языка победили. Победили в первой битве, но смогли ли они победить в войне? Давайте выясним.
Единый промежуточный язык назвали DACTL (Declarative Alvey Compiler Target Language). DACTL должен [Glau87] был подходить для трансляции в него таких языков как HOPE, Prolog и даже Lisp. Промежуточный язык также должен был подходить для исполнения на параллельных машинах программы Алви, и это не только Flagship-машина. О другой спецмашине программы мы еще расскажем позднее.
Язык должен был быть достаточно низкоуровневым чтоб описывать детали порядка вычисления и где происходит копирование, а где - переписывание для разделения результатов. Но не слишком низкоуровневым. Быть ФЯ, о свойствах кода на котором легко рассуждать и свойства которого легко доказывать.
Директорат Алви организовал команду по разработке DACTL в июле 84-го. Процесс создания DACTL пошел в Университете Восточной Англии (University of East Anglia) под руководством Ронана Слипа (Ronan Sleep) и Джона Глоерта (John Glauert).
Слип был соавтором героя прошлой части Келлера. Второй руководитель был связан с событиями предыдущих частей сильнее.
Глоерт [Glau1] [Glau2] получил степень бакалавра в Кембридже в 76-ом. Степень магистра он получал в Университете Манчестера, где в это время шли работы над Dataflow-машиной, которую мы упоминали в прошлой части. Магистерская диссертация была об имплементации ФЯ с рекурсией на Dataflow-машине.
Вернувшись после этого в Кембридж Глоерт защитил там докторскую диссертацию. Затем он вернулся в Манчестер и снова поработал там в Dataflow-проекте, над дизайном и имплементацией SISAL. После всего этого, в 84-ом году Глоерт начал работу в Университете Восточной Англии.
DACTL планировали создать за три итерации [Glau87]. Описание первой итерации Dactl0 было готово в мае 85-го. В сентябре 85-го состоялся первый релиз образцового интерпретатора [Glau91].
Финансирование от Alvey стало поступать в университет с мая 85-го. DACTL-проект был третьим по размеру спецмашинным проектом Алви. Выделенные на него средства [Blac85] - 360тыс. фунтов или 1.9 миллионов долларов в 2025 - были несопоставимы с первым по размеру проектом Flagship, но вполне сопоставимы со вторым.
DACTL - язык уравнений с паттерн-матчингом [Glau87]
```
PROGRAM test;
IMPORTS lists;
ATOM append;
RULE
<append nil $x> => !$x;
<append <cons $h $t> $x> := <cons $h !<append $t $x>>;
<append $a $b> := !<append !$a $b>;
REWRITE !<append <cons 1 nil> <cons 2 nil>>;
ENDPROGRAM test;
```
паттерны в Dactl лево-линейные (имена переменных не могут повторяться в паттерне для обозначения равенства).
Все вычисления явно обозначаются `!` и если восклицательного знака нет - это не вызов функции, а просто данные, конструкторы. Переписывание на месте `:=` и возвращение копии ссылки `=>` тоже явно указывается.
Вся эта получившаяся явность авторам быстро разонравилась и они решили сделать следующую версию менее явной или, по крайней мере сделать указания менее многословными и более высокоуровневыми.
И если не хватало проблем со взаимодействием между проектами от того, что промежуточный язык разрабатывается в отдельном проекте от имплементирующих его машин и компилирующих в него компиляторов, то теперь проект разработки промежуточного языка стал еще и международным.
### Барендрегт против лямбды
Университет Восточной Англии [Glau87] [Brus87] объединил усилия с голландским проектом по созданию параллельной машины редукции (Dutch Parallel Reduction Machine Project) под руководством более известного другими своими работами Хенка Барендрегта (Hendrik Pieter Barendregt).
Совместно они разработали язык LEAN (the Language of East Anglia and Nijmegen), который стал основой для Dactl1. Да, это означает, что у разработки Dactl было более трех итераций, но это, наверное, самое безобидное отклонение от первоначальных планов. Этот LEAN не имеет никакого отношения к современному языку Lean.
Как было принято в 80-х, Нидерланды тоже решили ответить на японский вызов [Bare87]. Так что в ноябре 1984 три исследовательских группы университетов Амстердама, Неймегена и Утрехта
начали совместный проект, спонсируемый министерством науки и образования.
Первая фаза, продолжающаяся до конца 87-го должна была ответить на вопрос: возможно ли и реалистично ли построить эффективную машину параллельной редукции? Эта цель может показаться не очень амбициозной но голландский ответ на японский вызов был довольно серьезным. Разрабатывались как минимум две специальные машины. Philips Laboratories работали над Distributed Object Oriented Machine, а университеты над Experimental Parallel Reduction Machine.
Что более важно для нашей истории - разрабатывали семейство быстрых имплементаций функциональных языков для обычных машин, которое если и не живет в полном смысле этого слова, то по крайней мере влачит жалкое существование до сих пор.
Первая имплементация семейства имплементировала не язык LEAN, а его чисто-функциональное подмножество без операции переписывания `:=` - язык CLEAN.
Некоторые читатели, возможно, знают современный язык с таким названием - чисто-функциональный ленивый язык с классами типов, который известен приличной производительностью, которая достигается не без помощи "плоских" объектов и уникальных типов, использующихся для изменения массивов на месте. Это не тот язык о котором мы рассказываем сейчас. В нем нет массивов, классов типов, уникальных типов да и типов вообще.
Нельзя сказать, что CLEAN 87-го года не имеет никакого отношения к современному, как было в случае LEAN. У первого и современного CLEAN общие авторы Марко ван Ээкелен (Marko C.J.D. van Eekelen) и его научрук Маринус Плазмейер (Marinus J. Plasmeijer). Оба языка являются продуктами одной исследовательской программы. Но один не превратился в другой путем добавления тех фич, которые сегодня выделяют Clean из множества прочих ФЯ. Синтаксически они настолько различны, насколько возможно в обсуждаемую эпоху HOPE-фикации. Первый CLEAN как LML, HOPE и SML происходят от поздних версий NPL с характерными разделителями между уравнениями одной группы, а современный Clean как Haskell и языки Тернера от раннего NPL с более легковесным синтаксисом.
Мелкие отличия от прочих поздних NPL-ей CLEAN 87 по видимому унаследовал от предыдущего ФЯ Барендрегта под названием TALE (Typed Applicative Language Experiment) [Bare86] на момент описания в 86-ом году Он не был имплементирован и не было конкретных планов имплементации.
```
list $ t = rectype ls: (* |(t, ls)).
Def:
map f <> -> <>;
map f (a:b) -> (f a) : (map f b).
map (`x -> x + y) <1, 2, 3> where y = 1 end
```
Так выглядит TALE, а (C)LEAN - намного проще [Brus87].
```
Map f Nil -> Nil |
Map f (Cons a b) -> Cons (Ap f a) (Map f b);
```
Планы имплементации CLEAN были. И та их часть, которая касалась обычных компьютеров была осуществлена.
Разработчики CLEAN считают, что хорошую имплементацию ФЯ на обычном железе может сделать и не так просто, но сделать можно. В середине 80-х эта проблема решена. Имплементаторы ФЯ теперь знают как эффективно реализовать ленивость, возвращение функций из функций и рекурсию. Если оптимизировать хвостовые вызовы, использовать редукцию графов и избегать ее где это возможно, заменяя обычными вычислениями на стеке, то можно добиться производительности сравнимой с имплементациями обычных императивных языков.
Разработчики CLEAN считают, что не все еще хорошо со сборкой мусора и анализом строгости - было бы неплохо поработать на этих направлениях. И тут сложно с ними не согласиться.
Существенно позднее авторы языка напишут, что он разрабатывался с самого начала проекта в 84-ом году, проектирование первой версии закончилось в 85-ом, первый компилятор был написан в 86-ом [Plas95]. В 87-ом году вышла первая дошедшая до на статья, в которой описывается версия 4.0 компилятора и языка, который определен только своей имплементацией. Версия современного Clean меньше, но это потому, что следующей версией после 4.0 была 0.5. Этот компилятор был первым публичным релизом в том же 87-ом году [Plas01].
Как и их лондонские коллеги, авторы CLEAN начали с компилятора для VAX-11, но более интересные результаты получили продолжив работу компиляторами для MC68K.
(C)LEAN был задуман как промежуточный язык, так что сначала в нем не было `let`, `where`, локальных функций и даже лямбд. Что может выглядеть неожиданно, принимая во внимание то, какими работами Барендрегт более известен.
Как ни странно, Барендрегт и остальные авторы (C)LEAN считают, что промежуточным языком для имплементаций ФЯ должна быть не лямбда с расширениями, а язык уравнений.
Лямбда-исчисление часто представляется как сама собой разумеющаяся вычислительная модель для ФЯ, пишут [Brus87] они, вот только большинство имплементаций основаны не на лямбда-исчислении, а на комбинаторной логике (SKI-интерпретатор Тернера, G-машина, CAM), а для представления функциональных программ используются графы, лишние вычисления в которых предотвращаются разделением подграфов. ПМ очень важен в ФЯ, так что имеет смысл включить его в вычислительную модель.
Получается, что если мы хотим вычислительную модель для ФЯ близкую к имплементации, то лямбда-исчисление уже совсем не выглядит очевидным выбором.
Это авторы (C)LEAN дискутируют с теми, кто имплементировал HOPE на обычном железе и с другим машинистом, будущим важным героем нашей истории. К этому мы еще вернемся.
Первоначально планировалось, что компилятор CLEAN станет компилятором LEAN поддержав мутабельность. И может быть даже логические переменные, приблизившись к DACTL.
Питер Копман (Pieter Koopman) и др. показали [Brus87], что в Clean можно компилировать SASL, TALE и OBJ2 - новую версию языка алгебраической спецификации OBJ0, о которой мы рассказывали в нулевой части. Главным же достижением должен был стать компилятор нового языка Тернера. Этим планам не суждено было сбыться и к причинам мы еще вернемся в следующей главе с новыми приключениями Тернера. Но и остальные перечисленные компиляторы не стали чем-то большим, чем эксперименты. CLEAN как промежуточный язык не состоялся.
Проблема в том, что CLEAN пока что не очень хороший промежуточный язык. Он не поддерживает локальные функции оставляя лямбда-лифтинг разработчикам транслятора в CLEAN. Не поддерживает CAF что важно для ленивых языков. Но хуже всего то, что CLEAN компилируется в медленный код. Код сгенерированный компилятором Lazy ML работает в 7-9 раз быстрее, в зависимости от микробенчмарка.
Но авторы компилятора CLEAN не унывают. Они считают, что смогут существенно улучшить производительность кода и собираются сконцентрировать свои усилия на этом. Больше использовать стек, лучше компилировать ПМ, умнее управлять памятью.
Важную роль в отставании от LML сыграло то, что первые версии CLEAN хоть и были языком уравнений с самого начала, еще не были полностью HOPE-фицированными.
Но CLEAN стал полностью HOPE-фицированным языком до конца 80-х годов. В это время еще не угасла надежда на то, что CLEAN будет промежуточным языком для какого-то компилятора кроме CLEAN, но появилось движение в сторону более-менее полноценного языка, хоть и все еще простого [Gron90]. И CLEAN оброс соответствующими фичами [Nock91].
```
MODULE Test;
TYPE
:: List x -> Cons x (List x) |
List x -> Nil ;
RULE
:: Map (=> x y) [x] -> [y] ;
Map f [] -> [] |
Map f [a | b] —> [f a | Map f b] ;
```
знакомые с современным Clean могут заметить тут пару знакомых синтаксических деталей, но это добавление деталей никогда не сложится в CLEAN похожий на современный. Современный будет сделан более-менее с нуля спустя годы, но это уже другая история.
### Самый известный птеродактиль на Панталасском театре
После совместной с голландцами "фундаментальной переработки вычислительной модели" в Университете Восточной Англии разработали новую версию DACTL основанную на LEAN.
Спецификация ядра Dactl была готова в марте 87, принята Flagship вскоре после того. Черновик описания новой версии Dactl появился в июне 87-го и готовое описание в декабре 87-го.
Никаких фундаментальных переработок больше не было, так что последняя версия Dactl не особенно отличалась от второй и была готова в начале января 89-го. Образцовый интерпретатор - вскоре после этого [Glau91].
Теперь DACTL выглядел так:
```
MODULE Test;
IMPORTS Lists;
SYMBOL REWRITABLE Append;
RULE
Append[Cons[h t] y] => #Cons[h ^*Append[t y]] |
Append[Nil y] => *ForceList[y] ;
Append[x y] => #Append[^*x y] ;
ENDMODULE Test;
```
`|` - разделитель между уравнениями, порядок которых не важен. И `;` - разделитель между уравнениями, порядок которых важен.
Аннотации порядка вычисления теперь показывают зависимость одних промежуточных результатов от других, так что ленивый код требовал меньше аннотаций и даже меньше уравнений:
```
Append[Cons[h t] y] => *Cons[h Append[t y]] |
Append[Nil y] => *y ;
```
Как видите, язык хоть и напоминает (C)LEAN, но не является просто им с дополнительными аннотациями.
Dactl разрабатывался итерационно для того, чтоб учитывать опыт его использования и для приобретения этого опыта использования Dactl0 и Dactl1 в Университете Восточной Англии и не только написали несколько трансляторов.
Промежуточный язык должен был подходить и для трансляции логических языков, так что Джордж Пападопулос (George Papadopoulos) написал трансляторы Parlog [Papa89] и GHC [Glau88] в DACTL. GHC не имеет ничего общего с более известным и релевантным для нашей истории Glasgow Haskell Compiler и в данном случае расшифровывается Guarded Horn Clauses.
Компания Harlequin, которая уже упоминалась в нашей истории, ей Радиолокационная Лаборатория заказала компилятор SML, для проекта Flagship писала в 87-ом году Harlequin Flagship Common Lisp Compiler.
Более соответствующими теме нашей истории компиляторами были три транслирующих HOPE-фицированные ФЯ в DACTL.
Один из авторов DACTL в университете Восточной Англии Ричард Кеннвей (Richard Kennaway) написал в 88-ом году транслятор CLEAN. Этот язык в описываемое время был довольно минималистичным и близким к DACTL, так что компилятор вышел не самым сложным. Второй восточно-английский компилятор был существенно сложнее.
Новый важный герой нашей истории Кевин Хаммонд (Kevin Hammond) написал транслятор языка PSML. Что означает Parallel Standard ML. Как обычно бывает в этой главе, стандартный ML был не совсем стандартным и относился к SML версии 2 (т.е. образца 88-го года) на основе которого был сделан, примерно так же как первоначальный Lazy ML относился к LCF/ML. PSML - декларативное подмножество Standard ML. Из этого языка убраны все императивные конструкции: циклы, изменяемые ссылки и большинство функций ввода-вывода. Исключения не убраны полностью, а заменены на ошибки-значения, похожие на те что в Hope+ [Hamm89b].
PSML компилировался сначала в DACTL0 [Glau87]
, а потом в в DACTL1, Хаммонд экспериментировал и со строгой и с ленивой версией языка. Хаммонд писал компилятор в рамках работы над диссертацией и защитил её [Hamm91] в ноябре 88-го.
Третьим транслятором был уже упомянутый нами лондонский компилятор параллельного HOPE+. Правда, компилировал он не в DACTL, а в его подмножество, поддерживаемое Flagship-машиной. Подмножество называлось MONSTR.
Как и трансляторы в CLEAN, эти экспериментальные компиляторы не были важными для нашей истории. DACTL тоже был не особенно удачным промежуточным языком. Идея единого промежуточного языка восторжествовала на этапе планирования, но не выдержала испытаний на этапе имплементации. Вместо единого языка получилось множество. Больше, чем получилось бы, если бы каждый проект спецмашины имел собственный язык с самого начала.
Существовали только две полных имплементации DACTL: университетский образцовый интерпретатор и транслятор в C под названием ICL IIS, который написали в ICL - компании, строившей прототипы Alice и Flagship.
Транслятор в C может для нашей истории быть важнее всех этих спецмашин вместе взятых. Но не этот. На новых рабочих станциях SUN, которые были в 2-3 раза быстрее VAX-11/780 он выдавал только 1000 nfib в секунду. Чуть более чем в два раза быстрее, чем образцовый интерпретатор. И на десятичные порядки медленнее, чем последнее слово техники функционального компиляторостроения.
Оба спецмашинных проекта директората Алви нашли способ не использовать DACTL. И если Flagship имплементировал подмножество, только то, что хотел, то другая Алви-машина отказалась от промежуточного языка уравнений с ПМ полностью, выбрав расширенную лямбду. Но это уже другая история.
### Негативное пространство.
Саймон Пейтон-Джонс (Simon Loftus Peyton Jones) [SPJ18], как и его шведский коллега Августссон, относится к тому поколению имплементаторов ФЯ, которое познакомилась с компьютером еще в школе. В этой же школе учился функциональный машинист из прошлой части Томас Кларк. В результате этого опыта у Кларка и Пейтон-Джонса появилось желание разрабатывать компьютеры. И разработка компьютеров - это не те работы, которыми Пейтон-Джонс известен. Но всему свое время.
После школы, в Кембриджском университете Пейтон-Джонс повстречал ещё больше героев нашей истории: Хьюза и Фейрберна.
В Кембридже, как и в университете Чалмерса, пока что не было компьютерных наук как специальности. Так что Пейтон-Джонс сначала изучал математику. Но математика показалась ему слишком сложной, поэтому он стал изучать электротехнику. Компьютерные науки, впрочем, успели появится достаточно рано чтоб Пейтон-Джонс получил и такую специальность за один 79-80 год.
На то, что Пейтон-Джонс заинтересовался не просто разработкой компьютеров, а именно специальных ФП-машин, повлияли уже упоминавшиеся нами преподаватель Артур Норман от которого Пейтон-Джонс впервые узнал о функциональном программировании, Тьюринговская лекция Бэкуса и, разумеется, статья Тернера.
Как и на его шведских коллег, на Саймона Пейтон-Джонса произвела впечатление статья Тернера про комбинаторный интерпретатор. Дипломная работа Пейтон-Джонса была сравнением комбинаторного интерпретатора с SECD. Сам СПЖ считает ее не особенно полезной потому, что из сравнения наивных интерпретаторов не стоит делать далеко идущих выводов. На основе этого диплома была написана уже упомянутая нами в прошлых частях статья.
Пейтон-Джонс не хотел работать над докторской диссертацией, он хотел работать в индустрии. Об этом он вскоре пожалел - работа в индустрии ему не особенно понравилась, и через два года он вернулся в академию.
В 82-ом Пейтон-Джонс стал читать лекции в Университетском колледже Лондона (University College London). Но для того чтоб преподавать надо же защитить диссертацию? Не в те времена. Внезапно оказалось, что нужно учить компьютерным наукам много-много студентов, а преподавателей не хватает. Так что Пейтон-Джонс мог работать, а диссертацию защитить когда-нибудь потом.
Для того чтоб освоить исследовательскую работу, Пейтон-Джонс написал уже упомянутую нами статью про написание Yacc на SASL. Пока работал над ней, он общался с Тернером и даже называет Тернера своим неформальным научным руководителем.
В апреле 83-го Саймон Пейтон-Джонс организовал [SERC83] коллоквиум по декларативному программированию в Университетском колледже Лондона. Там Йонссон впервые выступил с докладом о G-машине, о том как быстро можно редуцировать графы, а избегать их редукции - еще быстрее.
И именно этим Пейтон Джон со своими коллегами Клеком (Christopher D. Clack), Салкилдом (Jon Salkild) и Харди (Mark S. Hardie) и стали заниматься, когда Университетский колледж Лондона начал второй по величине проект директората Алви по созданию ФП-машины. Проект назвали GRIP (Graph Reduction In Parallel). Индустриальными партнёрами были все та же ICL и High Level Hardware Limited.
На второй по величине проект выделили в десятки раз меньше денег, чем на первый - всего 480 тыс. фунтов (два с половиной миллиона долларов в 2025) [Blac85], так что подходы исполнителей проектов просто обязаны были существенно отличаться.
Но GRIP-машина отвечала на проблемы ALICE с производительностью схожим с Flagship образом. Правда, хватало и различий [SPJ88a].
В GRIP осталось разделение на вычислительные элементы и элементы разделяемой памяти. Вычислительные элементы PE (Processing Element) - настолько обычные компьютеры, насколько это возможно. С новыми процессорами Motorola 68020 и большой локальной памятью, недоступной остальным процессорам компьютера. Сначала 128Кб но планировалось увеличение до 512Кб [SPJ87a] а затем и 1Мб [SPJ88a]. Обычные компьютеры умеют делать очень хорошо и дешево, и с каждым годом все лучше и дешевле, очень важно воспользоваться этими возможностями.
И что более важно для нашей истории, схожесть вычислительного элемента с обычной рабочей станцией означает, что участники проекта GRIP разрабатывали способы имплементации ФЯ применимые на обычной рабочей станции.
Но где же тогда специальное в этой спец-машине? Специальным микропрограммируемым железом являются только блоки разделяемой между процессорами памяти IMU (Intelligent Memory Unit). Эти микропрограммируемые компьютеры, оптимизированные для перемещения данных и операций с указателями, собирали мусор и предоставляли доступ к разделяемой памяти не как к массиву слов, а к операциям над графами и их элементами.
Авторы считают основным недостатком то, что работа с памятью и особенно кэшами в обычных компьютерах лучше и быстро совершенствуется. Специальный компьютер блока памяти не может полноценно использовать эти успехи. Авторам не очевидно, что специальность компьютера сможет компенсировать это отставание.
Эта организация памяти еще больше мотивирует минимизацию изменений графа. Переписыватель графа, чтоб быть эфективным переписывателем, переписывает только в том случае, если без переписывания будет потеряно разделение. Это мотивировало работу разработчиков GRIP над усовершенствованием способов компиляции ФЯ.
В блоке разделяемой памяти до 4 миллионов 40-битных слов.
Для соединения блоков используется уже существующая обычная шина, в отличии от прочих разработчиков спецмашин, разработчики GRIP не собирались связываться и с этим.
Но к существующим шинам не подключить много блоков, так что структура становится двухуровневой. 4 вычислительных блока и один блок разделяемой памяти объединяются на одной плате, которых может быть до 20. К блоку разделяемой памяти такой платы есть доступ и с других плат, но более медленный.
Так что на втором уровне блоки все-таки объединяются как во Flagship, но в каждом больше процессоров у каждого из которых больше собственной памяти.
Первый прототип с одной группой блоков планировали построить в середине 87-го, а с несколькими группами - в конце лета того же года [SPJ87a]. Не позднее 88-го первый прототип, смонтированный накруткой, был готов. Новый прототип с печатными платами ожидался в середине 88-го.
ФЯ имплементировались на этих вычислительных блоках с помощью суперкомбинаторов. Первоначальная имплементация была наивной, но не позднее 87-го года для этого использовали наработки Йонссона - G-машину [SPJ87a]. И это не последняя наработка Йонссона, которую использовали в GRIP.
До 87-го года разработчики GRIP собирались имплементировать DACTL. И использовать компиляторы в DACTL, написанные остальными Алви-проектами [SPJ87a].
Но оказалось, что DACTL не так легко имплементировать. Никто не сделал полноценной имплементации. Даже Flagship, и этот проект намного богаче GRIP. Нужно было что-то менее амбициозное. Этим неамбициозным чем-то стал FLIC (Functional Language Intermediate Code) [SPJ88b].
Над этим промежуточным языком работали еще и в Университете Уорика (University of Warwick), и FLIC - один из ранних примеров языка, который разрабатывали обсуждая в электронной почтовой рассылке. Но в университете Уорика наработали не много полезного.
Авторы пишут, что общий промежуточный язык может быть решением проблемы большого числа функциональных языков. Таким решением, которое не заставляет их унифицировать и позволяет им сохранить их сильные стороны.
Ирония в том, что средство спасения от необходимости заменять многообразие функциональных языков на один универсальный язык придумывал разработчик языков, более известный своей работой над универсальным языком для замены многообразия ФЯ.
Похоже, что авторы хотели подтолкнуть образование экосистемы вокруг FLIC. Вроде той, что тогда же пытались построить вокруг DACTL. По крайней мере для функциональных языков. В Лондоне не собирались поддерживать на GRIP ничего кроме функциональных языков, но другая группа исследователей в университете Эссекса работала над или-параллельным Прологом для этой машины.
Для них легкой жизни не обещали, но авторы пишут, что ФЯ транслировать во FLIC просто! Но никто не успел написать практичный транслятор ФЯ во FLIC за них.
И это было проблемой. Flagship мог себе позволить разработку двух компиляторов, но GRIP не может себе позволить даже одного. По крайней мере, пока не может.
Но если написание собственного компилятора требует слишком много усилий, то изменение существующего компилятора может быть вполне по силам.
Пейтон-Джонс и др. использовали язык и компилятор Lazy ML Августссона и Йонссона. Так что этот проект тоже получился международным. Но если в случае CLEAN/Dactl все закончилось международными согласованиями, после которых все делали что-то свое, то GRIP просто использовал то, что уже было сделано в Швеции. Согласования были позже, но это уже другая история.
Авторы пишут что использовали компилятор LML потому, что имели доступ к его коду. И выбор в это время был по видимому сильно ограничен. Особенно для тех кому нужен чисто функциональный язык и для ценителей работ Тернера.
Для компилятора LML написали бэкенд, транслирующий во FLIC. И легкость трансляции из промежуточного кода компилятора LML должна была сыграть важную роль в определении того, как FLIC выглядел. Функциональные языки - обычно лямбда с расширениями, пишут его авторы, так что все их можно компилировать в лямбду с несколько меньшим числом расширений.
Ну, допустим, что в это время ФЯ - уже обычно уравнения с паттерн матчингом, тут правы скорее авторы CLEAN. Но вот промежуточные языки у реально существующих и более-менее зрелых имплементаций все ещё лямбда с не особенно большим числом расширений. И FLIC - язык идейно родственный промежуточным языкам IF1 Манчестерской dataflow-машины и FP/M Лондонского компилятора HOPE+ для обычных машин. Но немного более универсальный и высокоуровневый.
Но главное то, что промежуточный язык компилятора Lazy ML - это сам Lazy ML. Но не Lazy ML второй половины 80-х, большой HOPE-фицированный язык уравнений с ПМ, а его минимальное подмножество - лямбда с расширениями.
Имплементации ПМ в компиляторах уже есть, разработчику спец-машины можно не имплементировать все возможные его версии, которых в то время было больше, чем сегодня.
Ирония в том, что это восстание против языков уравнений произошло потому, что разработчик компиляторов, который более известен имплементацией большого и сложного языка уравнений, не хотел имплементировать не такой большой и менее сложный язык уравнений.
Хотел или не хотел, правда, не так важно как то, что не мог. Альтернативное настоящее в котором роль Core в сегодняшнем GHC играет совсем не сегодняшний CLEAN было возможно, но такой исход не был особенно вероятным.
Важно, правда, отменить, что FLIC - это не Core. Да, FLIC - лямбда-исчисление с расширениями. Язык ленивый по умолчанию, но с помощью аннотаций можно писать энергичный код. Функции каррированы по умолчанию, способа объявлять некаррированные функции многих параметров нет. Но FLIC должен быть машиночитаемым. Хотя код на FLIC должен быть корректно типизирован, аннотация типов не требуется, а их проверка не производится. Компилирующий во FLIC компилятор может сохранить информацию о проверенных им типах только в аннотациях как метаданные.
Во FLIC нет АлгТД и даже одноуровневого ПМ. Есть только структуры с полями и тегом и функции для их разбора. Такой код на языке уравнений
```
f (LEAF x) = g x
f (NODE t1 t2) = h t1 t2
```
нужно транслировать в такой FLIC
```
= (f) (\x CASE 2
(UNPACK 1 g x)
(UNPACK 2 h x) x)
```
Во FLIC есть развитая система аннотаций. Авторы GRIP - энтузиасты аннотаций, которые не изменяют результата исполнения кода, но помогают сделать его быстрее. Пионером такого подхода был Уоррен, но в ФЯ он не стал распространенным до спецмашинных Алви-проектов.
Существенное преимущество ФЯ в том, пишут авторы GRIP, что параллелизм в них неявный и аннотации вообще говоря не требуются. Разработчики GRIP написали для компилятора обнаружение таких возможностей для параллелизма с помощью анализа строгости. Но они все равно имплементировали такие аннотации и пользовались ими. Аннотации заметно влияли на производительность.
Но аннотации для LML, похоже, серьезно отставали от аннотаций для FLIC. Так один из пользователей модифицированного компилятора пишет [Trin89] как он транслировал LML во FLIC и расставлял аннотации строгости и параллелизма уже только в сгенерированном FLIC-коде.
На этом закончена история о том, как Саймон Пейтон-Джонс успешно избегал работы над тем, чем он как раз известен. Пока, наконец, не перестал избегать. Но это уже другая история.
### День зависимости
Ответом правительства США на японский вызов была DARPA Strategic Computing Initiative [Stef85]. Десятилетий план, анонсированный осенью 83-го. 300 миллионов долларов ($976 миллионов 2025) на первые три года.
Это был обычный ответ. Но был ещё и ответ необычный. Необычным американским ответом на японский вызов было создание MCC (Microelectronics and Computer Technology Corporation) [Peck86]. Этот, в отличие от японского проекта машины пятого поколения и Алви - полностью частный. Да, 21 коммерческая компании вроде Motorola и AMD и, почему-то, Локхид и Боинг, готовы были не получать деньги на ответы японцам, а даже тратить свои. От государства требовалось пока что только разрешить создавать такие консорциумы, запрещённые в то время антимонопольным законодательством. Что было сделано в 84-ом.
Японская инициатива была, правда, только одной из угроз. Другой была IBM. 21 компания хотели совместно создать что-то вроде Белл Лабс AT&T или Йорктаун Хайтс IBM, про которую мы не раз писали в нулевой части. На свой ответ они планировали тратить сопоставимые средства - 80 миллионов долларов (237 миллионов в 2025) в год к концу десятилетия.
Лаборатории MCC расположились в Остине, где как раз в это время закрыли ARC, про который мы писали в прошлой части. Готовность отвечать Японии ARC не помогла, но отдельные исследователи перебежали оттуда в MCC.
Масштабы ответа впечатляют, но они не конвертируются в серьёзный вклад в нашу историю. Ответ японцам, как обычно, означал - делать больше того, что и так уже делали. И мало кто делал что-то связанное с Эдинбургской программой. А те, кто делали - делали не особенно самобытные вещи. Которые ещё и потеряли самобытность в ходе HOPE-фикации.
Посмотрим, например, на организованную MCC конференцию по редукции графов, прошедшую осенью 86-го [Fase87].
Организаторами были наш старый знакомый по предыдущей части Келлер и новый герой нашей истории Джозеф Фазель (Joseph H. Fasel) из Лос-Аламосской национальной лаборатории (Los Alamos National Laboratory).
Доклады работавшего над Ponder Фейрберна, Йонссона про Lazy ML и Худака с коллегами - про имплементации ФЯ для обычных машин и не относятся к теме этой главы.
Доклад героя нулевой главы Гогена про очередную версию его языка алгебраической спецификации, глава про который и прочие родственные Эдинбургским ФЯ направления ещё впереди.
Среди докладчиков преобладают европейцы: разработчики ALICE и Манчестерской Dataflow машины. Французской специальной машины MaRS и представители Голландского проекта.
Американские докладчики релевантные для этой главы и нашей истории в целом это уже знакомые нам разработчики FEL Келлер с коллегами, разработчики Id Арвинд с коллегами и новый герой Кибурц (Richard B. Kieburtz).
Кибурц работал в Орегоне над моделированием аппаратной G-машины [Kieb86] [Kieb87]. Кибурц, как и Пейтон-Джонс, использовал модифицированный компилятор Lazy ML Йонссона и Августссона.
Как и другие разработчики (стимуляторов) специального железа, Кибурц и др. использовали два симулятора - более детальный и медленный Microsim, пригодный только для исполнения программ в десятки команд и относительно быстрый инструментированный интерпретатор Macrosim. Macrosim написан Бориславом Агапиевым (Borislav Agapiev) на Modula-II и работал "примерно так же быстро, как интерпретатор Лиспа". Раман Теннети (Raman Tenneti) написал компилятор кодов виртуальной машины для VAX-11. Не позднее 86-го.
Как и разработчики транслятора PSML в DACTL, Кибурц экспериментировал с ленивостью и тестировал и строгие и ленивые версии. Мы уже видели ленивый "Standard" ML и вот, смотрите: энергичный "Lazy" ML. Обе имплементации, конечно, были не особенно серьёзными, даже по меркам этой истории.
Другие разработчики симуляторов машин Келлер с коллегами работали в 84-ом году над типизированной версией их языка FEL под названием TFEL [Mish85] [Mish84]. Конечная версия HOPE-фикации должна была стать, по видимому, самой буквальной HOPE-фикацией из всех, псевдокод в статье [Mish84] "похожий на TFEL" выглядел как HOPE без `<=` и с применениями функций как в FEL и FP:
```
data integer = zero + + succ[integer]
dec even: integer -> bool
--- even:zero = true
--- even:succ[zero] = false
--- even:succ[succ[x]] = even:x
```
К сожалению, для реконструкции нашего обычного примера недостаточно информации.
HOPE-фикация FEL, правда, не состоялась. В 85-ом году вместо этого заменили FEL на его версию с Лисп-синтаксисом и безо всяких групп уравнений, ПМ и АлгТД под названием RediLisp [Kelle85] [Kelle87].
Но не все разработчики специальных ФП-машин остались разработчиками симуляторов. Группа Арвинда в МТИ занялась созданием реального компьютера Monsoon, первый прототип которого должен был быть готов в конце лета 88. Но немного задержался.
Прототип, смонтированный накруткой, заработал в сентябре 88-го. В декабре он уже исполнял скомпилированные программы на Id. В том же 88-ом Motorola стала индустриальным партнёром МТИ по разработке Monsoon [LCS89].
Тем временем Нихил HOPE-фицировал Id. Эта HOPE-фикация - одна из самых поздних. Описание [Nikh88] нового Id 88.0 было готово в марте 88-го.
Теперь функциональное подмножество Id, пишет Нихил, сравнимо с современными ФЯ. В Id теперь есть параметрический полиморфизм, определяемые пользователем алгебраические типы данных и паттерн-матчинг для их конструкторов, абстрактные типы данных и лист-компрехеншоны.
В LCF/ML было три основных способа и стиля именования параметров типов. Их можно было именовать например `*` и `**`, `*a` и `*b`, `*1` и `*2`. В последующих языках с параметрическим полиморфизмом обычно ограничивались каким-то одним. В Lazy ML, SML и CAML оставили второй способ (заменив позднее `*` на `'` в некоторых из них). В Id выбрали третий способ [Nikh88].
```
type list *0 = nil | (:) *0 (list *0)
typedef map = (*0 -> *1) -> (list *0) -> (list *1)
def map f nil = nil
| map f (x:xs) = f x : map f xs
map = { fun f nil = nil
| f (x:xs) = f x : map f xs }
def map f l = { case l of
nil = nil
| (x:xs) = f x : map f xs }
def map f l = {: f x || x <- l }
{ y = 1
In
map { fun x = x + y } (1: (2: (3: nil))) }
```
Как видите, авторы Id не стали себя ограничивать и позаимствовали большинство способов разбора АлгТД. Есть и группы уравнений и `case`-выражения и лямбды, которые одновременно поддерживают и несколько веток и карринг, как в CAML и новом GHC Haskell. `:` после открывающей скобки компрехеншона тут означает, что создается список, эта нотация работает и для массивов.
Поддержку Id 88 добавил в компилятор весной 88-го Джеймс Хикс (James Hicks) [Nikh88b]. ПМ компилировался методом, описанным Вадлером с некоторыми изменениями. Первоначально язык был имплементирован не полностью, не поддерживались проверка типов для всех нововведений и объявления констант на топлевеле, можно было писать только функции с параметрами. Полная имплементация ожидалась к концу лета 88-го.
И по крайней мере проверка типов была имплементирована полностью к осени Шаилом Адитьей (Shail Aditya).
В 88-ом компилятор модифицировали чтоб генерировать код для Monsoon и решили, что неплохо было бы генерировать его и для обычных машин. Трауб работал над техниками имплементации нестрогих но не ленивых языков на обычных машинах. И в 89-ом году Лина Мурьянто (Lina Muryanto) и Питер Тан (Peter Tan) написали кодогенератор для MC68020, но пока только для подмножества языка [LCS89].
На этом очередная глава про специальные ФП-компьютеры подходит к концу. Возможно, вклад героев этой главы в историю функционального программирования пока что не выглядит впечатляющим. Но основной их вклад в дело HOPE-фикации еще впереди. Это, впрочем, уже другая история.
ПРОДОЛЖЕНИЕ СЛЕДУЕТ
Литература
==========
[Nikh88b]: R.S. Nikhil. Computation Structures Group Progress Report 1987-88. Memo-288, 1988, June
[Nikh88]: Nikhil, R.S. Id (Version 88.0) Reference Manual. Computation Structures Group Memo 284. MIT Laboratory for Computer Science, Cambridge, MA March 1988
[LCS89]: MIT Laboratory for Computer Science Progress Report 26, Jul 1988 - Jun 1989 https://apps.dtic.mil/sti/tr/pdf/ADA228606.pdf
[Kelle85]: Keller, Robert M. "Rediflow architecture prospectus." In TR UUCS-85-105. Dept of Computer Science, University of Utah USA, 1985 Aug.
[Kelle87]: Keller, R.M., Slater, J.W., Likes, K.T. (1987). Overview of Rediflow II development. 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_56
[Mish84]: Prateek Mishra and Robert M. Keller. 1984. Static inference of properties of applicative programs. In Proceedings of the 11th ACM SIGACT-SIGPLAN symposium on Principles of programming languages (POPL '84). Association for Computing Machinery, New York, NY, USA, 235244. doi:10.1145/800017.800535
[Mish85]: Prateek Mishra and Uday S. Reddy. 1985. Declaration-free type checking. In Proceedings of the 12th ACM SIGACT-SIGPLAN symposium on Principles of programming languages (POPL '85). Association for Computing Machinery, New York, NY, USA, 721. doi:10.1145/318593.318603
[Kieb86]: Richard B. Kieburtz. 1986. Performance measurement of a G-machine implementation. In Proceedings of the Workshop on Graph Reduction. Springer-Verlag, Berlin, Heidelberg, 275296.
[Kieb87]: Rchard B. Kieburtz. 1987. A RISC architecture for symbolic computation. In Proceedings of the second international conference on Architectual support for programming languages and operating systems (ASPLOS II). Association for Computing Machinery, New York, NY, USA, 146155. doi:10.1145/36206.36197
[Fase87]: Fasel, Joseph H. Graph Reduction: Proceedings of a Workshop Santa Fe, New Mexico, USA, September 29-October 1, 1986. Vol. 279. Springer Science & Business Media, 1987.
[Peck86]: Merton J. Peck, Joint R&D: The case of microelectronics and computer technology corporation, Research Policy, Volume 15, Issue 5, 1986, Pages 219-231, ISSN 0048-7333, doi:10.1016/0048-7333(86)90023-5.
[Stef85]: Mark Stefik. 1985. Strategic computing at DARPA: overview and assessment. Commun. ACM 28, 7 (July 1985), 690704. doi:10.1145/3894.3896
[SPJ88a]: Peyton Jones, Clack, Salkild and Hardie, Functional Programming on the GRIP multiprocessor. in Proceedings IEE International Specialist Seminar on Design and Application of Parallel Digital Processors, pp 116-127. 1988
[SPJ18]: People of Programming Languages. An interview project in conjunction with POPL 2018. Interview with Simon Peyton-Jones http://www.cs.cmu.edu/~popl-interviews/peytonjones.html
[SPJ87a]: Peyton Jones, Clack, Salkild and Hardie, GRIP - a high performance architecture for parallel graph reduction, LNCS 274:98-112, ISSN 0302-9743, Springer 1987.
[SPJ88b]: S. L. Peyton Jones. 1988. FLIC—a functional language intermediate code. SIGPLAN Not. 23, 8 (August 1988), 3048. doi:10.1145/47907.47910
[Trin89]: Phil Trinder, A FUNCTIONAL DATABASE, PRG82, 1989.
[Bare87]: Barendregt, H.P., M.C.J.D. van Eekelen, P.H. Hartel, L.O. Hertzberger, M.J. Plasmeijer and W.G. Vree. The Dutch Parallel Reduction Machine Project, In Future Generations Computer Systems 3, pp. 261-270. Proceedings of the International Conference on Frontiers of Computing (Amsterdam, December 1987).
[Brus87]: Brus, T., M.C.J.D. van Eekelen, M. van Leer, M.J. Plasmeijer and H.P. Barendregt. CLEAN - A Language for Functional Graph Rewriting, In Proc. of Conference on Functional Programming Languages and Computer Architecture (FPCA '87), Portland, Oregon, USA, Kahn Ed., Springer-Verlag, LNCS 274, pp. 364-384.
[Nock91]: Nöcker, E.G.J.M.H., J.E.W. Smetsers, M.C.J.D. van Eekelen and M.J. Plasmeijer. Concurrent CLEAN, In Proc. of Parallel Architectures and Languages Europe (PARLE '91), Eindhoven, the Netherlands, Aarts, Leeuwen and Rem Eds., Springer-Verlag, LNCS 505, pp. 202-219.
[Plas01]: Rinus Plasmeijer, Marko van Eekelen, CLEAN LANGUAGE REPORT version 1.3.1 September 2001
[Plas96]: Rinus Plasmeijer, Marko van Eekelen, Clean Language Report - Version 1.1 - March 1996
[Gron90]: Groningen J.H.G. van. (1990), Implementing the ABC-machine on M680x0 based architectures'. Master Thesis, University of Nijmegen, November 1990.
[Hamm91]: Hammond, Kevin. "Parallel SML: a Functional Language and its Implementation in DACTL." (1991).
[Glau2]: John Glauert: Research Background https://web.archive.org/web/20041207045351/http://www2.cmp.uea.ac.uk/~jrwg/MultiPar/resbg.html
[Glau1]: John Glauert, Personal profile. https://research-portal.uea.ac.uk/en/persons/john-glauert
[Hamm89b]: Hammond, Kevin. "Exception handling in a parallel functional language: PSML." In Fourth IEEE Region 10 International Conference TENCON, pp. 169-173. IEEE, 1989.
[Glau87]: Glauert, J. R. W., J. R. Kennaway, and M. R. Sleep. "DACTL: A computational model and compiler target language based on graph reduction." ICL Technical Journal 5, no. 3 (1987): 509-537.
[Papa89]: Papadopoulos, G.A. (1989). A fine grain parallel implementation of PARLOG. In: Díaz, J., Orejas, F. (eds) TAPSOFT '89. TAPSOFT 1989. Lecture Notes in Computer Science, vol 352. Springer, Berlin, Heidelberg. doi:10.1007/3-540-50940-2_44
[Glau88]: John R. W. Glauert, George A. Papadopoulos: A Parallel Implementation of GHC. FGCS 1988: 1051-1058
[Glau91]: Glauert, J.R.W., Kennaway, J.R., Sleep, M.R. (1991). Dactl: An experimental graph rewriting language. In: Ehrig, H., Kreowski, HJ., Rozenberg, G. (eds) Graph Grammars and Their Application to Computer Science. Graph Grammars 1990. Lecture Notes in Computer Science, vol 532. Springer, Berlin, Heidelberg. doi:10.1007/BFb0017401
[Bare86]: H P Barendregt and M van Leeuwen. 1986. Functional programming and the language TALE. Current trends in concurrency. Overviews and tutorials. Springer-Verlag, Berlin, Heidelberg, 122207.
[Darl87]: Darlington, J. (1987) Software development using functional programming languages. ICL Technical J., 5 (3): 492-508
[Glyn90]: Kewley, John M., and Kevin Glynn. "Evaluation annotations for Hope+." In Functional Programming: Proceedings of the 1989 Glasgow Workshop 2123 August 1989, Fraserburgh, Scotland, pp. 329-337. London: Springer London, 1990. doi:10.1007/978-1-4471-3166-3_22
[Robe89]: Robertson, I.B., Way, Wenlock. "Hope+ on Flagship." In Functional Programming: Proceedings of the 1989 Glasgow Workshop, 21-23 August 1989, Fraserburgh, Scotland, p. 296. Springer, 1990. doi:10.1007/978-1-4471-3166-3_20

View file

@ -14,6 +14,14 @@
---------------------------
[Обновление 2026-01-01](hopes.md#день-зависимости)
[Обновление 2025-12-13](hopes.md#негативное-пространство)
[Обновление 2025-11-16](hopes.md#граф-0)
[Обновление 2025-10-30](hopes.md#новая-надежда)
[Обновление 2025-09-06](hopes.md#big-in-japan)
[Обновление 2025-08-09](hopes.md#le-ml)