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

October update

This commit is contained in:
klapaucius 2025-11-16 22:51:40 +05:00 committed by GitHub
parent 305f859eb9
commit 5e3dfb9d59
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

149
hopes.md
View file

@ -1233,11 +1233,160 @@ filter(p,xs) <= {x | x in xs : p x}
В функциональных языках Эдинбургской исследовательской программы такие расширения не прижились. Они сыграли более заметную роль в HOPE-фикации Пролога. Но это уже другая история. В функциональных языках Эдинбургской исследовательской программы такие расширения не прижились. Они сыграли более заметную роль в 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 имплементировал подмножество, только то, что хотел, то другая Алви-машина отказалась от промежуточного языка уравнений с ПМ полностью, выбрав расширенную лямбду. Но это уже другая история.
ПРОДОЛЖЕНИЕ СЛЕДУЕТ ПРОДОЛЖЕНИЕ СЛЕДУЕТ
Литература Литература
========== ==========
[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 [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 [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 [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