diff --git a/index.md b/index.md index f0945fc..d78f7ac 100644 --- a/index.md +++ b/index.md @@ -1,6 +1,8 @@ История применения и оценки функционального программирования ======= +[Обновление 2024-01-03](#декабрьский-апдейт) + [Обновление 2023-11-30](#у-меня-нет-памяти-а-я-должен-аллоцировать) [Обновление 2023-10-31](#lambda-the-ultimate-misunderstanding) @@ -184,6 +186,26 @@ - [STAR против сил Лиспа](#star-против-сил-лиспа) - [Aut Caesar aut NIL](#aut-caesar-aut-nil) - [Per aspera ad astra](#per-aspera-ad-astra) + - [декабрьский апдейт](#декабрьский-апдейт) + - [Стандартизация — это путь обмана](#стандартизация--это-путь-обмана) + - [Анизотропия фунарга](#анизотропия-фунарга) + - [План Йенсена](#план-йенсена) + - [Конвергенция?](#конвергенция) + - [Амстердамский заговор](#амстердамский-заговор) + - [Алгол с человеческим лицом](#алгол-с-человеческим-лицом) + - [Ускорение](#ускорение) + - [Перестройка](#перестройка) + - [Сюрприз](#сюрприз) + - [Посчитать компиляции в Молверне](#посчитать-компиляции-в-молверне) + - [ALGOL 68-R](#algol-68-r) + - [Algol68C](#algol68c) + - [Эдикт Фонтенбло](#эдикт-фонтенбло) + - [ALGOL 68 Revised](#algol-68-revised) + - [Расширения](#расширения) + - [ALGOL 77](#algol-77) + - [Ограниченное могущество кучи](#ограниченное-могущество-кучи) + - [Алголы 70-х](#алголы-70-х) + - [Антиалголы 80-х](#антиалголы-80-х) - [Литература](#литература) @@ -4992,8 +5014,8 @@ Per aspera ad astra Еще одно непопулярное у лисперов МТИ мнение Фейтмана: написание (переписывание) имплементации Лиспа на языке C лучше, чем подход NIL. Язык C, на тот момент новый и мало кем используемый, уже продемонстрировал свои возможности для системного программирования и разработки языков. Поэтому разработчики нового Лиспа для VAX решили, что никакие модификации его для их целей не потребуются. Для сравнения, Хейвенс (W. Havens) из Университета Висконсина писал VAX Interlisp на Паскале и Паскаль пришлось модифицировать, менять типизацию указателей. Основным преимуществом C Фейтман и его единомышленники считали один портабельный компилятор, определяющий язык [Fate81]. Никаких проблем с несовпадением имплементаций, комитетами по стандартизации и так далее! -Университетский PDP-11/70 c UNIX UNIX ver 6 [Fate81] конечно же имеет слишком мало памяти, но разрабатывать какой-никакой Лисп можно уже на ней. И студенты Фейтмана приступили к разработке. Начали с Лиспа для PDP-11, написанного в Гарварде. Расширили для совместимости с MacLisp. Основными конрибьютерами в первоначальную систему были Майк Карри (Mike Curry), Джон Бридлов (John Breedlove) и Джеф Левински (Jeff Levinsky). Билл Роуэн (Bill Rowan) написал сборщик мусора и поддержку массивов. Кип Хикман (Kipp Hickman) и Чарльз Костер (Charles Koester) - поддержку плоских структур. Основными разработчиками имплементации далее были Джон Фодераро (John Foderaro), работавший над компилятором, Кейт Скловер (Keith Sklower), занимавшийся длинной арифметикой и оптимизациями и Кевин Лэйер (Kevin Layer), который позднее будет писать MC68K бэкенд [Fode83] [Franz]. -Заметная часть имплементации написана на Лиспе. Рантайм почти полностью написали на C, но не обошлось без пары страниц ассемблера. Компромисс между портабельностью и производительностью. +Университетский PDP-11/70 c UNIX UNIX ver 6 [Fate81] конечно же имеет слишком мало памяти, но разрабатывать какой-никакой Лисп можно уже на ней. И студенты Фейтмана приступили к разработке. Начали с Лиспа для PDP-11, написанного в Гарварде. Расширили для совместимости с MacLisp. Основными контрибьюторами в первоначальную систему были Майк Карри (Mike Curry), Джон Бридлов (John Breedlove) и Джеф Левински (Jeff Levinsky). Билл Роуэн (Bill Rowan) написал сборщик мусора и поддержку массивов. Кип Хикман (Kipp Hickman) и Чарльз Костер (Charles Koester) - поддержку плоских структур. Основными разработчиками имплементации далее были Джон Фодераро (John Foderaro), работавший над компилятором, Кейт Скловер (Keith Sklower), занимавшийся длинной арифметикой и оптимизациями и Кевин Лэйер (Kevin Layer), который позднее будет писать MC68K бэкенд [Fode83] [Franz]. +Заметная часть имплементации написана на Лиспе. Рантайм почти полностью написали на C, но не обошлось без пары страниц ассемблера. Компромисс между портируемостью и производительностью. Основное предназначение имплементации - поддержка MACSYMA. Так что имплементаторы не особо стараются имплементировать фичи, которые для MACSYMA не нужны. Также не особенно работают над оптимизатором считая, что это можно компенсировать с помощью FFI. Писать часть кода на Фортране, Си и т.д. Вызывать фортран код из PDP-10 Maclisp невозможно (Multics Maclisp есть FFI), на Лисп-машинах в это время нет компилятора Фортрана, готовых библиотек для HPC и прочих полезных вещей. На популярных платформах все это, конечно, есть. Библиотеки для FFT работает в 100 раз быстрее, чем написанная на Лиспе, так зачем тратить силы на оптимизации [Fate81]? Первая версия этого Лиспа, названного Franz Lisp заработала на PDP-11 весной 78-го [Fate81]. Конечно, PDP-11 недостаточно чтоб запускать MACSYMA. Не проблема, Фейтман достанет VAX-11. Пока студенты Фейтмана занимались имплементацией Лиспа, он и еще 13 преподавателей составили заявку на грант NSF, который позволил, с добавлением из фондов департамента, приобрести VAX. Машину привезли осенью 1978. Сначала на ней работала ОС DEC VMS, но департамент хотел использовать UNIX, к которому привыкли на PDP-11 [McKus]. Конечно, для использования наработок студентов Фейтмана тоже нужен был UNIX. И для того, чтоб запускать большие программы вроде MACSYMA VMS не подходила. В VMS каждому процессу дается память одинаковая для всех процессов - резидентный набор. Страницы, которые не являются частью никаких резидентных наборов используются как дисковый кэш. Даже если работает один процесс - из его резидентного набора все равно отбирается память если много неработающих процессов. Разумеется это неудобно, процессы сильно отличаются по потреблению памяти. Также у процессов меняется поведение по запрашиванию памяти, Лисп-система во время сборки мусора сильно отличается таким поведением от времени работы мутатора. Это будет частично исправлено в VMS 2.1, но пока что этой версии системы не было [Baba81]. Не проблема, Фейтман достанет 32бит UNIX. @@ -5005,12 +5027,678 @@ Per aspera ad astra Фейтман связался с профессором Доменико Феррари (Domenico Ferrari), преподавателем факультета систем в Беркли чтоб привлечь его группу к написанию системы виртуальной памяти для UNIX. Основной целью проекта называется предоставление большое адресное пространство для пользовательских процессов, а именно для лисп-программ таких как MACSYMA и для программ обработки изображений [Baba79]. Этим занялся его студент Озалп Бабаоглу (Ozalp Babaoglu). После имплементации прототипа Бабаоглу стал работать совместно с Биллом Джоем, который тогда поддерживал берклиевский дистрибутив UNIX. Билл Джой помог с интеграцией менеджера памяти в 32/V и отладкой [McKus]. Модификация Version 7 UNIX в систему со страничной памятью началась поздней весной 79 и первая версия была готова для использования в сентябре 79 [Baba81]. Лисп является не только одним из основных бенчмарков для системы. Поддержка имплементации Лиспа закладывается в сам менеджер памяти. Добавлен системный вызов, чтоб перед началом сборки мусора можно было запросить более подходящую политику пейджинга [Baba81]. Система по умолчанию использует политику "дольше всего не использовалась". Но во время сборки Franz Lisp посещает так много страниц, что такая политика не годится. Поэтому системе посылается сигнал и она меняет ее на FIFO с удвоенной скоростью замены страниц. После окончания сборки системе посылается сигнал и она помещает все страницы лисповой программы в список свободных и возвращается к политике по умолчанию [Fode81]. В декабре 1979 готов 3 BSD - дистрибутив UNIX с ядром с поддержкой страничной памяти и портированными программами, разработанными для 2 BSD. Например компилятором Паскаля, который начинал Кен Томпсон во время визита в Беркли [McKus]. Распространение системы началось в январе 1980, к весне распространено больше 50 копий. Популярна у тех, кто запускает большие программы, а не использует как обычную систему разделения времени [Baba81]. Сопоставимая поддержка больших программ появилась в Bell Labs UNIX только в System V Release 2 Version 4 в 84 году [Quar86]. Фейтман доволен результатами, Macsyma на VAX работает с 80-го года [Fode81]. В 81-ом "Vaxima" работает на VAX-11/780 c 2.5Мб физической памяти. Сегмент только для чтения, разделяемый между всеми пользователями 1.8Мб, объекты в динамической памяти 1.4Мб - 3.3Мб. В 81-ом году в Franz Lisp 15,000 строк на Си, немного ассемблера для аллокатора, сборщика мусора, длинных целых. Из-за того что в Си недостаточно инструментов для управления регистрами, пришлось передавать/возвращать на стеке во многих случаях, когда можно бы было в регистрах. Также лисперы недовольны медленным сишным соглашением о вызове. Но были довольны тем, как быстро удалось написать систему не сильно медленнее написанной на ассемблере. Со сборкой мусора все еще проблемы, даже поддержки от ОС недостаточно [Fode81], но к этому мы еще вернемся. -Лисперы МТИ не любят Franz LISP, хоть и признают, что это де факто стандартный Лисп на VAX. Пишут, что он написан "быстро и грязно" [Stee82] и что Franz Lisp не интересен потому, что "ничего не предлагает кроме портабельности" [Stee96]. +Лисперы МТИ не любят Franz LISP, хоть и признают, что это де факто стандартный Лисп на VAX. Пишут, что он написан "быстро и грязно" [Stee82] и что Franz Lisp не интересен потому, что "ничего не предлагает кроме портируемости" [Stee96]. 3BSD произвел хорошее впечатление на (D)ARPA и они выбрали берклиевский UNIX для использования как единую ОС для своих проектов, а значит для поддержки и финансирования [McKus]. Для начала, контракт на 18 месяцев с апреля 1980 на добавление фич, нужных для (D)ARPA. Билл Джой - руководитель проекта. В октябре 1980 выходит 4 BSD - основная система, на которой будут разрабатывать компиляторы ФЯ в 80-е годы. Дистрибутив включает Pascal и Franz Lisp, через год работает на ~500 машинах [McKus]. 3BSD и 4BSD де факто стандартный выбор UNIX на VAX, использовался даже в самой Bell AT&T. И многие, получив от них лицензию, даже не утруждали себя получением ленты с 32V [Quar86]. В (D)ARPA довольны дистрибутивом, заключают новый двухгодичный контракт, увеличивают финансирование в пять раз. И увеличив финансирование тут, в кое-каком другом месте они его существенно уменьшили, но это уже другая история. Franz LISP входит в дистрибутив 3BSD и 4BSD. Статья про то, что страничная память имплементировалась для того, чтоб запускать Macsyma поставлялась с ним вместе с прочей документацией. Но чем больше лет проходило с тех пор тем меньше упоминаний о роли Macsyma и Лиспа в истории BSD и тем более расплывчатыми становятся оставшиеся. Лисперы исчезают из истории, как товарищи с фотографий со Сталиным. На момент написания этого текста, например, статья про BSD на Википедии почти полностью свободна от какого-то упоминания Лиспа, кроме скриншота на котором Franz LISP по какой-то причине. По всей видимости, ранние историки BSD смело упоминали Лисп потому, что это было что-то важное и передовое, но чем дальше, тем страннее очередному автору очередного исторического очерка было видеть и тем сложнее оставить упоминания Лиспа. Который превратился в какую-то затянувшуюся шутку. И лисперов, которые стали известны как те, кто утверждают, что все изобрели и все могут сделать, но ничего не делают. Да, как мы уже видели и еще увидим, лисперы часто присваивают себе достижения, которые от невнятной идеи лиспера до практически работающего воплощения доводились другими. Но этого достижения у них не отнять. Они сыграли важную роль в том, что UNIX стал ОС для рабочих станций, а не какой-нибудь нишевой системой для управления АТС. Но почему Лисп превратился в эту самую затянувшуюся шутку, с которой UNIX культуре некомфортно иметь что-то общее? Пока что лисперам, вроде бы, удалось спастись с тонущего PDP-10 и спасти главное из того ценного, что было сделано (но не компилятор с поддержкой ФП-фич). Но война за наследство ИИ-лаборатории только началась. И если МТИ проиграл первую битву, это еще не значит, что он не может сделать так, чтоб все проиграли войну. +декабрьский апдейт +------------------ + +Итак, мы выяснили, что имплементаторы Лиспов не были особенно заинтересованы в поддержке функционального программирования. И стели делать что-то для этого только в конце 70-х. И даже когда стали делать, то не сделали ничего подходящего для того, чтоб взять и использовать как бэкенд для компиляции ФЯ. Причины для этого были разными, но результат один: в 70-е имплементаторы эдинбургских ФЯ могли использовать Stanford LISP на PDP-10, а в 80-е они вступили имея возможность использовать Franz LISP на VAX-11. Ни та ни другая имплементация, фактически, не имела для поддержки ФП ничего кроме сборщика мусора. Тут возникает вопрос: если имплементации Лиспа дают только сборщик мусора, то почему бы не рассмотреть использование каких-то других языков со сборщиками мусора? Зачем платить производительностью за поддержку в имплементации Лиспа ненужных ФЯ "динамических" фич? Сегодня относительно успешно имплементируют ФЯ трансляцией в мейнстримные языки со сборщиком мусора. Но десятилетия наработок в области эффективной имплементации скриптов все еще не дают ФЯ, транслируемому в JavaScript, догнать ФЯ, транслируемый в JVM. Но существовало ли в 70-е годы что-то соответствующее Java в этом сравнении? Мейнстримные языки со сборкой мусора могут быть существенно более современным явлением. Давайте выясним. + +Стандартизация — это путь обмана +----------------------------------- + +> Описание ALGOL 60 стало достойной демонстрацией языка. Хорошо организованное, маняще неполное, слегка двусмысленное, трудное для чтения, краткое, оно было идеальным холстом для языка, который обладал теми же свойствами. Как и Библия, оно было задумано не только для чтения, но и для толкования. +> Алан Перлис, Американская сторона разработки ALGOL [Perl78] + +> После Парижского заседания на Петера Наура снизошел Святой Дух. +> Фриц Бауэр, Европейская сторона разработки ALGOL [Naur78] + +Вернемся практически в самое начало нашей истории, когда работы над имплементацией CPL в Лондоне и том самом Кембридже завершились крахом. Выяснилось, что ожиданиям нового высокоуровневого языка в Кембридже и Королевском Институте Радиолокации не суждено сбыться. После этого мы отправились в другой Кембридж. Там сделали работающую, урезанную версию CPL практически полностью свободную от всех претензий на высокоуровневость. И потому не интересную для истории ФЯ. Понятно, что практически вся наша история ФЯ до сих пор была посвящена тому, что произошло от другого языка сделанного там, свободного от практически всех претензий на практичность. Что же происходило в том самом Кембридже и Институте Радиолокации? Похоже, что ни один из вариантов продолжения CPL от другого Кембриджа их полностью не устроил. Так что они поучаствовали в эксперименте, который определил, как много мечт о CPL могут быть воплощены в относительно практичном языке. Попробовали двигаться к компилятору ФЯ не как в Эдинбургской программе от ФЯ-скрипта к языку общего назначения, а от языка общего назначения к добавлению в него ФП фич. Как много ФП можно себе позволить с компилятором, который работает на обычной машине, а не на специально сконструированной без особых оглядок на дороговизну как в МТИ? +После гибели CPL, в Кембридже и Радиолокационном институте обратили внимание на другой язык, произошедший от ALGOL. Как и CPL. И общее происхождение только одно из многих общих свойств. Авторы CPL не без оснований заявляют [Camp85] о влиянии CPL на этот язык, как об одном из основных результатов их трудов. Язык, впрочем, начал разрабатываться достаточно давно, чтоб были основания предполагать его влияние на CPL. + +### Анизотропия фунарга + +Насколько ALGOL 60 хорош как основа для получения ФЯ? Да, мы уже рассказывали об одной неудачной попытке это сделать и скоро расскажем об еще одной. Но причина этих неудач не в ALGOL 60. Посмотрим на пример из учебника по ALGOL 60 [Ruti67]. В нем объявляется такая вот ФВП: + +```pascal +REAL PROCEDURE sum (p, q, term); + VALUE p, q; + INTEGER p, q; REAL PROCEDURE term; + BEGIN + REAL s; + INTEGER k; + s := 0; + FOR k := p STEP 1 UNTIL q DO s := s + term(k); + sum := s + END sum +``` + +А так она использована с объявлением локальной процедуры, которая замыкается на какие-то значения a и b выше по области видимости: + +```pascal +REAL PROCEDURE scalp(p); +INTEGER p; + scalp := a[p] x b[p]; +z := sum(1, n, scalp); +``` + +Что напоминает высокоуровневые обоекембриджские языки, но отличается экстремально тяжелым синтаксисом и тем, что все эти замыкания и передачи работают в одну сторону - вниз. Не только для функций, вернуть массив тоже не получится. Это, конечно не ФЯ, но очень амбициозный проект для 50-х годов. Память управляется автоматически и без сборщика мусора. Ну, пока кто-нибудь не сломает всю эту автоматику CPS-трансформацией, как Моррис. Имплементировать ALGOL 60 было не так легко, и обычно он не был имплементирован полностью [Naur78]. Но интересные для нашей истории фичи были имплементированы и довольно рано, в 1960-ом году [Dijk62]! ALGOL 60 - это не просто набор пожеланий, как CPL. И значит было известно из опыта, что можно и не отступать от набора пожеланий BCPL так далеко, как отступили в BCPL. Но можно ли было отступать еще меньше? +Конечно, есть и другая, существенно менее интересная чем "работающий только вниз ISWIM с тяжелым синтаксисом", перспектива на ALGOL 60. Что это - Паскаль. Но действительно ли это Паскаль? +С одной стороны, это даже меньше, чем Паскаль. Описанный в репорте ALGOL 60 - не то, что мы бы сегодня ожидали от языка программирования. Это скорее что-то вроде языка формул калькулятора. Средств для описания структур данных в нем нет. Так что авторам имплементаций Алгола приходилось разрабатывать свои средства, и делать ALGOL 60 с расширениями. Как AED-0 [Ross61], на котором Ричардс написал первый компилятор BCPL для бутстрапа [Rich2000], как имплементация ALGOL 60 от Королевского Института Радиолокации [Wood66], как SIMULA. + +### План Йенсена + +С другой стороны - это больше, чем Паскаль. И ALGOL 60 не так просто имплементировать. В 1964 Дональд Кнут опубликовал [Knut64] код для проверки того, имплементирует ли компилятор ALGOL 60 основные фичи языка. И насколько эффективно. + +```pascal +BEGIN REAL PROCEDURE A(k, x1, x2, x3, x4, x5); + VALUE k; INTEGER k; + BEGIN REAL PROCEDURE B; + BEGIN k := k - 1; + B := A := A(k, B, x1, x2, x3, x4) + END; + IF k <= 0 THEN A := x4 + x5 ELSE B + END; + outreal(A(10, 1, -1, -1, 1, 0)) +END; +``` + +Да, как мы уже выяснили, работающая лексическая видимость это не то, на поддержку чего можно всегда рассчитывать в 60-е и 70-е годы. Код выглядит немного странно, но это всего лишь Паскаль с другим синтаксисом аннотации типов. Нет! Тест Кнута проверяет не только лексическую видимость. На Паскале этот код будет выглядеть так [Rosetta1]: + +```pascal +program manorboy(output); + +function zero: integer; begin zero := 0 end; +function one: integer; begin one := 1 end; +function negone: integer; begin negone := -1 end; + +function A( + k: integer; + function x1: integer; + function x2: integer; + function x3: integer; + function x4: integer; + function x5: integer +): integer; + + function B: integer; + begin k := k - 1; + B := A(k, B, x1, x2, x3, x4) + end; + +begin if k <= 0 then A := x4 + x5 else A := B +end; + +begin writeln(A(10, one, negone, negone, one, zero)) +end. +``` + +Да, в ALGOL 60 способ передачи аргументов по умолчанию - вызов по имени. Единственный аргумент из примера, который передается по значению декларирован как таковой: `VALUE k`. Это определенно не самое распространенное решение. Но интереснее то, как алголисты его использовали для имитации конструкции несколько более распространенной. +В ALGOL 60 нет лямбд. На первый взгляд это кажется нормальным. Их и в CPL/ISWIM обычно не планировали. В этой истории мы уже повидали несколько функциональных языков без лямбд, и в ALGOL 60 есть вложенные функции и функциональные параметры для передачи функций вниз. Но алголистам этого мало и они имитируют лямбды с помощью вызова по имени. Обычно программисты поступают наоборот и имитируют вызов по имени с помощью лямбд. +Чтоб паскалеобразность не мешала пониманию совсем не паскалеобразной семантики, рассмотрим пример на языке, в котором вызов по имени привычнее. Допустим нам нужно воспроизвести такую вот ФВП: + +```haskell +bar f = do + f 1 + f 2 +``` + +которая используется так: + +```haskell +> bar (\x -> print x) +1 +2 +``` + +Для этого алголисты использовали технику, называющуюся "устройство Йенсена" (Jensen's device), в честь одного из имплементаторов Алгола Йорна Йенсена (Jørn Jensen). +Заводим для каждой связанной переменной параметр функции и пишем в него нужные значения перед каждым "вызовом" "функции": + +```haskell +foo a f = do + writeIORef a 1 + f + writeIORef a 2 + f +``` + +Получаем тот же результат: + +```haskell +> x <- newIORef 0 +> foo x (print =<< readIORef x) +1 +2 +``` + +Но какой ценой? Отказ от имплементации лямбд ничего не дает. Разумеется, имплементировать передачу в функции функций и санков для вызова по имени одинаково трудно. Сложная для имплементации часть лямбды - свободные переменные. И в ALGOL 60 есть "лямбды" без конструкции связывания переменных. Все переменные в них свободные. Это не только не упрощает имплементации, но и в сочетании с другими фичами не запрещает использование "лямбд" в качестве лямбд. Но, может быть, так и было задумано? Да, обычно в ISWIM-ах не было лямбд, но в реально имплементированных ISWIM-ах лямбды как раз обычно были. И Йенсен очень хорошо позиционирован для того, чтоб продвинуть лямбду в Алгол, если он хочет. Он работает над компилятором вместе с основным автором Алгола и редактора репорта Петером Науром (Peter Naur). Но нет, вместо обычной лямбды - странный фокус. Алголисты вообще про лямбду-то знают? + +### Конвергенция? + +Корректная статическая видимость Алгола в сочетании с этим странным фокусом, по всей видимости, и породили мнение о том, что авторы Алгола не знали о лямбда-исчислении, но (недо)открыли его независимо. Статическая видимость необходима для того, чтоб откладывание вычисления параметров правильно работало. +Следовательно, предполагает Бердж [Burg75], а вслед за ним и Тернер [Turn12], имеет место конвергенция подходов "как надо делать по теории" и "как надо делать чтоб работало". Что должно подтверждать некоторую фундаментальную правильность подходов "по теории". Во что, конечно, хочется верить. +Как мы уже знаем, лисперы действительно столкнулись со сложностями, когда имплементировали видимость не как в ЛИ. С другой стороны, два десятка лет после открытия этих проблем лисперы чаще решали, что сойдет и так. +Но насколько правдоподобно то, что авторы Алгола совсем не знали ЛИ? +МакКарти уже понял что такое лямбда и как она должна работать [McCa60b] к тому времени как ALGOL 60 репорт был готов. Но в первые годы разработки ALGOL 60 МакКарти видимо знал про лямбды гораздо меньше, если судить по коду в первом отчете [McCa58] Лаборатории ИИ МТИ, в котором `map` применяется так, как будто написан с помощью техники Йенсена: + +```haskell +maplist (cdr(J),L,(L = K -> diff(L), L != K -> copy (L))) +``` + +Но Рутисхаузер утверждает, что техника Йенсена изобретена на два года позднее, в 1960 [Ruti67]. Возможно, МакКарти мог поучаствовать в обсуждениях только после того, как основные решения были приняты. И к тем участникам обсуждений, кто должен был знать ЛИ в это время можно добавить еще и Ландина. Хотя тогда он еще не состоял в комитете. +Есть серьезные основания сомневаться в идеях Берджа о том, что ALGOL 60 не проектировали со знанием ЛИ. И для странностей Алголов есть другое объяснение. Комитетчики совсем не ладили друг с другом и придерживались очень разных взглядов на то, что нужно добавлять, а что нет. Многие странности языка и неоднозначности его описания были определены тем, как проходили линии фронта на момент перемирия 1960-го года. + +### Амстердамский заговор + +Бауэр (Friedrich Ludwig Bauer) пишет [Naur78], что Самельсон (Klaus Samelson) и "другие" пытались добавить в Алгол прямую и логичную как в лямбда-исчислении передачу функций через аргументы. Неудачно. Алан Перлис (Alan Jay Perlis), по словам Бауэра, заявлял, что понимает, что вызов по имени - скрытое добавление в язык фич для передачи функций в функции, которые не удалось добавить явно. Бауэр жалуется, что Наур просто не оставил адекватных заметок об этих попытках "функционализации". Наур пишет, что в вопросах передачи функций через параметры не было не только общего согласия, но и общего понимания. Что полностью понимал о чем говорится в предложениях по передаче функций в функции только Перлис. Похоже, что не только он, но вполне возможно, что понимали не все. +Было бы чрезмерным упрощением разделять авторов ALGOL на про-ФП и анти-ФП фракции. Что "про", а что "анти-ФП" в те далекие времена было не совсем очевидно. И из нашего времени многие позиции выглядят противоречиво. По крайней мере, на первый взгляд. Например, те, кто были за лямбды - были против рекурсии. +Попытка американской части комитета (видимо МакКарти) добавить рекурсию с аннотацией `recursive` оказалась неудачной, предложение было отклонено с небольшим перевесом. Но рекурсию удалось добавить Ван Вейнгаардену с Дейкстрой в результате "Амстердамского заговора". В репорте обнаруживались или даже закладывались некоторые умолчания и утверждения, которые по отдельности не привлекали внимания тех, кого они не должны были привлекать, пока все вместе они не сложились в поддержку рекурсии. Когда противник уже измотан и потерял волю к борьбе с этой фичей. Наур вспоминает, что последнюю, решающую деталь, сконструированную так, чтоб Бауэр не обратил на неё внимание, предложил добавить Ван Вейнгаарден только при поддержке Дейкстры [Naur78], но Дейкстра приписывает исполнение хитрого плана себе [Dijk2001]. +Может быть, такая борьба комитетчиков даже полезна. В конце концов, авторы CPL так и не закончили его описание. Ведь для них оно было только рутинным документированием того, что прочие авторы согласны со Стрейчи. Другое дело - описание ALGOL. Каждая строчка в нем - памятник чьей-то победы. Свидетельство того, как кто-то был переигран и уничтожен. +С другой стороны, успехи борьбы за то, чтоб ALGOL 60 был функциональным языком, были очень ограниченными. Хак Йенсена - это, скорее всего не то, что вы хотели бы получить вместо лямбды. Да и с рекурсией все вышло не особенно хорошо. Рекурсия имплементирована не самым практичным для ФП образом и занимает стек в любом случае. Но в это время еще не знали как имплементировать рекурсию практично. ALGOL 60 репорт написан за четыре года до того самого выступления Вейнгаардена [Wijn66]. Возможно, поэтому у рекурсии и были противники среди тех, кто продвигал ФЯ фичи. Но не обязательно. Во время обсуждения доклада Самельсон отнесся без особого энтузиазма к идеям Вейнгаардена [Wijn66]. +Косвенным подтверждением истории про Самельсона, который хотел добавить в Алгол лямбды еще в 1960 можно считать то, как он изменил Алгол, получив такую возможность. + +Алгол с человеческим лицом +-------------------------- + +> Говорят, что один ирландец на вопрос, как добраться до какого-то отдаленного места, ответил, что если вы действительно хотели бы попасть в это место, то не стоило бы начинать путь отсюда. <..> Начинать с ALGOL 60 было ошибкой. +> Чарльз Линдси [Lind93] + +На выпуске репорта об ALGOL 60 разработка Алгола не закончилась, и вскоре линии фронтов стали двигаться вновь. На этот раз основной конфликт определить намного легче. Не все авторы хотели, чтоб новый Алгол был таким же новаторским и амбициозным каким был в свое время старый. Хотели, чтоб был просто таким же. ALGOL 60 был недоделан, не было средств объявлять типы данных вроде рекордов. Рекорды нужно добавить. В ALGOL 60 были недостатки вроде вызова по имени - это нужно убрать. Минимальные изменения ALGOL 60 описывались в репорте-кандидате Хоара (рекорды) и Никлауса Вирта (Niklaus Wirth) (все остальное) [Wirt66]. +Понятно, что этот подход, в основном, был направлен против функционализации Алгола. Но и члены этой партии продвигали некоторые изменения, которые делали Алгол более похожим на ФЯ. +В прошлый раз победил тот, кто первым написал хорошую заготовку для репорта. Так что победа партии умеренной модификации Алгола была весьма вероятна. В октябре 1965 в Сен-Пьер-де-Шартрёз минимальный инкремент Алгола был представлен как два документа от Хоара и Вирта. И комитет решил, что это примерно то, что нужно. Победное шествие, правда, натолкнулось на неожиданное препятствие. +Наш старый знакомый, непонятный изобретатель CPS-преобразования Адриан Ван Вейнгаарден, тоже подготовил заготовку репорта. Репорт вовсе не был готов, но комитету понравилось, как Ван Вейнгаарден описывает язык. Так что комитет решил: нужен язык Хоара и Вирта, описанный Ван Вейнгаарденом. +Из собственных взглядов на то, каким должен быть новый Алгол у Ван Вейнгаардена пока что были только идея "ортогональности" и то, что новый Алгол, называемый сначала Algol X, должен быть языком выражений. Последнее делает язык более похожим на ФЯ, у первого будут неоднозначные последствия для "функционализации". + +### Ускорение + +История добавления типов данных в CPL плохо задокументирована. Добавление типов данных в Алгол - совсем другое дело. Почему мы вдруг вспомнили про историю типов данных в CPL? Потому, что это скорее всего одна и та же история. +Джон МакКарти был автором первого предложения [McCa64] о том, как могут выглядеть типы данных для Алгола. Для этого он, еще в 1964, приспособил уже знакомую нам его идею [McCa61] о суммах и произведениях. Стековая дисциплина Алгола не особенно способствовала развесистым деревьям в памяти, так что в его примерах только плоские структуры вроде точек. Декларирующий типы программист должен придумать и описать имена конструкторов, селекторов и даже функций, возвращающих число-тег суммы: + +``` +CARTESIAN typename, ((field1, type1),...(fieldn, typen)), constructorname +UNION typename, ((cons1, sel1, type1),...(consn, seln, typen)), gettag +``` + +Да, никакой конструкции для деконструкции МакКарти не предложил. Нужно сравнивать числа-теги: + +``` +typename x := cons1(y) +type1 r := IF gettag(x) = 1 THEN sel1(x) ELSE y +``` + +Эту идею летом 65-го развил Хоар. Не только добавив побольше ключевых слов. + +``` +RECORD CLASS cons(head, tail); + BEGIN INTEGER head; + REFERENCE tail(cons) + END; +``` + +Хоар вводит ссылки. Рекорды Хоара совсем не плоские. Наоборот, это средства создания деревьев в куче. Тип рекорда и его конструктор имеют одно и то же имя: + +``` +BEGIN REFERENCE list (cons); + list := cons(1,NULL); + tail(list) := cons(0,NULL); +END +``` + +Удивительно, но синтаксис для юнионов не такой тяжелый: + +``` +UNION list(cons, nil); +``` + +Юнион тут - "неопределенная ссылка". +Легкость декларации компенсируется синтаксисом для деконструкции юниона с невероятными составными ключевыми словами: + +``` +IF x IS A cons THEN ... head(x) ... +OR IF IT IS A nil THEN ... +``` + +Хоар упустил возможность изобрести нотацию Бурсталла, при том что сам уже предлагал [Hoar64] для Алгола конструкцию такого вида: + +``` +CASE x OF ( + resIfx1 ELSE + resIfx2 ELSE + resIFx3 +) +``` + +Но для чисел, а не тегов юнионов. Идея настолько не предусматривает ничего кроме чисел, что даже самые примитивные "паттерны" в виде констант пока что отсутствуют, есть только порядок результатов. +Тут типы данных для Алгола сильнее всего сближаются с обсуждаемыми позднее [Stra67] типами данных для CPL. Этот обмен идеями мог осуществить Ландин, который принимал участие в проектировании обоих языков. Никаких признаний или даже претензий на заимствование в ту или иную сторону мы, правда, не видели. Да, у пишущих истории CPL есть мнение [Camp85], что новый Алгол происходит от CPL, хотя и без конкретных упоминаний заимствования типов данных. Историки Алгола CPL не вспоминают. +Хоар упоминает CPL в этом предложении фичи для Алгола, но не как язык, из которого он позаимствовал типы данных. Хоар пишет о ссылках как концепции из CPL, которую он предлагает не заимствовать. Уже в 65-ом году Хоар противник первоклассных ссылок и продвигает ссылочные типы. Продвижение которых и через десять лет после этого будет слишком смелым и опережающим свое время. Но в 70-е Хоар будет продвигать уже не МакКартиевские раздельные суммы и произведения, а суммы произведений. Это будет сближение с работами Бурсталла, а пока что пройдено сближение с CPL, дальше расхождения в типах данных с новым Алголом будут нарастать. +Разумеется, комитет Алгола 68, не принял это предложение Хоара в неизменном виде. Вместо ссылочных типов новый Алгол получил плоские типы, которые можно размещать и на стеке с явными первоклассными ссылками. Которыми можно имплементировать список с некоторым выбором представления так: + +``` +MODE LIST = UNION(NULL,CONS); +MODE NULL = VOID; +MODE CONS = REF STRUCT(INT h, LIST t); + + ┌───┬───┐ ┌───┬───┬───┐ + │001│ ├──►│ 1 │000│ │ + └───┴───┘ └───┴───┴───┘ + +``` +или так: + +``` +MODE LIST = REF UNION(NULL,CONS); +MODE NULL = VOID; +MODE CONS = STRUCT(INT h, LIST t); + + ┌───┐ ┌───┬───┬───┐ ┌───┬───┬───┐ + │ ├──►│001│ 1 │ ├──►│000│ │ │ + └───┘ └───┴───┴───┘ └───┴───┴───┘ + +``` + +Есть и еще одно важное отличие этих типов данных попавших в Алгол от того, что хотел продвинуть Хоар. Эти `MODE` декларации аналог `type` в Хаскеле, а Хоаровский `RECORD CLASS` - аналог `data`. `MODE` можно подставить в другой `MODE` и все продолжит работать, типизация структурная и ближе к первоначальной идее МакКарти: + +``` +MODE LIST = REF UNION(VOID,STRUCT(INT h, LIST t)); +MODE NULL = VOID; +MODE CONS = STRUCT(INT h, LIST t); +``` + +Хоар такого не хотел. +Вы, вероятно, не захотите использовать юнионы для объявления списков таким образом не только из-за неэффективного представления МакКартиевских данных в памяти (о котором мы уже писали в главах про LCF/ML и непосредственную имплементацию) но и потому, что новый Алгол пока что не имеет удобной конструкции для их разбора, пусть даже и с тяжелым синтаксисом как IF Хоара. Вместо удобной есть вот такая: + +``` +CASE nullvar, consvar ::= l IN + nullvar, + t of consvar +ESAC +``` + +Что тут происходит? Что-то вроде такого: + +```haskell +data Cons = Cons{ h :: Int, t :: List } +data List = Null () | NotNull Cons +case l of + Null null -> do + nullVar <- newIORef null + return nullVar + NotNull cons -> do + consvar <- newIORef cons + return . t =<< readIORef consvar +``` + +Да, вместо паттерна тут тоже только порядок. Что, возможно, даже хуже, чем вы ожидаете. Потому, что еще один автор нового Алгола, более известный другими своими работами, Ёнэда (Yoneda Nobuo) настоял, чтоб декларации `UNION(NULL,CONS)` и `UNION(CONS,NULL)` объявляли один и тот же тип. Порядок типов в юнионе не имеет значения. Одно хорошо - неправильный порядок вариантов в этом `CASE` не пройдет проверки типов. Так что пока лучше использовать рекорды и `null`, как собирались и в CPL. Не очень-то похоже на ФЯ. Юнионы даже хотели заменить на ссылку на любой юнион, но Хоар их отстоял. +Почему мечты Хоара потерпели крах? Это результат других планировавшихся изменений Алгола, идеи Ван Вейнгаардена об "ортогональности" и практических соображений. Если убрать из Алгола вызов по имени - нужно найти какую-то замену. Нельзя просто постоянно копировать структуры, передающиеся по значению. Нужно добавить передачу аргументов по ссылке. По замыслу Хоара и Вирта ссылочные типы - рекорды и юнионы - и способ передачи параметров - это отдельные фичи, никак не связанные. Но "ортогональность" Ван Вейнгаардена, что-то вроде минимальности в сочетании с первоклассностью, требует все это делать с помощью одной фичи - первоклассных ссылок. Видимо, решение делать все типы ссылочными тоже соответствовало бы "ортогональному" подходу. Но во-первых, из практических соображений авторы Алгола не хотели размещать все в куче. Наоборот, хотели иметь возможность размещать все на стеке, хотя куча со сборкой мусора и была добавлена. Но если вы переживаете за прочие функциональные фичи после такого-то решения вопроса о ссылочных типах, то у вас есть все основания. Во-вторых, это не устроило бы самих Хоара с Виртом. Рекорды Хоара должны были быть единственным ссылочным типом, передача параметра по ссылке должна была быть отдельной фичей. Хоар с Виртом были против "ортогональности" в принципе и называли свой подход "диагональным". Не повезло! Описывать все это в репорте хотел только Ван Вейнгаарден. Вернее, руководить своими студентами и аспирантами, которые описывают. Так что все больше и больше в Algol X было таким, как хотел Ван Вейнгаарден. Если кто-то предлагал какую-то фичу, которую Ван Вейнгаарден видеть в Алголе не хотел, он жаловался, что описание языка - тяжелый труд, что добавлять это уже поздно, но если так уж нужно предлагающий может сам описывать синтаксис и семантику. Изменения, которые Ван Вейнгаардену нравились он, конечно же, вносил быстро и с удовольствием. "Кто первый подготовит заготовку для репорта - тот и выиграл" - неверный урок из истории ALGOL 60. Выиграл тот, кто хотел делать скучную работу по редактированию репорта. Просто в случае ALGOL 60 это был один и тот же человек - Петер Наур. +Время шло. Ван Вейнгаарден все не дописывал кандидат-репорт до конца. Партия минимального изменения потеряла темп и Алгол догнали авторы серьезных изменений. Вирт потерял интерес к Algol X и имплементировал их совместное с Хоаром предложение как ALGOL W, который позднее развился в язык Pascal. Algol X же разовьется совсем не в Паскаль. Партия минимального изменения упустила свой шанс и проиграла. С осени 66-го года Ван Вейнгаарден работал над репортом один, без Вирта и Хоара. Началось время существенного изменения. +Погодите-ка, если Ван Вейнгаарден так усилился, пытался ли он использовать свой подход к описанию языков из того доклада про CPS, сделать в Алголе работающую рекурсию? Похоже что нет. Он усилился потому, что описывал язык не как рассказывал в том докладе. И сам, по всей видимости, потерял интерес к этому своему изобретению. + +### Перестройка + +На заседании комитета в октябре 66-го в Варшаве МакКарти предложил ad-hoc перегрузку операторов. Но самое важное для нашей истории изменение там предложил Клаус Самельсон. Передачи параметров по ссылке достаточно для того, чтоб заменить вызов по имени для многих. Но, конечно, не для тех, кто использовал Устройство Йенсена. Сторонники "функционализации" попытались обменять свою частичную победу из ALGOL 60 на победу более полную. Самельсон предложил добавить в Algol X лямбды [Same65]. +Вместо техники Йенсена применяющейся как здесь: + +```pascal +REAL PROCEDURE traps(a, b, n, f, x); + VALUE a, b, n; REAL a, b, f, x; INTEGER n; + BEGIN REAL s; INTEGER i; + x := a; + s := f/2; + FOR i := 1 STEP 1 UNTIL n - 1 DO + BEGIN x := x + (b - a)/n; + s := s + f END; + x := b; + traps := (b - a)/n * (s + f/2) + END + +traps(0, 1, n, exp(sin(w * t)), t) +``` + +Теперь можно, наконец, писать нормальную ФВП: + +```pascal +REAL PROCEDURE traps(a, b, n, f); + VALUE a, b, n; REAL a, b; INTEGER n; REAL PROCEDURE f; + BEGIN REAL s; INTEGER i; + s := (f(a) + f(b))/2; + FOR i := 1 STEP 1 UNTIL n - 1 DO + s := s + f(a + i * (b - a)/2); + traps := (b - a)/n * s + END + +traps(0, 1, n, REAL t : exp(sin(w * t))) +``` + +В предложении самельсона 65-го года лямбды точно не изобретены независимо, ЛИ упоминается явно. Но типы функций все еще неполные, как в ALGOL 60. И, конечно, из принципа "ортогональности" следует, что в языке должны быть лямбды и функциональные переменные, раз уж в нем есть функциональные параметры. К следующему заседанию комитета в Зандворте в мае 67-го Ван Вейнгаарден включил и перегрузку и лямбды в язык. +Для того, чтоб эти нововведения больше походили на Алгол, в Algol X добавили фичу, которой критики Алгола будут особенно недовольны - неявные приведения типов. Например, ссылки приводятся к значениям, а значения к лямбдам. Алголисты так вошли во вкус, что вместо специальных скобок добавили приведение элемента массива к массиву из одного элемента, для того чтоб `(1)` мог быть таким же нормальным литералом для массива как `()` и `(1,2)`. Как и МакКартиевские перегрузки операторов и структурные типы, это делало вывод типов в Алголе не особенно реалистичным, хотя этого, вроде бы, никто и не собирался делать. +Сходство с ALGOL 60, впрочем, уже перестало интересовать алголистов. Даже основной автор ALGOL 60 написал предложение [Naur64] о том, что функция должна возвращать значение последнего блока, а никаких присваиваний к одноименной переменной быть не должно. Алголисты сделали следующий логичный шаг и сделали Новый Алгол языком выражений, это была одна из первых идей Ван Вейнгаардена о том, каким должен быть новый Алгол. Еще 64-го года. +Наур сделал еще одно популярное предложение [Naur66] от октября 65-го о том, что аннотации типов и способов передачи аргумента + +``` +PROCEDURE P(a, b, c); VALUE b; INTEGER a, b; REAL b; +``` +должны быть в списке параметров: + +``` +PROCEDURE P(INTEGER a, INTEGER VALUE b, REAL c); +``` + +как, например, в CPL. По крайней мере, CPL в начале 66-го года [Stra66b]. Но еще в 63-ем в CPL псевдокоде [Barr63] типы уже были в списке параметров, хотя способы передачи параметров декларировались отдельно: +``` +ROUTINE Work [REAL a, b, c, INDEX d, LABEL e] + VALUE a, e; REF c; SUBST b, d +``` +Это нововведение приняла даже партия минимального изменения Алгола. +Синтаксис ALGOL 60 со множеством длинных ключевых слов подсократили и облегчили. Но легкость синтаксиса не навязывалась. У конструкций сделали и легкие и тяжелые синтаксические формы. + +### Сюрприз + +Наконец, в феврале 68 Ван Вейнгаарден распространил черновик репорта, который дошел даже до комитетчиков, которые старались не знать как там идут дела с описанием нового Алгола. В ужасе, они увидели там вместо Алгола язык, на котором можно писать что-то такое: + +``` +MODE LIST = REF NODE; +STRUCT NODE = (INT head, LIST tail); + +OP >> = (INT x, LIST xs)LIST: HEAP NODE := (x,xs); +PRIO >> = 9; +LIST nil = NIL; + +PROC map = (PROC(INT)INT f, LIST xs)LIST: + (xs IS NIL | NIL | f(head OF xs) >> map(f,tail OF xs)); + +INT y = 1; + +map((INT x)INT: x + y, 1 >> (2 >> (3 >> nil))) +``` + +Удивительно, но язык, похожий на ALGOL 60 примерно в той же степени, что и CPL, все равно назвали Алгол. Хотя, после различий между SASL и SASL, такое уже не должно удивлять. По крайней мере авторы языка сами дописали год к названию, получив ALGOL 68. +Конечно, бросается в глаза отсутствие параметризованных типов, но в остальном язык выглядит скорее как очередной модный и молодежный язык с элементами ФП начала двадцать первого века. Так что, не смотря на то, что долгое время Паскаль от партии ограниченной модификации Алгола был популярнее, понятно кто в конечном итоге оказался на верной стороне истории. И рассказ о параметризованных типах еще впереди, алголисты продвинулись тут значительно дальше смутных идей авторов CPL. +Да, функции всегда определяются с помощью лямбд. Ортогональность! Обратите внимание на то, что все объявления по умолчанию - это объявления констант. У обоекембриджских языков, как мы помним, с этим не все хорошо, это больше похоже на будущие эдинбургские языки. Функции не обязаны быть константами, можно объявить и мутабельную ссылку на функцию. В некоторых случаях даже нужно. Например, чтоб разбить взаимную рекурсию в том случае, если компилятор ALGOL 68 её не поддерживает. И компиляторы ALGOL 68 что-то не поддерживают не так и редко. +Думаем, уже из этого примера понятно, почему авторам первого компилятора Пролога и первого компилятора ML нравился ALGOL 68. Понятно, почему алголисты считают, что ML и даже эдинбургские ФЯ вообще произошли от ALGOL 68. Эта гипотеза выглядит очень правдоподобной. Установить происхождение ML от CPL можно только читая малодоступный обоекембриджский самиздат и подмечая какие-то необычные детали. И по воспоминаниям участников Эдинбургской Программы. +Понятны и претензии обоекембриджцев на влияние и даже происхождение ALGOL 68 от CPL. Какой из этих языков повлиял на какой и как - не так просто определить. Особенно потому, что участие Ландина в проектировании этих языков не особенно хорошо документировано. +Известно, что Ландин был в "ближнем круге" ван Вейнгаардена вместе с Ёнэдой, командой имплементаторов Герхарда Гооса (Gerhard Goos) из Мюнхена и другой командой имплементаторов из Брюсселя и получал черновики репорта еще в 67-ом. Если учесть такой-то состав "ближнего круга", а также то, что Гоос работал в одном университете с Самельсоном и Бауэром, неожиданная метаморфоза Алгола уже не выглядит такой уж неожиданной. +Но странно, что при всем при этом одно важное обстоятельство вскрылось только в Июне 1968 на встрече комитета в Тиррении. Там Ландин продемонстрировал, что функциональное программирование на ALGOL 68, каким его планировали сделать на тот момент, невозможно: + +``` +PROC curryplus = (REAL u)PROC(REAL)REAL: (REAL v)REAL: u+v; +PROC(REAL)REAL addthree = curryplus (3); +addthree(5) +``` + +возвращаемая из функции `curryplus` функция `addthree` ссылается на окружение, время жизни которого закончилось вместе с этим возвращением. Лямбды и тут неправильные. И алголисты не готовы к типам, значения которых не могут лежать на стеке. Поэтому возвращение функций, ссылающихся на окружение из которого они возвращаются, было запрещено. Так что МакКарти поучаствовал в создании как минимум двух языков с, по крайней мере, двумя разновидностями неправильных лямбд. +Но все эти функциональные проблемы затмила реакция комитетчиков не из "ближнего круга". Интересно, что еще сильнее чем язык, комитетчиков возмутил способ его описания. Хотя Ван Вейнгаарден получил в свое время контроль над репортом потому, что комитетчики хотели, чтоб новый Алгол описывали именно так. +После распространения черновика весной 68-го из комитета ушли Наур и Вирт, еще несколько комитетчиков, включая Хоара и Дейкстру, доработали в комитете до завершения первой редакции, но написали особое мнение [Dijk70] в котором назвали репорт слишком большим, а язык устаревшим. +Почему они считали его устаревшим? Это неочевидно из самого особого мнения. Но если учесть хорошее отношение Хоара к SIMULA и прочие работы и идеи подписантов особого мнения, то можно предположить, что из-за отсутствия каких-то конструкций для группировки функций. Вроде классов и, в недалеком будущем, модулей и АТД. По крайней мере, отсутствие модулей будет одной из основных проблем, которые авторы ALGOL 68 будут решать в 70-е. +Действительно ли репорт большой? Ну, даже если не считать все цитаты и одну иллюстрацию из «Винни-Пуха» Милна, зачем-то включенных в репорт, ALGOL 68 больше, чем SML 97. Но меньше, чем Haskell 98. Правда, в последствии репорт стал больше, проектирование языка не закончено в 60-е годы. Комитет планировал выпустить репорт и дать время имплементаторам его использовать. А после, уже с участием имплементаторов, написать окончательный репорт, к которому можно только добавлять фичи. Но не убирать и менять фичи из "окончательного" репорта. С момента выбора названия они опасались, что в 68-ом году он не будет готов. Так и вышло, первое издание репорта [Wijn69] было закончено в 1969. + +## Посчитать компиляции в Молверне + +> Более десяти тысяч успешных компиляций было выполнено вычислительной службой Королевского радарного института. +> Филип Вудвард, Практический опыт ALGOL 68 [Wood72] + +Конференция пытающихся имплементировать Алгол 68 состоялась в июле следующего, 1970 года в Мюнхене. Над имплементацией работали еще во время написания репорта. Две команды имплементаторов из Мюнхена и Брюсселя, как мы помним, пристально следили за работой Ван Вейнгаардена. Не дожидаясь очередных сюрпризов на плановых заседаниях комитета на одном из очередных морских или лыжных курортов. Но, неожиданно для всех участников [Lind93] [Bond2001], гонку выиграли не они. + +### ALGOL 68-R + +Первый компилятор написала команда имплементаторов из Королевского Института Радиолокации в Молверне: Иан Карри (Ian F. Currie), Сьюзен Бонд (Susan G. Bond) и Джон Морисон (John D. Morison). Перед докладом [Curr70] выступил с краткой историей проекта их руководитель, начальник отдела Филип Вудвард. Тот самый Вудвард, который рассказывал на летней школе 63-го года по "нечисленным вычислениям" [Fox66] про CPL и диалект ALGOL 60, который произвел впечатление на Поплстоуна [Popplestone]. +В 68-ом году в Радиолокационном институте начался переход на новые машины. И хотелось еще более современный и выразительный язык, чем Алгол 60. В 63-ем Вудвард с энтузиазмом ожидал CPL, который, по его рассказам, должен был "объединить все полезные средства LISP и ALGOL, да еще и добавить новых". В 68-ом было уже ясно, что разработка CPL провалилась. Но не время впадать в отчаянье. Как раз заканчивают описание почти такого же амбициозного языка - ALGOL 68. Успеют ли в институте имплементировать компилятор ALGOL 68 за два года, до полного перехода на новые машины, или лучше снова имплементировать ALGOL 60? (Портировать тот компилятор, про который Вудвард рассказывал в 63-ем невозможно - он написан на ассемблере). Решение было сложным. Но если говорить о выборе языка, на который они хотели бы перейти с Алгола 60, то тут выбора (уже?) не было. +В результате Вудвард и др. решили, что напишут новый компилятор примерно за год. И писали его с января 69-го. Компилятор написан на расширенном подмножестве Алгол 60, который им все же пришлось имплементировать для новой машины, ICL 1907F. Для нее еще не было ничего, кроме посредственного компилятора Фортрана. В апреле 70-го компилятор подмножества Алгола 68 уже был готов для пользователей в институте, в октябре 70-го запланирован полный переход на новые компьютеры. +Да, имплементировано только подмножество Алгола 68, которое разработчики из Молверна называют ALGOL 68-R. Но это не частичная имплементация из тех что были для CPL, когда почти ничего не было имплементировано. В данном случае было имплементировано почти все. Изменения в языке нужны для того, чтоб код можно было компилировать в один проход. Мы практики, объясняет Вудвард, для нас важна высокая скорость компиляции. Для этого пришлось пожертвовать несколькими фичами вроде автоматического преобразования обычных обращений по имени в лямбды и сделать декларации перед использованием обязательными. Такое объявление типов - расширение языка: + +``` +MODE X; +MODE Y = STRUCT (INT a, REF X x); +MODE X = STRUCT (REAL r, REF Y y) +``` + +Взаимная рекурсия двух функций разбивается уже имеющимися средствами: + +``` +PROC p1,q1; +PROC p = VOID: ( ... ;q1; ... ); +PROC q = VOID: ( ... ;p1; ... ); +p1 := p; q1 := q; ... +``` + +Что, конечно, было бы не особенно приятно делать в ФЯ. +Для компиляции нужно по крайней мере 96Кб (32K 24-бит. слов). Из них 60Кб - код самого компилятора. Разработчики считают, что это довольно много. +Можно использовать рантайм с компактифицирующим сборщиком мусора, но для желающих писать программы не использующие кучу - всего оверхеда связанного со сборкой мусора можно избежать. Производительность генерируемого кода для авторов тоже важна. +Возможно, Стрейчи и др. все-таки стоило доделать описание CPL. Может быть, в Радиолокационном Институте имплементировали бы какое-то более интересное его подмножество, чем имплементировал Ричардс. + +### Algol68C + +Но Вудвард, конечно, не единственный и даже не первый герой нашей истории, безрезультатно ожидавший CPL. CPL ждал еще один наш старый знакомый - Морис Уилкс. И, конечно же, в кембриджской компьютерной лаборатории под его началом тоже обнаружили новый язык с похожими на CPL возможностями. +В 1970, в том году, когда первый компилятор Алгола 68 уже передали первым пользователям, более известный другими своими проектами Стивен Борн (Stephen Richard Bourne) и Майкл Гай (Michael J. T. Guy) начали имплементацию языка под названием Z70 [Birr77]. Z70 был языком выражений для калькулятора с двумя типами: целыми числами и функциями, небольшим приблизительным подмножеством ALGOL 68. Z70 развивался как ISWIM, от минимального языка выражений, до языка совсем не минимального. Но если ISWIM долгое время рос только на бумаге, то Z70 рос как имплементация. Да еще и на том компьютере, для которого в свое время делали CPL. Имплементирован на том самом Titan с помощью компилятора компиляторов PSYCO. Можно ли имплементировать Z70, который еще больше? Раз за разом оказывалось, что можно! Шло время, и Z70 включал все больше фич Алгола 68, а все большую часть компилятора Z70 писали на Z70. К середине 72-го года Z70 был все еще подмножеством, но уже узнаваемым диалектом Алгола 68 и его переименовали в Algol68C. +В том же 72-ом году было принято решение писать портабельный компилятор Алгол 68, написанный на Алгол 68. Гай в этом проекте принимает уже не особенно активное участие. Первая версия была написана на подмножестве языка,доступном имплементации бывшего Z70. Портируемость достигалась использованием виртуальной машины ZCODE, как достигал BCPL, транслирующийся в OCODE. +Этот компилятор не был однопроходным, стадий компиляции у него было больше, чем у типичного компилятора Лиспа, но не так много, как у RABBIT, конечно. Компилятор в код ВМ компилировал в три стадии: парсер, тайпчекер и генератор ZCODE. ZCODE транслируется в нативный код нужной машины в один проход. +Компилятор, к сожалению, реализовывал гораздо менее интересное для нашей истории подмножество Алгола 68: только не требующую сборки мусора часть языка. +В сентябре 72 Борн начал переписывать парсер на Алгол 68. С января 73-го новый участник проекта - аспирант Эндрю Биррелл (Andrew Birrell) - пишет тайпчекер и работает над системой раздельной компиляции. К июню 73-го парсер и тайпчекер работают достаточно хорошо, чтоб распарсить и тайпчекнуть себя. Биррелл, еще один аспирант Уолкер (I. Walker) и научный сотрудник Эндрюс (A. Andrews) на основе кодогенератора Z70 пишут новый кодогенератор и транслятор ZCODE для Titan. Наконец, в конце сентября 1973 кембриджский компилятор Алгола 68 благополучно компилирует себя на Titan, за неделю до окончательного прекращения его работы. +Ура? Мечта Мориса Уилкса и других кембриджцев сбылась? По крайней мере, в урезанном виде. После апгрейда машины с увеличением памяти в четыре раза [Lavi12]. И слишком поздно. Да, это не воплощение самых смелых фантазий о CPL, не ML и даже не ФЯ вовсе. Но демонстрирует, что BCPL-пораженчество не было единственным практически возможным результатом обоекембриджской программы. Практичный неФЯ мог бы быть в большей степени ФЯ, чем сделал Ричардс. +Но мы уже выяснили, что компилятор полноценного ФЯ был неосуществим в то время и на том железе, которое было в распоряжении имплементаторов CPL. Но что насчет 70-х и более нового железа? CPL на рубеже 60-х и 70-х мертв, а ALGOL 68 пока еще нет. Dum spiro spero! Сегодня нам известны мейнстримные языки, такие как Java и С#, в которых изначально не было полноценных лямбд и параметризованных типов, но со временем они были добавлены. Могли ли их добавить в ALGOL 68? + +Эдикт Фонтенбло +--------------- + +Такие пожелания появились практически сразу же после конференции имплементаторов. Как оказалось, имплементировать Алгол 68 не так сложно, как ожидали его авторы. Так почему-бы не сделать язык еще более амбициозным? Тем более, что партия минимальной модификации и все сочувствующие окончательно разгромлены. + +### ALGOL 68 Revised + +Первое заседание комитета, который готовил второй, окончательный репорт состоялось через неделю после конференции имплементаторов, в июле 1970, в Абе-ла-Нёв [Lind93]. На нем Ханс Бекич (Hans Bekić) начал свою компанию за полноценные лямбды в Алголе 68. Но не стоит удивляться, что в начале 70-х кто-то, о ком мы пока еще не писали, вдруг озаботился возможностью возвращать функции из функций. Ханс Бекич работал с Ландином в колледже королевы Марии в 1968–69 [Jone99]. Работал в Венской лаборатории IBM, цитировал [Beki84] Бурсталла, разрабатывал META IV в 1973-75 вместе с Джонсом [Jone78]. И таким образом был частью той социальной сети вокруг Берджа и Йорктаун Хайтс. Тех узких кругов, в которых возвращение функций из функций было хорошо известно. +Проблема в том, что полноценные лямбды, размещающие замыкание в куче, а не на стеке делают сборку мусора гораздо важнее. Авторы Алгола 68 предпочитают его видеть в первую очередь стековым языком, имплементация которого может и не включать сборщик мусора. Так что у таких идей найдутся противники как среди старого поколения комитетчиков, которые в свое время не пропустили ссылочные типы Хоара, так и среди новых комитетчиков-имплементаторов. +Но, как мы уже выяснили, идеи о возвращении функций стали занимать умы как раз в это время. От возвращения функций в 70-м отмахнуться уже чуть сложнее, чем в 68-м. Поэтому против полноценных лямбд выдвинули два контрпропозала. Что посчитали главной проблемой полноценных лямбд Бекича [ALGOL72b]? То, что компилятор должен как-то отличать лямбды, замыкание которых нужно размещать в куче от тех, которым требуется только дисплей и стек. И все объявления процедур в Алголе 68 лямбды, так что отличать придется часто. Компилятор Стила будет решать эту проблему в конце 70-х. И не то чтобы комитетчики опасались, что не смогут решить её в начале 70-х, но считали, что это может заметно замедлить и усложнить компиляцию. Вполне разумное предположение, если учесть системные требования RABBIT. При этом комитетчики считают, что если задача будет решена и замыкания на стеке будут создавать только функции, которым это необходимо, то не придется платить за это тем, кто таких функций не пишет. Так что оба контрпропозала были направлены на облегчение решения именно этой задачи. +Первый контрпропозал - окружения Бома. Хендрик Бом (Hendrik Boom) предложил явно обозначать область видимости замыкания аннотацией `glob`: + +``` +MODE M = PROC(REAL)REAL; +OP O = (GLOB M f, g)M: (REAL X)REAL f(g(x)); +M cs = cos O sin; +``` + +Второй контрпропозал - частичная параметризация. Сначала так называли декларацию каррированных функций. Вместо многословия нескольких лямбд `(X x)PROC (X)X:(X y)X: x+y` просто `(X x)(X y)X: x+y`. + +``` +MODE F = PROC(REAL)REAL; +PROC compose = (F f)(F g)(REAL x)REAL: f(g(x)); +F g = compose(cos)(sin); +F h = g(1.0); +``` + +Окружения каррированных функций отправляются в кучу. +В обоих случаях компилятору очень легко определить где размещать окружения. +Но, конечно, без параметризованных типов функциональное программирование хорошо не пойдет. И как раз такой пропозал выдвинул Радиолокационный Институт весной 71-го [ALGOL71]. Типы в Алголе 68 называются "modes" и эта фича получила название "modals". +В ранней версии сами типы еще не были параметризованы. Предлагалось объявлять абстрактные типы без правой части и потом работать с ссылками на этот тип: + +``` +MODE X; +PROC sort = (REF[] X vec, PROC(REF X, REF X)BOOL cmp): ... +``` + +Фича демонстрируется на ФВП: + +``` +MODE X, LIST = STRUCT(REF X value, REF LIST next); +PROC apply = (REF LIST l, PROC(REF X) f): + (REF LIST ll := l; REF LIST empty = nil; + WHILE ll ISNT empty DO (f(value OF ll); ll := next OF ll) + ); +``` + +Тут `MODE X, LIST = ...` не какой-то новый синтаксис, это просто краткая запись для `MODE X; MODE LIST = ...` +В обобщенном коде со значениями такого абстрактного синонима, конечно, ничего нельзя сделать, можно только оперировать ссылками на него. Иначе такой код не скомпилировать отдельно от используемых потом конкретных типов. Обычная идея об "универсальном представлении". + +``` +MODE INTLIST = STRUCT(REF INT value, REF INTLIST next), + BOOLIST = STRUCT(REF BOOL value, REF BOOLIST next); +INTLIST il := ...; BOOLIST bl := ...; +apply(il, (REF INT i): (i := -i)); +apply(bl, (REF BOOL b): (b := NOT b)); +``` + +Совсем не удивительно, что разработчики кембриджской имплементации без сборщика мусора стали противниками [Bour72] этого предложения разработчиков имплементации со сборщиком мусора. Кембриджцы обеспокоены сложностью имплементации и считают, что полагаться на работоспособность универсального представления на компьютерах будущего опасно: в будущем ссылка на значение одного типа может отличаться от ссылки на значение другого. +Пропозал развивался и в 72-ом году "modal", который называют также и "explicit free mode" становится параметром [ALGOL72b]: + +``` +PROC sort = (MODE X, REF[]X a, PROC(REF X, REF X)BOOL swap)VOID: ... +``` + +параметризованная типом процедура используется так: + +``` +sort(INT, row, swap) +``` + +и раскрывается в + +``` +(MODE X = INT, REF[]X r = row, PROC(REF X, REF X)BOOL swp = swap ... sort(r,swp)) +``` + +планируют разрешить частичную параметризацию для аргументов-типов такого вида: + +``` +PROC gensort = (MODE X)(REF[]X a, ... +PROC(REF[]INT, ...) intsort = gensort(INT); +``` + +даже если соответствующий пропозал для обычных параметров не пройдет. +Теперь можно параметризовать и типы-синонимы: + +``` +MODAL LIST = (MODE Y) STRUCT(REF Y a, REF LIST(Y) next); +``` + +с похожим на лямбду синтаксисом. "Modals" называют функциями времени компиляции. +Появилось и предложение по улучшению конструкции для разбора композитных типов +[ALGOL72] [ALGOL72b]: + +``` +CASE xs IN + (NULL): ... , + (CONS l): ... l ... +ESAC +``` + +Позже, чем похожая конструкция описана у Бурсталла [Burs69] (1968). Но раньше, чем похожая конструкция описанная Хоаром [Hoar75], ссылающимся на Бурсталла (октябрь 73). Раньше, чем похожая конструкция появилась в _неисполняемом_ языке описания спецификаций META IV [Jone78] над которым работал Бекич (1973-75). Раньше, чем такая конструкция появилась в описании SCRATCHPAD [Jenk74] (апрель 74). Конструкция могла быть предложена МакКарти или Ландином. МакКарти слушал доклад Бурсталла [Burs69], но мы не видели, чтоб МакКарти когда-нибудь использовал её. И ни Ландин, ни МакКарти не принимали активного участия в доделывании Алгола 68. Может быть, конструкция была предложена Хоаром, который писал о ней позже и уже мог знать в это время. Но не принимал участия в доделывании Алгола 68 вовсе. Но скорее всего, если кто и предложил её - то Бекич, который на следующий год спроектировал язык с такой конструкцией и мог познакомится с ней в Йорктаун Хайтс. Или увидеть в статье Ландина и Бурсталла, в которой она вероятно использовалась и на которую Бекич ссылается в своих работах [Beki84]. "Вероятно" тут потому, что статья не отсканирована, и судить о её содержании можно только по косвенным признакам. Не исключено, даже не смотря на все это столпотворение людей, которые её видели, что конструкция была изобретена независимо. +Разумеется, у конструкции для разбора юнионов была и версия с облегченным синтаксисом, так что `map` на Алгол 68 теперь можно написать так: + +``` +PROC map = (PROC(INT)INT f, LIST xs)LIST: (xs| + (NULL): null, + (CONS l): f(h OF l) >> map(f,t OF l)); +``` + +К сожалению, "паттерн матчинг" одноуровневый, как в трактовке идеи Бурсталла Хоаром. И в системе МакКарти это еще хуже, чем в случае сумм произведений как у Хоара. Там хотя-бы можно связать хвост и голову в паттерне, а не доставать их из рекорда селекторами. +Итак, в 1972 Алгол 68 был близок к тому, чтоб стать "Эдинбургским ФЯ" до появления Эдинбургских ФЯ. Да, типы данных - не суммы произведений. Да, не ссылочные типы с понятными последствиями для полиморфизма. Но это детали и провести границу было бы труднее. Было бы. Такой Алгол 68 не состоялся. +На очередном заседании комитета в апреле 72 в Фонтенбло по всем требующим сборку мусора ФП планам был нанесен сокрушительный удар [ALGOL72a]. Параметризованные типы отклонили. Ареол первых имплементаторов Алгола 68 не помог. Отклонили и полноценные лямбды Бекича и обе их альтернативы. Линдси вспоминает, что полноценные лямбды вполне могли быть приняты. Но не были. Активность Ханса Бекича по отстаиванию полноценных лямбд произвела впечатление на его коллег по алголостроению и хорошо им запомнилась, если судить по его некрологу [Lind83]. Но её не было достаточно для победы. +Конструкции для разбора юнионов, правда, пережили разгром в Фонтенбло в неопределенном статусе и была принята в сентябре 72 в Вене [ALGOL73]. Так что имплементация `map` из примера выше работает. В сентябре 1973 в Лос-Анджелесе был принят окончательный ALGOL 68 репорт [Wijn77]. Опубликован в марте 75-го. + +### Расширения + +Окончательность репорта, правда, не означала полного краха функционализации Алгола 68. Из него больше ничего нельзя убрать или существенно переделать, но можно добавить. Это даже проще, процесс для принятия расширений Алгола 68 не такой сложный. Конечно, лямбды Бекича уже не принять: нельзя менять как работают лямбды. Но частичная параметризация и параметризованные типы становятся такими пропозалами расширений. +Параметризованным типам новый процесс принятия не особенно помог. Алголистам не особенно нравилось, что можно работать только со ссылками на типы-параметры. Хотя это ограничение было с самого начала, со временем эта ссылочная версия "модов" стала называться "ограниченными модами". Но и добавлять гипотетические неограниченные "моды", то есть фичу, которая не позволяет раздельную компиляцию они тоже не хотели [Lind74b]. +Но надежду решить более сложную проблему фунарга алголисты не потеряли. Частичная параметризация была переработана [Lind74a]. Это больше не способ объявлять каррированные лямбды. Фича теперь работает в месте применения, никак не влияя на объявление: + +``` +PROC compose = (PROC(REAL)REAL f, g, REAL x)REAL: f(g(x)); +PROC (REAL)REAL cossin = compose(cos,sin, ) +``` + +И прямо совместима с окончательным Алголом 68. Все лямбды продолжают компилироваться как раньше, частичное применение должно копировать данные со стека в кучу и создавать функцию, которая перед вызовом частично примененной функции вернет все что нужно из кучи на стек. Это, конечно, менее эффективно для пользователей, передающих функции вверх, но передающий их только вниз не платит за возможность передавать вверх. +В январе 75-го в Бостоне был собран специальный подкомитет по частичной параметризации из Бекича, Линдси и еще нескольких имплементаторов. В августе 75-го в Мюнхене расширение было принято. Описание добавлений в репорт опубликовали [Lind76] в начале 76-го. Алгол 68 все-таки стал, хотя-бы на бумаге, неудобным ФЯ без параметрических типов. Чем-то вроде POP-2, но на десяток лет позже. +Еще одно принятое по новому процессу расширение - модули. И в компилятор Радиолокационного института [Bond77] и в Кембриджский компилятор [Birr77] добавили модули довольно рано, для поддержки раздельной компиляции. В радиолокационном Алголе они были даже параметризованными. Стандартные модули начали обсуждать в Фонтенбло в 72, рассмотрели несколько пропозалов [Schu74] [Curr76] [Lind76b] [ALGOL78]. Некоторые идеи оттуда могли повлиять на работу с пространствами имен в ФЯ. Например оттуда в OCaml могла попасть квалификация для выражения вида `Module.(name1 + name2)`. Но это могло быть и изобретено независимо. Модули приняли в Яблонне в августе 78 [Lind78], на чем процесс расширения Алгола 68 и закончился. +Комитет, пишущий Алгол-репорт - так называемая "Рабочая Группа 2.1 IFIP по алгоритмическим языкам и исчислениям" - существует и сегодня [IFIP21], но, к сожалению, больше не выпускал никаких Алголов. В этом комитете побывали Дэвид Тернер, Конор МакБрайд, Олег Киселев, Ричард Берд и многие другие выдающиеся мыслители. Так что больно думать о том, какие потенциальные Алголы мы потеряли. +Но не все смирились с гибелью мечты о функциональном алголе 72-го года. Бауэр и Самельсон в том же роковом году решили делать в Мюнхене свой функциональный Алгол [Baue76]. + +### ALGOL 77 + +Конечно же, функции в Алгол 77 могут возвращать функции [Baue81] и в нем даже планировались аннотации ленивости [Baue79c]. С 73-го года этот язык стал языком CIP-L (Computer-aided Intuition-guided Programming) для системы трансформации CIP-S как S-0/NPL/Hope был в Эдинбурге и Лондоне языком для систем Дарлингтона и Фезера. CIP-L не синоним Алгола 77, в Мюнхене делали еще и ФП-Паскаль. Более-менее активная работа началась только в 75. +Чтоб направлять и проверять трансформации в Алгол добавили параметризованные АТД со спецификациями как в CLEAR Бурсталла и Гогена. Можно сказать, что проект и был повторением работ Бурсталла и других с той разницей, что вместо CPL/ISWIM был ALGOL 68. Это не было какой-то конвергенцией с переизобретением того же самого независимо. Бауэр и другие явно ссылаются на работы Дарлингтона по трансформации кода и работы Бурсталла, Циллеса, Гогена, Гуттага над языками спецификации [Baue76] [Baue79b]. + +``` +TYPE Stack ≡ (MODE U) STACK U, nullstack, isnull, top, rest, append: + mode STACK U, + FUNCT STACK U nullstack, + FUNCT(STACK U) bool isnull, + FUNCT(STACK U s : ¬ isnull(s)) U top, + FUNCT(STACK U s : ¬ isnull(s)) STACK U rest, + FUNCT(STACK U, U) STACK U append, + LAW A : ¬ isnull(s) => append(rest(s), top(s)) = s, + LAW R : rest(append(s,x)) = s, + LAW T : top(append(s,x)) = x, + LAW E : isnull(nullstack), + LAW NE: ¬ isnull(append(s,x)) ENDOFTYPE +``` + +не смотря на очевидно исполняемый пример спецификации [Baue79], имплементации у Бауэра не отмирают, их нужно писать + +``` +[ MODE STACK U ≡ EMPTY | (STACK U trunk, U item), + FUNCT nullstack ≡ STACK U: () + FUNCT isnull ≡ (STACK U s) BOOL: s = nullstack, + FUNCT top ≡ (STACK U s : ¬ isnull(s)) U: item OF s, + FUNCT rest ≡ (STACK U s : ¬ isnull(s)) STACK U: trunk OF s, + FUNCT append ≡ (STACK U s, U s) STACK U: (s, x) ] +``` + +Обратите внимание на то, что типы должны быть ссылочными, разрешена рекурсия без явных ссылок. Облегченный синтаксис для декларации типов данных, но первоначально была еще система МакКарти, со ссылкой на него. Но вскоре ей на смену пришли суммы произведений как у Хоара, со ссылкой на него [Baue81] + +``` +MODE LIST ≡ ATOMIC{nil} | cons(M head, LIST tail) +``` + +Если эдинбургские коллеги Бауэра в конце концов пришли к языку в котором и типы и модули параметризованы, то Алгол 77 начал как язык в котором и типы (modes) и модули (types) параметризованы, но стал языком, в котором параметризованы только модули. +Не смотря на цитирование Бурсталла, добавление в язык АлгТД и уравнений для спецификаций, никакого паттерн-матчинга, только многоветочный `if` + +``` +IF l IS cons THEN ... head OF l ... tail OF l +| l IS nil THEN ... +``` + +Но Бауэр позаимствовал выражение `where`. + + +Ограниченное могущество кучи +---------- + +Разумеется, все это богатство ссылочных фич Алгола 77 не было имплементировано в 70-е [Part84]. А что было имплементировано? И что можно было использовать для имплементации эдинбургских ФЯ? + +### Алголы 70-х + +Параметризованные типы (ну или "моды") были имплементированы в диалекте Алгола 68, называющемся Mary [Conr74]. Но Mary это не более свободный в использовании кучи язык, а наоборот более низкоуровневый и системный, с более явными ссылками. И параметризованные типы там жертвуют раздельной компиляцией, а не принимают универсальное представление: + +``` +MODE LIST(M) = (REF LIST(M) NEXT, M VALUE); +LIST(INT) LI := (NIL,2); +LIST(REAL) LR := (LR,5.0); +``` + +по крайней мере некоторые их разновидности. Это имплементировано не позднее лета 1974. +С поддержкой "ссылочных" фич в имплементациях Алгола 68 же все обстояло не особенно хорошо. Предложение Радиолокационного института про параметрические типы не было имплементировано даже Радиолокационным Интститутом и никто не имплементировал в 70-е годы частичную параметризацию [Lind93]. Сегодня имплементация, в которой это расширение поддерживается существует - Algol68g - но имплементировано оно неправильно. +Первоначальный Алгол 68 69-го года никогда не был полностью имплементирован. Но окончательный Алгол 68 75-го года был имплементирован один раз полностью. Но большинство имплементаций было частичными. Конечно, окончательный Алгол 68 не стал ФЯ, но если есть хорошо работающий сборщик мусора и хороший генератор кода для актуальных платформ, то можно использовать все это для имплементации ФЯ эдинбургской программы. Но есть ли все это? +Начинались работы над многими имплементациями Алгола 68 [Hunt77], но только две более-менее законченные имплементации обеспечивали хорошую производительность генерируемого кода. Уже знакомые нам компиляторы Радиолокационного Института и Кембриджа [Curr70] [Wich76] [Hunt77] [ALGOL80]. Например, Algol68C может быть быстрее BCPL. Получается, что сколько не жертвуй высокоуровневыми фичами, при плохом генераторе кода от этого много толку не будет. +Радиолокационный институт в 76-ом году начал работы над ALGOL 68RS - портируемым компилятором с ВМ, написанным на подмножестве Алгола 68. Летом 77-го года он уже работал [Bond77]. Бутстрап был, разумеется, осуществлен с помощью ALGOL 68-R. Но в Радиолокационном институте делали компиляторы для тех машин, которые использовали там [ALGOL81]. Разработчики ФЯ их не использовали. В 81-82 годах для ALGOL 68RS написали бэкенд для ненужного уже разработчикам ФЯ Multics. Только в начале 83-го года начались работы над генераторами кода для VAX и Motorola 68K [Finn83]. +В Кембридже, компилятор Algol68C заработал на новом компьютере IBM370/165 в конце декабря 73-го. Борн руководил его разработкой до начала 75-го. В 77-ом компилятор - это программа из 18 тыс. строк на Алголе 68 [Birr77]. +Следующей машиной после IBM370, на которой заработал компилятор была ICL 4130, та самая, которую использовали в Эдинбурге до PDP-10. По крайней мере в 77-ом он как-то работал. Когда в Эдинбурге эту машину уже не использовали. +Университет Эссекса портировал [Gard77] кембриджский Algol68C на PDP-10. Работы велись с осени 75 до весны 77. В лучших традициях таких проектов 70-х наработали за этот период только семь человеко-месяцев. +Транслятор из ZCODE в нативный написали на BCPL и переписали на Algol68C после бутстрапа. +Считают, что важно добиться того, чтоб код компилятора умещался в 35K слов (~140Кб), что удалось. И маленькая программа должна компилироваться секунд за шесть. Это не удалось, компилируется более 10 секунд. +Но в 77-ом году Algol68C еще считается недоделанным. Весной 77 первый релиз ожидают летом того же года, но релиз будет выпущен существенно позже. В январе 80-го [ALGOL80]. +И к релизу сборщик мусора все еще не заработал. Сборщика мусора в Algol68C нет не потому, что так и задумано. Разработчики компилятора обещают его в версии 2, работы над которой уже идут. Но если бы кто-то начал работы над компилятором ФЯ, который использует Algol68C как бэкенд, то это было бы ошибкой. Сборщик мусора так никогда не доделают и версия 2 никогда не выйдет. Последней версией будет 1.3. +Algol68C работал на VAX c 81-го года [ALGOL81], и хотя его невозможно было использовать как бэкенд и рантайм для ФЯ, его использовали в 80-е для написания имплементации ФЯ. +Из требований Algol68C можно составить некоторое представление о том, сколько памяти в конце 70-х может позволить себе требовать компилятор. Которым кто-то будет пользоваться на "обычной" машине, а не собранной специально под программы требующие гигантскую память, как RABBIT. +Первый релиз Algol68C на IBM 360/370 требовал минимум 180Кб и 200-220Кб для более реалистичных программ. Версия для PDP-10 требует минимум в 70K слов (~280Кб). Описатели этих требований обычно избегают указания конкретных размеров таких "реалистичных программ", но есть и исключения. В требованиях Algol68C для Telefunken TR440/TR445 говориться, что может потребоваться 50K слов (325Кб) для компиляции "больших" программ в 30 страниц [ALGOL80]. Судя по числу строк в распечатках программ на других языках, которые нам приходилось видеть до сих пор, это 1-2 тысячи строк. Надо полагать, что это для случая без раздельной компиляции. Потому, что компилятор они как-то компилируют. +Опциональность сборщика мусора в ALGOL 68-R/ALGOL 68RS и полное его отсутствие в Algol68C, а также успешное сопротивление фичам, которые сделали бы использование сборщика мусора более важным, от ссылочных типов и до полноценных лямбд, делает Алгол 68 не Java 70-х, которая при годилась бы для имплементации ФЯ, а чем-то вроде языка D 70-х. Разумеется, Алголом 68 и D список этих языков не исчерпывается. Даже Лисп, а точнее MacLISP пытался быть таким языком в 70-е. Тут мы имеем дело с интересным, но трагичным явлением, которое мы будем называть "язык семидесятых". Трагизм явления не только в неудачах вроде Алгола 68, но и в успехах вроде C++. +Авторы "языка семидесятых" уже знакомы со многими фичами, которые можно себе позволить в языке со сборщиком мусора. Но обязательный сборщик мусора не могут себе позволить авторы языка. Так что одни фичи приобретают странные формы и особенности, а другие отсутствуют, но не из-за незнания о них. Они сознательно запрещены потому, что авторы недостаточно смелые и неразборчивые для того, чтоб добавить эту фичу в странной форме и с особенностями. Если, конечно, авторы недостаточно смелые. +Ограниченная или неправильная первоклассность функций в одних языках 70-х могла мотивировать запрет на первоклассность функций в других языках 70-х. Так, в требованиях к языку, которым позднее станет Ada, запрет на первоклассность функций прописан явно [IRON77]. +Да, авторы некоторых языков не могут себе позволить сборщик мусора и сегодня. Но сегодня это скорее исключение. В 70-е это было правилом. И редкими исключениями были первые примеры того, что мы будем называть "язык восьмидесятых". Давайте посмотрим, какие языки в 70-е решили полагаться на наличие сборщика мусора, сделать его обязательным. Поищем настоящую Java 70-х. + +### Антиалголы 80-х + +ФЯ всегда были "языками восьмидесятых", хотя их неудачливые имплементаторы в 60-е этого и не знали. Но не все "языки восьмидесятых" - это ФЯ. Многие ФЯ в гораздо меньшей степени, чем Алгол 68. В том числе и из-за плохого отношения их авторов к Алголу 68 [Lisk93]. И плохое отношение к Алголу 68 довольно распространенный сентимент. Не беда, ФЯ можно сделать из любого "языка восьмидесятых" просто добавлением фронтенда. +Первым таким языком был, по всей видимости, еще один произошедший непосредственно от ALGOL 60 язык - SIMULA. Точнее поздние его версии с обязательным сборщиком мусора вроде SIMULA 67. +Для пользователей IBM 370 компилятор SIMULA 67 был готов в мае 72-го [Holm98]. Пользователи PDP-10 получили его позже. Но читатели, думаем, уже привыкли к тому, что это платформа второго сорта для всего, кроме Лиспа. +Компилятор SIMULA 67 для PDP-10 написали в Стокгольме. Он заработал в сентябре 74-го и первый публичный релиз состоялся только в январе 75-го. Да, в случае SIMULA 67 номер года в названии создает не намного менее обманчивое впечатление о том, когда его можно было использовать, чем номер года в названии ALGOL 68. +Для VAX компилятора SIMULA, правда, не будет. Но гипотетические имплементаторы ФЯ, которые могли бы решиться использовать компилятор SIMULA как основу их компилятора, этого еще не могли знать. Была проблема очевидная уже тогда - плохая производительность [Wich76] [Stro93]. +Но SIMULA 67 все-таки была полезна для развития ФП и повлияла на историю. Своим отсутствием на VAX мотивировала автора первого компилятора ML писать компилятор ML. +Другой ранний "язык восьмидесятых" - это уже знакомый нам по истории абстрактных типов язык CLU. Но до 77 он не может быть альтернативой компиляции через Лисп, так как сам транслировался в MDL - Лисп для антипрологов Хьюита. И практичный компилятор, который по оценке авторов был готов для использования, появился только в 1980 на PDP-10 и "позднее" на VAX и Motorola 68K [Lisk93]. Опять слишком поздно. +С прочими "языками восьмидесятых", которые начали делать в 70-х, на рубеже десятилетий все еще хуже. Наш будущий герой Дэвид Мэттьюз (David Charles James Matthews) в своей диссертации [Matt83] подготовил краткий обзор таких языков в начале 80-х. Russell - еще не имплементирован. Cedar Mesa - Mesa со сборщиком мусора, еще не имплементирован. Alphard - не имплементирован. +Да, транслировать эдинбургский ФЯ в Лисп - еще и не такая плохая идея. Все остальное готово в лучшем случае в той же степени или еще меньше. И похоже, что только трансляция в Алгол 68 производила бы код быстрее лиспового. Если б еще Algol 68RS был для имеющихся у разработчиков ФЯ машин. Если б только доделали вовремя сборщик мусора для Algol68C. +Все эти победы (отсутствия) сборщика мусора над Бекичем, "языками восьмидесятых" и ФП, конечно, не должны быть ни для кого сюрпризом. Ны уже ознакомились с плачевной ситуацией с памятью в то время. Сегодня мы знаем, что со временем сборщики мусора начали работать нормально, хотя и не без проблем. Но видно ли из 1980-го года хотя-бы отблески этого счастливого времени где-то в далеком будущем? Конечно, к описываемому времени сборщики мусора как-то существуют уже два десятка лет. Но мы уже видели, каким жалким и условным бывает такое существование на примере лямбд. Символично, что после ухода из проекта Борна, руководить разработкой Algol68C стал сапожник без сапог, более известный как раз статьей о сборщике мусора - Крис Чейни (Chris J. Cheney). Давайте выясним, насколько плохо шла сборка мусора, когда функционального программирования не было. + ПРОДОЛЖЕНИЕ СЛЕДУЕТ Литература @@ -5021,6 +5709,14 @@ Franz LISP входит в дистрибутив 3BSD и 4BSD. Статья п [Abra81]: Harvey Abramson, D. A. Turner, SASL Reference Manual. TM-81-26, October 1981 https://www.cs.ubc.ca/sites/default/files/tr/1981/TM-81-26.pdf [Acke28]: Ackermann, W. (1928). Zum Hilbertschen Aufbau der reellen Zahlen. Mathematische Annalen, 99(1), 118–133. doi:10.1007/bf01459088  [Aiel74]: Aiello, Jack Michael. An Investigation of Current Language Support for the Data Requirements of Structured Programming. Massachusetts Institute of Technology, Project MAC, 1974. https://ia802901.us.archive.org/34/items/bitsavers_mitlcstmMI_32305830/MIT-LCS-TM-051_text.pdf +[ALGOL71]: AB32.3.3 C, Modals. Algol Bulletin No. 32, May 1971 http://archive.computerhistory.org/resources/text/algol/algol_bulletin/A32/P33.HTM +[ALGOL72]: AB33.3.3 IFIP WG2.1 Subcommittee: Maintenance of and Improvements to ALGOL 68, Algol Bulletin No. 33, March 1972 http://archive.computerhistory.org/resources/text/algol/algol_bulletin/A33/P33.HTM +[ALGOL72a]: AB34.3.1 Report on the meeting of WG2.1 at Fontainebleau Algol Bulletin No. 34, July 1972 http://archive.computerhistory.org/resources/text/algol/algol_bulletin/A34/P31.HTM +[ALGOL72b]: AB34.3.2 Report on considered improvements (Fontainebleau 9), Algol Bulletin No. 34, July 1972 http://archive.computerhistory.org/resources/text/algol/algol_bulletin/A34/P32.HTM +[ALGOL73]: AB35.3.1 Further Report on Improvements to ALGOL 68, Algol Bulletin No. 35, March 1973 http://archive.computerhistory.org/resources/text/algol/algol_bulletin/A35/P31.HTM +[ALGOL78]: AB42.1.1 Modules and Separate Compilation, Algol Bulletin No. 42, May 1978 http://archive.computerhistory.org/resources/text/algol/algol_bulletin/A42/P11.HTM +[ALGOL80]: AB45.4.2 ALGOL 68 Implementations - ALGOL 68C - Release 1, Algol Bulletin No. 45, January 1980 http://archive.computerhistory.org/resources/text/algol/algol_bulletin/A45/P42.HTM +[ALGOL81]: AB47.3.3 Survey of viable ALGOL 68 Implementations, Algol Bulletin No. 47, August 1981 http://archive.computerhistory.org/resources/text/algol/algol_bulletin/A47/P33.HTM [ATLAS]: London Atlas http://www.chilton-computing.org.uk/acl/technology/atlas/p010.htm [Atki78]: Atkinson, M. P., & Jordan, M. J. (1978). An effective program development environment for BCPL on a small computer. Software: Practice and Experience, 8(3), 265–275. doi:10.1002/spe.4380080304 [Augu84]: Lennart Augustsson, A compiler for lazy ML. LFP '84: Proceedings of the 1984 ACM Symposium on LISP and functional programming August 1984 Pages 218–227 doi:10.1145/800055.802038 @@ -5035,15 +5731,25 @@ Franz LISP входит в дистрибутив 3BSD и 4BSD. Статья п [Barr63]: Barron, D.W., Buxton, J.N., Hartley, D.F., Nixon, E., and Strachey, C. The main features of CPL. Computer Journal 6(2) (1963) 134–143. [Barr68]: Barron, David William. Recursive Techniques in Programming (1968) [Bask80]: Forest Baskett, Andreas Bechtolsheim, Bill Nowicki and John Seamons, The SUN Workstation. March 1980 +[Baue76]: F. L. Bauer. 1976. Programming as an evolutionary process. In Proceedings of the 2nd international conference on Software engineering (ICSE '76). IEEE Computer Society Press, Washington, DC, USA, 223–234. doi:10.5555/800253.807679 +[Baue79]: Bauer, F.L. (1979). Program development by stepwise transformations — The project CIP. In: Bauer, F.L., et al. Program Construction. Lecture Notes in Computer Science, vol 69. Springer, Berlin, Heidelberg. doi:10.1007/BFb0014671 +[Baue79b]: Bauer, F.L. (1979). From specification to implementation — The formal approach. In: Bauer, F.L., et al. Program Construction. Lecture Notes in Computer Science, vol 69. Springer, Berlin, Heidelberg. doi:10.1007/BFb0014670 +[Baue79c]: Bauer, F.L. (1979). Detailization and lazy evaluation, infinite objects and pointer representation. In: Bauer, F.L., et al. Program Construction. Lecture Notes in Computer Science, vol 69. Springer, Berlin, Heidelberg. https://doi.org/10.1007/BFb0014675 +[Baue81]: Bauer, F. L., Broy, M., Dosch, W., Gnatz, R., Krieg-Brückner, B., Laut, A., … Wössner, H. (1981). Programming in a wide spectrum language: a collection of examples. Science of Computer Programming, 1(1-2), 73–114. doi:10.1016/0167-6423(81)90006-x  [BBC73]: The Lighthill debate on Artificial Intelligence https://www.youtube.com/watch?v=03p2CADwGF8&t=1682s [Bech82]: Andreas Bechtolsheim, Forest Baskett, Vaughan Pratt. The SUN Workstation Architecture. Technical Report No. 229, March 1982 +[Beki84]: Bekić, H. (1984). Towards a mathematical theory of processes. In: Jones, C.B. (eds) Programming Languages and Their Definition. Lecture Notes in Computer Science, vol 177. Springer, Berlin, Heidelberg. doi:10.1007/BFb0048944 [Bell98]: Bell G, Strecker WD. Retrospective: what have we learned from the PDP-11—what we have learned from VAX and Alpha. In 25 years of the international symposia on Computer Architecture (selected papers) 1998 Aug 1 (pp. 6-10). doi:10.1145/285930.285934 +[Birr77]: Andrew Birrell. System Programming in a High Level Language. Ph.D. Thesis, University of Cambridge. December 1977. [Blai70]: Fred W. Blair. Structure of the Lisp Compiler. IBM Research, Yorktown Heights, circa 1970. https://www.softwarepreservation.org/projects/LISP/ibm/Blair-StructureOfLispCompiler.pdf [Blai79]: Blair, F. W. "The Definition of LISP 1.8+0.3i." IBM Thomas J Watson Research Center, Internal Report (1979). https://www.softwarepreservation.org/projects/LISP/ibm/Blair-Definition_of_LISP1_8_0_3i-1979.pdf +[Bour72]: S.R.Bourne and M.J.T.Guy. AB33.3.8: Comments on suggested improvements to ALGOL 68, Algol Bulletin No. 33, March 1972 http://archive.computerhistory.org/resources/text/algol/algol_bulletin/A33/P38.HTM [Boye75]: Robert S. Boyer and J Strother Moore. 1975. Proving Theorems about LISP Functions. J. ACM 22, 1 (Jan. 1975), 129–144. doi:10.1145/321864.321875 [Bobr66]: Bobrow, Daniel G., D. Lucille Darley, Daniel L. Murphy, Cynthia Ann Solomon and Warren Teitelman. “THE BBN-LISP SYSTEM.” (1966). [Bobr67]: Daniel G. Bobrow and Daniel L. Murphy. 1967. Structure of a LISP system using two-level storage. Commun. ACM 10, 3 (March 1967), 155–159. https://doi.org/10.1145/363162.363185 [Bobr73]: Daniel G. Bobrow and Ben Wegbreit. 1973. A model and stack implementation of multiple environments. Commun. ACM 16, 10 (Oct. 1973), 591–603. doi:10.1145/362375.362379 +[Bond77]: Bond, Susan Gillian, Philip Mayne Woodward, and ROYAL RADAR ESTABLISHMENT MALVERN (ENGLAND). Introduction to the 'RS' Portable Algol 68 Compiler. Royal Radar Establishment, Procurement Executive, Ministry of Defence, 1977. +[Bond2001]: Susan Bond. An oral history conducted in 2001 by Janet Abbate, IEEE History Center, New Brunswick, NJ, USA. https://ethw.org/Oral-History:Susan_Bond [Brat86]: Bratko, Ivan. Prolog programming for artificial intelligence. 1986. [Broo14]: Stephen Brookes, Peter W. O'Hearn, and Uday Reddy. 2014. The essence of Reynolds. SIGPLAN Not. 49, 1 (January 2014), 251–255. doi:10.1145/2578855.2537851 [Bund84]: Bundy, Alan, ed. "Catalogue of artificial intelligence tools." (1984). @@ -5081,11 +5787,14 @@ https://core.ac.uk/download/pdf/236248615.pdf [Coel82]: Coelho, H., Cotta JC, and L. M. Pereira. "How to Solve it in Prolog, July 1982." Laboratório Nacional de Engenhara Civil, Lisbon, Portugal. [Cohe88]: Jacques Cohen. 1988. A view of the origins and development of Prolog. Commun. ACM 31, 1 (Jan. 1988), 26–36. doi:10.1145/35043.35045 [Colm96]: Alain Colmerauer and Philippe Roussel. 1996. The birth of Prolog. History of programming languages---II. Association for Computing Machinery, New York, NY, USA, 331–367. doi:10.1145/234286.1057820 +[Conr74]: R. Conradi, P. Holager, MARY Textbook, RUNIT rapport, 1974 [Coro83]: Corovessis, Jiannis. A parallel implementation of SASL. University of St. Andrews (United Kingdom), 1983. [Coul68]: Coulouris, George, T. J. Goodey, R. W. Hill, R. W. Keeling and D. Levin. “The London CPL1 compiler.” Comput. J. 11 (1968): 26-30. [Coul]: George Coulouris http://www.eecs.qmul.ac.uk/~gc/ [Crev93]: Crevier, Daniel, AI: the tumultuous history of the search for artificial intelligence, 1993. [Curr58]: Haskell B. Curry, Robert Feys, William Craig. "Combinatory Logic: Volume I" (1958). +[Curr70]: Currie, Ian F., Susan G. Bond and J. D. Morison. “Algol 68-R.” ALGOL 68 Implementation (1970). +[Curr76]: I.F. Currie, AB39.4.1: Modular Programming in ALGOL 68, Algol Bulletin No. 39, February 1976 http://archive.computerhistory.org/resources/text/algol/algol_bulletin/A39/P41.HTM [Darl72]: Darlington, John. "A semantic approach to automatic program improvement." (1972). [Darl73]: J. Darlington and R. M. Burstall. 1973. A system which automatically improves programs. In Proceedings of the 3rd international joint conference on Artificial intelligence (IJCAI'73). Morgan Kaufmann Publishers Inc., San Francisco, CA, USA, 479–485. [Darl75]: R. M. Burstall and John Darlington. 1975. Some transformations for developing recursive programs. In Proceedings of the international conference on Reliable software. Association for Computing Machinery, New York, NY, USA, 465–472. doi:10.1145/800027.808470 @@ -5096,6 +5805,8 @@ https://core.ac.uk/download/pdf/236248615.pdf [Dewa79]: Dewar, Robert BK. The SETL programming language. Bell Laboratories, 1979. [Dijk60]: Dijkstra, E. W. (1960). Recursive Programming. Numerische Mathematik, 2(1), 312–318. doi:10.1007/bf01386232 [Dijk62]: DIJKSTRA, E. W. (1962). "An ALGOL60 Translator for the X1" Automatic Programming Bulletin, No. 13. +[Dijk70]: AB31.1.1.1 "Minority Report", Algol Bulletin No. 31, March 1970 http://archive.computerhistory.org/resources/text/algol/algol_bulletin/A31/P111.HTM +[Dijk2001]: Dijkstra, Edsger Wybe. "Oral history interview with Edsger W. Dijkstra." (2001). [Dugg96]: Dominic Duggan and Constantinos Sourelis. 1996. Mixin modules. SIGPLAN Not. 31, 6 (June 15, 1996), 262–273. doi:10.1145/232629.232654 [Dunn70]: Raymond D. Dunn. "POP-2/4100 Users' Manual". School of Artificial Intelligence. University of Edinburgh (February 1970) [Eager]: Bob Eager, More on the ICL 2900 Series http://www.tavi.co.uk/icl/bob.htm @@ -5114,6 +5825,8 @@ https://core.ac.uk/download/pdf/236248615.pdf [Fate73]: R. J. Fateman. 1973. Reply to an editorial. SIGSAM Bull., 25 (March 1973), 9–11. doi:10.1145/1086803.1086804 [Fate81]: Fateman RJ. Views on transportability of lisp and lisp-based systems. InProceedings of the fourth ACM symposium on Symbolic and algebraic computation 1981 Aug 5 (pp. 137-141). [Feat79]: Feather, Martin S. “A system for developing programs by transformation.” (1979). +[Feni69]: Robert R. Fenichel and Jerome C. Yochelson. 1969. A LISP garbage-collector for virtual-memory computer systems. Commun. ACM 12, 11 (Nov. 1969), 611–612. doi:10.1145/363269.363280 +[Finn83]: Gavin Finnie, AB49.2.1 RS ALGOL 68 Implementors Group (RIG), Algol Bulletin No. 49, May 1983 http://archive.computerhistory.org/resources/text/algol/algol_bulletin/A49/P21.HTM [Fisc93]: Fischer, M. J. (1993). Lambda-calculus schemata. LISP and Symbolic Computation, 6(3-4), 259–287. doi:10.1007/bf01019461  [Fode81]: Foderaro JK, Fateman RJ. Characterization of VAX Macsyma. InProceedings of the fourth ACM symposium on Symbolic and algebraic computation 1981 Aug 5 (pp. 14-19). [Fode83]: Foderaro JK, Sklower KL, Layer K. The FRANZ Lisp Manual. Regents of the University of California; 1983 Jun. @@ -5123,6 +5836,7 @@ https://core.ac.uk/download/pdf/236248615.pdf [Frie76b]: Friedman, Daniel P. and David S. Wise. “CONS Should Not Evaluate its Arguments.” International Colloquium on Automata, Languages and Programming (1976). [Full76]: Samuel H. Fuller. 1976. Price/performance comparison of C.mmp and the PDP-10. In Proceedings of the 3rd annual symposium on Computer architecture (ISCA '76). Association for Computing Machinery, New York, NY, USA, 195–202. doi:10.1145/800110.803580 [Gabb98]: Gabbay, Dov M., Christopher John Hogger, and John Alan Robinson, eds. Handbook of logic in artificial intelligence and logic programming: Volume 5: Logic programming. Clarendon Press, 1998. +[Gard77]: P. J. Gardner. 1977. A transportation of ALGOL68C. In Proceedings of the Strathclyde ALGOL 68 conference. Association for Computing Machinery, New York, NY, USA, 95–101. doi:10.1145/800238.807148 [GEDANK]: GEDANKEN. Scanned source listing. https://www.softwarepreservation.org/projects/GEDANKEN/Reynolds-GEDANKEN-MakeTranslator.pdf [GEDANKb]: GEDANKEN. Scanned execution listing https://www.softwarepreservation.org/projects/GEDANKEN/Reynolds-GEDANKEN-Test_Ch_II_Run.pdf [GHC23]: GHC User’s Guide https://downloads.haskell.org/ghc/latest/docs/users_guide/ @@ -5159,16 +5873,22 @@ https://core.ac.uk/download/pdf/236248615.pdf [Hewi74]: Hewitt, C., Bishop, P., Steiger, R., Greif, I., Smith, B., Matson, T., & Hale, R. (1974). Behavioral semantics of nonrecursive control structures. Programming Symposium, 385–407. doi:10.1007/3-540-06859-7_147  [Hewi09]: Carl Hewitt. Middle History of Logic Programming. 2009 doi:10.48550/arXiv.0904.3036 [Hind07]: Hindley, J. R. (2007). M. H. Newman’s Typability Algorithm for Lambda-calculus. Journal of Logic and Computation, 18(2), 229–238. doi:10.1093/logcom/exm001   +[Hoar64]: C. A. R. Hoare. AB18.3.7: Case expressions, pages 20-22, Algol Bulletin No. 18, October 1964 +[Hoar65]: C. A. R. Hoare. AB21.3.6: Record Handling, Algol Bulletin No. 21, November 1965 [Hoar72]: Hoare, Charles Antony Richard. "Chapter II: Notes on data structuring." In Structured programming, pp. 83-174. 1972. [Hoar75]: Hoare, C.A.R. Recursive data structures. International Journal of Computer and Information Sciences 4, 105–132 (1975). doi:10.1007/BF00976239 [Hoar89]: Hoare, C.A.R. Recursive data structures. Essays in computing science. Prentice-Hall, Inc., USA. (1989) doi:10.5555/63445.C1104369 +[Holm98]: Holmevik, Jan Rune. "Compiling Simula: A historical study of technological genesis." (1998) https://staff.um.edu.mt/jskl1/simula.html [Honeywell72]: Honeywell Series 6000 User Manual [Howe07]: Jim Howe - ARTIFICIAL INTELLIGENCE AT EDINBURGH UNIVERSITY : A PERSPECTIVE http://www.inf.ed.ac.uk/about/AIhistory.html [Hud07]: 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, 12–1–12–55. DOI:10.1145/1238844.1238856 [Huda89]: Paul Hudak. 1989. Conception, evolution, and application of functional programming languages. ACM Comput. Surv. 21, 3 (Sep. 1989), 359–411. DOI:10.1145/72551.72554 [Hugh83]: Hughes, Robert John Muir. "The design and implementation of programming languages." Ph. D. Thesis, Oxford University 130 (1983). [Hulz83]: Van Hulzen, J. A., & Calmet, J. (1983). Computer Algebra Systems. Computer Algebra, 221–243. doi:10.1007/978-3-7091-7551-4_14  +[Hunt77]: R.B. Hunter et al. AB41.4.6 Some ALGOL 68 compilers, Algol Bulletin No. 41, July 1977 http://archive.computerhistory.org/resources/text/algol/algol_bulletin/A41/P46.HTM +[IFIP21]: IFIP Working Group 2.1 on Algorithmic Languages and Calculi https://ifipwg21wiki.cs.kuleuven.be/IFIP21/WebHome [Ilif61]: ILIFFE, J. K. (1961). "The use of the GENIE System in numerical calculation," Annual Review in Automatic Programming, Vol. 2, Pergamon Press DOI:10.1016/S0066-4138(61)80002-5 +[IRON77]: High Order Language Working Group. "Department of Defense Requirement for High-Order Computer Programming Languages-Revised IRONMAN." (1977). 5D. RESTRICTIONS ON VALUES [Jenk71]: Griesmer, J. H., & Jenks, R. D. (1971). SCRATCHPAD/1. Proceedings of the Second ACM Symposium on Symbolic and Algebraic Manipulation - SYMSAC ’71. doi:10.1145/800204.806266  [Jenk74]: Jenks, R. D. (1974). The SCRATCHPAD language. ACM SIGSAM Bulletin, 8(2), 20–30. doi:10.1145/1086830.1086834  [Jenk75b]: Griesmer, J. H., Jenks, R. D., & Yun, D. Y. Y. (1975). A SCRATCHPAD solution to problem #7. ACM SIGSAM Bulletin, 9(3), 13–17. doi:10.1145/1088309.1088314 @@ -5177,8 +5897,10 @@ https://core.ac.uk/download/pdf/236248615.pdf [Jenk84]: Jenks, R. Scratchpad II, an experimental computer algebra system, abbreviated primer and examples. IBM Thomas Watson Research Center, Yorktown Heights, NY (1984) [Jone78]: Jones, C.B. (1978). The meta-language: A reference manual. In: Bjørner, D., Jones, C.B. (eds) The Vienna Development Method: The Meta-Language. Lecture Notes in Computer Science, vol 61. Springer, Berlin, Heidelberg. doi:10.1007/3-540-08766-4_10 [Jone78b]: Henhapl, W., Jones, C.B. (1978). A formal definition of ALGOL 60 as described in the 1975 modified report. In: Bjørner, D., Jones, C.B. (eds) The Vienna Development Method: The Meta-Language. Lecture Notes in Computer Science, vol 61. Springer, Berlin, Heidelberg. doi:10.1007/3-540-08766-4_12 +[Jone99]: Jones, C.B. (1999). Scientific Decisions which Characterize VDM. In: Wing, J.M., Woodcock, J., Davies, J. (eds) FM’99 — Formal Methods. FM 1999. Lecture Notes in Computer Science, vol 1708. Springer, Berlin, Heidelberg. doi:10.1007/3-540-48119-2_2 [Kidd81]: Tracy Kidder, The Soul Of A New Machine. 1981 [Klee52]: S.C. Kleene. Introduction to Metamathematics, North-Holland Publishing Co. (1952) +[Knut64]: Donald Knuth, AB17.2.4: Man or boy?, Algol Bulletin No. 17, July 1964 http://archive.computerhistory.org/resources/text/algol/algol_bulletin/A17/P24.HTM [Knut73]: Knuth, Donald Ervin. A Review of "Structured Programming". Stanford, California: Computer Science Department, Stanford University, 1973. [Korn22]: Körner P, Leuschel M, Barbosa J, Costa VS, Dahl V, Hermenegildo MV, Morales JF, Wielemaker J, Diaz D, Abreu S, Ciatto G. Fifty years of Prolog and beyond. Theory and Practice of Logic Programming. 2022 Nov;22(6):776-858. [Kowa74]: Kowalski, Robert. Logic for problem solving. Department of Computational Logic, Edinburgh University, 1974. @@ -5200,6 +5922,13 @@ https://core.ac.uk/download/pdf/236248615.pdf [Levi82]: Bellia, Marco, Pierpaolo Degano, and Giorgio Levi. "The call by name semantics of a clause language with functions." Logic Programming 1 (1982): J82. [Li96]: Li, X. (1996). Program Sharing: A new implementation approach for Prolog. Programming Languages: Implementations, Logics, and Programs, 259–273. doi:10.1007/3-540-61756-6_90  [Ligh72]: James Lighthill, Artificial Intelligence: A General Survey (1972) http://www.chilton-computing.org.uk/inf/literature/reports/lighthill_report/p001.htm +[Lind74a]: C.H. Lindsey, AB37.4.2: Partial Parametrization, Algol Bulletin No. 37, July 1974 http://archive.computerhistory.org/resources/text/algol/algol_bulletin/A37/P42.HTM +[Lind74b]: C.H. Lindsey, AB37.4.3: Modals, Algol Bulletin No. 37, July 1974 http://archive.computerhistory.org/resources/text/algol/algol_bulletin/A37/P43.HTM +[Lind76]: C.H. Lindsey, AB39.3.1: Specification of Partial Parametrization Proposal, Algol Bulletin No. 39, February 1976 http://archive.computerhistory.org/resources/text/algol/algol_bulletin/A39/P31.HTM +[Lind76b]: C.H. Lindsey, AB39.4.2: Proposal for a Modules Facility in ALGOL 68, Algol Bulletin No. 39, February 1976 http://archive.computerhistory.org/resources/text/algol/algol_bulletin/A39/P42.HTM +[Lind78]: C. H. Lindsey and H. J. Boom, AB43.3.2: A Modules and Separate Compilation facility for ALGOL 68, Algol Bulletin No. 43, December 1978 http://archive.computerhistory.org/resources/text/algol/algol_bulletin/A43/P32.HTM +[Lind83]: C. H. Lindsey. AB49.1.1 Hans Bekic, Algol Bulletin No. 49, May 1983 http://archive.computerhistory.org/resources/text/algol/algol_bulletin/A49/P11.HTM +[Lind93]: C. H. Lindsey. 1993. A history of ALGOL 68. In The second ACM SIGPLAN conference on History of programming languages (HOPL-II). Association for Computing Machinery, New York, NY, USA, 97–132. doi:10.1145/154766.155365 [Lisk74]: Barbara Liskov and Stephen Zilles. 1974. Programming with abstract data types. In Proceedings of the ACM SIGPLAN symposium on Very high level languages. Association for Computing Machinery, New York, NY, USA, 50–59. doi:10.1145/800233.807045 [Lisk93]: Liskov, B. (1993). A history of CLU. ACM SIGPLAN Notices, 28(3), 133–147. doi:10.1145/155360.155367 [Lond78]: London, Thomas B., and John F. Reiser. "A UNIX™ Operating System for the DEC VAX-11/780 Computer." @@ -5214,11 +5943,14 @@ https://core.ac.uk/download/pdf/236248615.pdf [Mart76]: Martelli A., Montanari U. Unification in linear time and space: a structured presentation. Internal note IEI-B76-16, 1976. [Mart82]: Alberto Martelli and Ugo Montanari. 1982. An Efficient Unification Algorithm. ACM Trans. Program. Lang. Syst. 4, 2 (April 1982), 258–282. doi:10.1145/357162.357169 [Mart2008]: Martelli, A. (2008). The Seventies. In: Degano, P., De Nicola, R., Meseguer, J. (eds) Concurrency, Graphs and Models. Lecture Notes in Computer Science, vol 5065. Springer, Berlin, Heidelberg. doi:10.1007/978-3-540-68679-8_49 -[McBr69]: McBride, F. V., D. J. T. Morrison, and R. M. Pengelly. "A symbol manipulation system." Machine Intelligence 5 (1969): 337-347. +[Matt83]: Matthews, David Charles James. Programming language design with polymorphism. No. UCAM-CL-TR-49. University of Cambridge, Computer Laboratory, 1983. +[McBr69]: McBride, F. V., D. J. T. Morrison, and R. M. Pengelly. "A symbol manipulation system." Machine Intelligence 5 (1969): 337-347. +[McCa58]: J. McCarthy: An Algebraic Language for the Manipulation of Symbolic Expressions. MIT AI Lab., AI Memo No. 1, Cambridge, Sept. 1958. [McCa60]: John McCarthy. 1960. Recursive functions of symbolic expressions and their computation by machine, Part I. Commun. ACM 3, 4 (April 1960), 184–195. doi:10.1145/367177.367199 [McCa60b]: J. McCarthy, R. Brayton, D. Edwards, P. Fox, L. Hodes, D. Luckham, K. Maling, D. Park and S. Russell. LISP I Programmer's Manual. Computation Center and Research Laboratory of Electronics, Massachusetts Institute of California, March 1, 1960. https://www.softwarepreservation.org/projects/LISP/book/LISP%20I%20Programmers%20Manual.pdf [McCa61]: John McCarthy. 1961. A basis for a mathematical theory of computation, preliminary report. In Papers presented at the May 9-11, 1961, western joint IRE-AIEE-ACM computer conference (IRE-AIEE-ACM '61 (Western)). Association for Computing Machinery, New York, NY, USA, 225–238. doi:10.1145/1460690.1460715 [McCa62]: McCarthy, J., Abrahams, P. W., Edwards, D. J., Hart, T. P., & Levin, M. I. (1962). LISP 1.5 programmer's manual. MIT press. +[McCa64]: J. McCarthy, AB18.3.12: Definition of new data types in ALGOL x, Algol Bulletin No. 18, October 1964 [McCa74]: McCarthy, J. (1974). Artificial intelligence: a paper symposium. Artificial Intelligence, 5(3), 317–322. doi:10.1016/0004-3702(74)90016-2  [McCa78]: McCarthy J. History of LISP. In History of programming languages 1978 Jun 1 (pp. 173-185). [McDe84]: Drew McDermott et al., "The Dark Ages of AI: A Panel Discussion at AAAI-84," AI Magazine, Fall 1984, pp. 122-34. @@ -5253,6 +5985,8 @@ https://core.ac.uk/download/pdf/236248615.pdf [Muss74]: Ralph L. London and David R. Musser. 1974. The application of a symbolic mathematical system to program verification. In Proceedings of the 1974 annual conference - Volume 1 (ACM '74). Association for Computing Machinery, New York, NY, USA, 265–273. doi:10.1145/800182.810412 [Muss80a]: Musser, D. R. (1980). Abstract Data Type Specification in the Affirm System. IEEE Transactions on Software Engineering, SE-6(1), 24–32. doi:10.1109/tse.1980.230459  [Muss80b]: David R. Musser. 1980. On proving inductive properties of abstract data types. In Proceedings of the 7th ACM SIGPLAN-SIGACT symposium on Principles of programming languages (POPL '80). Association for Computing Machinery, New York, NY, USA, 154–162. doi:10.1145/567446.567461 +[Naur64]: P. Naur. Proposals for a new language, Algol Bulletin No. 18, October 1964 http://archive.computerhistory.org/resources/text/algol/algol_bulletin/A18/P39.HTM +[Naur66]: P. Naur. The form of specifications, Algol Bulletin No. 22, February 1966 http://archive.computerhistory.org/resources/text/algol/algol_bulletin/A22/P37.HTM [Naur78]: Naur, Peter. "The European side of the last phase of the development of ALGOL 60." In History of programming languages, pp. 92-139. 1978. [Neum23]: Von JOHANN v. NEUMANN, Zur Einführung der transfiniten Zahlen. Acta litt. Acad. Sc. Szeged X. 1(1923) p.199-208 [Newe75]: Newey, Malcolm C.. “Formal semantics of lisp with applications to program correctness.” (1975). @@ -5263,7 +5997,9 @@ https://core.ac.uk/download/pdf/236248615.pdf [O'Ke83]: R. A. O'Keefe. 1983. Prolog compared with LISP? SIGPLAN Not. 18, 5 (May 1983), 46–56. doi:10.1145/948249.948255 [Padg88]: Padget, Julian. "Three Uncommon Lisps." In First International Workshop on Lisp Evolution and Standardization. 1988. [PAL360]: PAL https://www.softwarepreservation.org/projects/lang/PAL/ +[Part84]: Partsch, H. (1984). The CIP Transformation System. In: Pepper, P. (eds) Program Transformation and Programming Environments. NATO ASI Series, vol 8. Springer, Berlin, Heidelberg. doi:10.1007/978-3-642-46490-4_27 [Pate76]: M. S. Paterson and M. N. Wegman. 1976. Linear unification. In Proceedings of the eighth annual ACM symposium on Theory of computing (STOC '76). Association for Computing Machinery, New York, NY, USA, 181–186. doi:10.1145/800113.803646 +[Perl78]: Alan J. Perlis. 1978. The American side of the development of ALGOL. History of programming languages. Association for Computing Machinery, New York, NY, USA, 75–91. doi:10.1145/800025.1198352 [Pett78]: Pettorossi, A. (1978). Improving memory utilization in transforming recursive programs. In: Winkowski, J. (eds) Mathematical Foundations of Computer Science 1978. MFCS 1978. Lecture Notes in Computer Science, vol 64. Springer, Berlin, Heidelberg. doi:10.1007/3-540-08921-7_89 [Pigo95]: Diarmuid Pigott, HOPL: an interactive Roster of Programming Languages, HOPE https://hopl.info/showlanguage.prx?exp=810 [Plot2000]: Plotkin, Gordon D., Colin Stirling, and Mads Tofte. "A brief scientific biography of Robin Milner." In Proof, Language, and Interaction, pp. 1-18. 2000. DOI:10.7551/mitpress/5641.003.0004 @@ -5292,14 +6028,17 @@ https://core.ac.uk/download/pdf/236248615.pdf [Rich74]: RICHARDS, Martin; EVANS JR, Arthur; MABEE, Robert F. The BCPL reference manual. MASSACHUSETTS INST OF TECH CAMBRIDGE PROJECT MAC, 1974. [Ritc93]: Ritchie, Dennis M. "The development of the C language." ACM Sigplan Notices 28.3 (1993): 201-208. [Robi76]: Robinson, Lawrence, and Oliver Roubine. Special: A specification and assertion language. Menlo Park, Ca.: Stanford Research Institute, 1976. +[Rosetta1]: Man or boy test in Pascal https://rosettacode.org/wiki/Man_or_boy_test#Pascal [Ross61]: ROSS, DOUGLAS T., and STEVEN A. COONS. INVESTIGATIONS IN COMPUTER-AIDED DESIGN. MASSACHUSETTS INST OF TECH CAMBRIDGE ELECTRONIC SYSTEMS LAB, 1961. [Ruti67]: Rutishauser, Heinz. "Description of ALGOL 60, volume 1, edited by Bauer, FL." (1967). [Ryde82]: Rydeheard, David Eric. "Applications of category theory to programming and program specification." (1982). [Ryde2002]: RYDEHEARD, D. E., & SANNELLA, D. T. (2002). A Collection of Papers and Memoirs Celebrating the Contribution of Rod Burstall to Advances in Computer Science. Formal Aspects of Computing, 13(3-5), 187–193. doi:10.1007/s001650200006 [Salu94]: Salus PH. A quarter century of UNIX. ACM Press/Addison-Wesley Publishing Co.; 1994 Dec. +[Same65]: K. Samelson, AB20.3.3. Functionals and functional transformations, Algol Bulletin No. 20, July 1965 https://archive.computerhistory.org/resources/text/algol/algol_bulletin/A20/P33.HTM [Sann82]: Sannella, Donald. "Semantics, implementation and pragmatics of Clear, a program specification language." (1982). [Sann94]: Sannella, Donald and Martin Wirsing. “Specification Languages” (1994). [Sann14]: D. Sannella, CV https://homepages.inf.ed.ac.uk/dts/cv.html +[Schu74]: S.A. Schuman, AB37.4.1: Toward Modular Programming in High-Level Languages, Algol Bulletin No. 37, July 1974 http://archive.computerhistory.org/resources/text/algol/algol_bulletin/A37/P41.HTM [Schw71]: Jacob T. Schwartz. Abstract algorithms and a set theoretic language for their expression. Computer Science Department, Courant Institute of Mathematical Sciences, New York University. Preliminary draft, first part. 1970-1971, 16+289 pages. This copy scanned from NYU Library, courtesy of Alex Kennedy-Grant. http://www.softwarepreservation.net/projects/SETL/setl/doc/Schwartz-Abstract_Algorithms-1971.pdf [Schw82]: Schwarz, J. (1982). Using Annotations to Make Recursion Equations Behave. IEEE Transactions on Software Engineering, SE-8(1), 21–33. doi:10.1109/tse.1982.234771  [Somm77]: Sommerville JF. An experiment in high-level microprogramming. University of St. Andrews (United Kingdom); 1977. @@ -5327,6 +6066,7 @@ https://core.ac.uk/download/pdf/236248615.pdf DOI:10.1023/A:1010000313106 [Strachey]: Catalogue of the papers and correspondence of Christopher Strachey https://archives.bodleian.ox.ac.uk/repositories/2/resources/2561 [Stro70]: H. R. Strong. 1970. Translating recursion equations into flow charts. In Proceedings of the second annual ACM symposium on Theory of computing (STOC '70). Association for Computing Machinery, New York, NY, USA, 184–197. doi:10.1145/800161.805164 +[Stro93]: Bjarne Stroustrup. 1993. A history of C++: 1979–1991. In The second ACM SIGPLAN conference on History of programming languages (HOPL-II). Association for Computing Machinery, New York, NY, USA, 271–297. doi:10.1145/154766.155375 [Thom90]: Lins, Rafael Dueire, and Simon J. Thompson. "Implementing SASL using categorical multi-combinators." Software - Practice and Experience 20, no. 11 (1990): 1137-1165. [TITAN]: Cambridge Atlas http://www.chilton-computing.org.uk/acl/technology/atlas/p011.htm [Teit74]: Teitelman, Warren. “The interlisp reference manual.” (1974). https://www.softwarepreservation.org/projects/LISP/interlisp/Interlisp-Oct_1974.pdf @@ -5363,11 +6103,16 @@ http://www1.cs.columbia.edu/~waltz/Papers/Understanding%20Line%20Drawing%20of%20 [Whit78]: Jon L White. 1978. LISP/370: a short technical description of the implementation. SIGSAM Bull. 12, 4 (November 1978), 23–27. doi:10.1145/1088276.1088280 [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 [Whit80]: White JL. Address/memory management for a gigantic Lisp environment or, GC considered harmful. InProceedings of the 1980 ACM Conference on LISP and Functional Programming 1980 Aug 25 (pp. 119-127). +[Wich76]: Wichmann, B.A. Ackermann's function: A study in the efficiency of calling procedures. BIT 16, 103–110 (1976). doi:10.1007/BF01940783 [Wijn66]: van Wijngaarden, Adriaan. Recursive Definition of Syntax and Semantics : (proceedings IFIP Working Conference on Formal Language Description Languages, Vienna 1966, P 13-24). Stichting Mathematisch Centrum. Rekenafdeling. Stichting Mathematisch Centrum, 1966. +[Wijn69]: A. van Wijngaarden (Ed.), Mailloux, B. J., Peck, J. E. L., & Koster, C. H. A. (1969). Report on the Algorithmic Language ALGOL 68. Numerische Mathematik, 14(2), 79–218. doi:10.1007/bf02163002 +[Wijn77]: A. van Wijngaarcien, B. J. Mailloux, J. E. L. Peck, C. H. A. Kostcr, M. Sintzoff, C. H. Lindsey, L. G. L. T. Meertens, and R. G. Fisker. 1977. Revised Report on the Algorithmic Language ALGOL 68. SIGPLAN Not. 12, 5 (May 1977), 1–70. doi:10.1145/954652.1781176 [Wilk92]: Wilkes, M. V. (1992). EDSAC 2. IEEE Annals of the History of Computing, 14(4), 49–56. doi:10.1109/85.194055  [Wirs95]: Wirsing, M. (1995). Algebraic specification languages: An overview. Lecture Notes in Computer Science, 81–115. doi:10.1007/bfb0014423 +[Wirt66]: Niklaus Wirth and C. A. R. Hoare. 1966. A contribution to the development of ALGOL. Commun. ACM 9, 6 (June 1966), 413–432. doi:10.1145/365696.365702 [Wirt76]: Wirth, Niklaus. "MODULA: a language for modular multiprogramming." Berichte des Instituts für Informatik 18 (1976). doi:10.3929/ethz-a-000199440 [Wood66]: Woodward, Philip M. List Programming in Advances in programming and non-numerical computation. 1966 +[Wood72]: Woodward, Philip M.. “Practical experience with algol 68.” Software: Practice and Experience 2 (1972) doi:10.1002/spe.4380020103 [Woze71]: J. M. Wozencraft and A. Evans. Notes on Programming Linguistics. M.I.T. Department of Electrical Engineering, February 1971 [Wray86]: Wray, Stuart Charles. Implementation and programming techniques for functional languages. No. UCAM-CL-TR-92. University of Cambridge, Computer Laboratory, 1986. https://www.cl.cam.ac.uk/techreports/UCAM-CL-TR-92.pdf [Wulf73]: Wulf, William Allan et al. "The design of an optimizing compiler." (1973).