mirror of
https://github.com/thegeneralist01/fphistoryru
synced 2026-01-10 14:10:24 +01:00
Update index.md
gc
This commit is contained in:
parent
4b37390548
commit
3e0961905f
1 changed files with 113 additions and 3 deletions
114
index.md
114
index.md
|
|
@ -1,6 +1,8 @@
|
|||
История применения и оценки функционального программирования
|
||||
=======
|
||||
|
||||
[Обновление 2024-01-11](#сколько-тысяч-слов--все-впустую)
|
||||
|
||||
[Обновление 2024-01-03](#декабрьский-апдейт)
|
||||
|
||||
[Обновление 2023-11-30](#у-меня-нет-памяти-а-я-должен-аллоцировать)
|
||||
|
|
@ -206,6 +208,12 @@
|
|||
- [Ограниченное могущество кучи](#ограниченное-могущество-кучи)
|
||||
- [Алголы 70-х](#алголы-70-х)
|
||||
- [Антиалголы 80-х](#антиалголы-80-х)
|
||||
- [Сколько тысяч слов – все впустую](#сколько-тысяч-слов--все-впустую)
|
||||
- [THE GARBAGE COLLECTOR HAS BEEN CALLED](#the-garbage-collector-has-been-called)
|
||||
- [_Миллиарды_](#миллиарды)
|
||||
- [Лисп-машина атакует!](#лисп-машина-атакует)
|
||||
- [GC considered harmful](#gc-considered-harmful)
|
||||
- [Похищение огня](#похищение-огня)
|
||||
- [Литература](#литература)
|
||||
|
||||
|
||||
|
|
@ -5076,7 +5084,7 @@ INTEGER p;
|
|||
z := sum(1, n, scalp);
|
||||
```
|
||||
|
||||
Что напоминает высокоуровневые обоекембриджские языки, но отличается экстремально тяжелым синтаксисом и тем, что все эти замыкания и передачи работают в одну сторону - вниз. Не только для функций, вернуть массив тоже не получится. Это, конечно не ФЯ, но очень амбициозный проект для 50-х годов. Память управляется автоматически и без сборщика мусора. Ну, пока кто-нибудь не сломает всю эту автоматику CPS-трансформацией, как Моррис. Имплементировать ALGOL 60 было не так легко, и обычно он не был имплементирован полностью [Naur78]. Но интересные для нашей истории фичи были имплементированы и довольно рано, в 1960-ом году [Dijk62]! ALGOL 60 - это не просто набор пожеланий, как CPL. И значит было известно из опыта, что можно и не отступать от набора пожеланий BCPL так далеко, как отступили в BCPL. Но можно ли было отступать еще меньше?
|
||||
Что напоминает высокоуровневые обоекембриджские языки, но отличается экстремально тяжелым синтаксисом и тем, что все эти замыкания и передачи работают в одну сторону - вниз. Не только для функций, вернуть массив тоже не получится. Это, конечно не ФЯ, но очень амбициозный проект для 50-х годов. Память управляется автоматически и без сборщика мусора. Ну, пока кто-нибудь не сломает всю эту автоматику CPS-трансформацией, как Моррис. Имплементировать ALGOL 60 было не так легко, и обычно он не был имплементирован полностью [Naur78]. Но интересные для нашей истории фичи были имплементированы и довольно рано, в 1960-ом году [Dijk62]! ALGOL 60 - это не просто набор пожеланий, как CPL. И значит было известно из опыта, что можно и не отступать от набора пожеланий CPL так далеко, как отступили в BCPL. Но можно ли было отступать еще меньше?
|
||||
Конечно, есть и другая, существенно менее интересная чем "работающий только вниз ISWIM с тяжелым синтаксисом", перспектива на ALGOL 60. Что это - Паскаль. Но действительно ли это Паскаль?
|
||||
С одной стороны, это даже меньше, чем Паскаль. Описанный в репорте ALGOL 60 - не то, что мы бы сегодня ожидали от языка программирования. Это скорее что-то вроде языка формул калькулятора. Средств для описания структур данных в нем нет. Так что авторам имплементаций Алгола приходилось разрабатывать свои средства, и делать ALGOL 60 с расширениями. Как AED-0 [Ross61], на котором Ричардс написал первый компилятор BCPL для бутстрапа [Rich2000], как имплементация ALGOL 60 от Королевского Института Радиолокации [Wood66], как SIMULA.
|
||||
|
||||
|
|
@ -5699,7 +5707,93 @@ Algol68C работал на VAX c 81-го года [ALGOL81], и хотя ег
|
|||
Да, транслировать эдинбургский ФЯ в Лисп - еще и не такая плохая идея. Все остальное готово в лучшем случае в той же степени или еще меньше. И похоже, что только трансляция в Алгол 68 производила бы код быстрее лиспового. Если б еще Algol 68RS был для имеющихся у разработчиков ФЯ машин. Если б только доделали вовремя сборщик мусора для Algol68C.
|
||||
Все эти победы (отсутствия) сборщика мусора над Бекичем, "языками восьмидесятых" и ФП, конечно, не должны быть ни для кого сюрпризом. Ны уже ознакомились с плачевной ситуацией с памятью в то время. Сегодня мы знаем, что со временем сборщики мусора начали работать нормально, хотя и не без проблем. Но видно ли из 1980-го года хотя-бы отблески этого счастливого времени где-то в далеком будущем? Конечно, к описываемому времени сборщики мусора как-то существуют уже два десятка лет. Но мы уже видели, каким жалким и условным бывает такое существование на примере лямбд. Символично, что после ухода из проекта Борна, руководить разработкой Algol68C стал сапожник без сапог, более известный как раз статьей о сборщике мусора - Крис Чейни (Chris J. Cheney). Давайте выясним, насколько плохо шла сборка мусора, когда функционального программирования не было.
|
||||
|
||||
ПРОДОЛЖЕНИЕ СЛЕДУЕТ
|
||||
Сколько тысяч слов – все впустую
|
||||
--------------------------------
|
||||
|
||||
> Как только мы определились со сборкой мусора, ее реальную реализацию можно было отложить, потому что мы писали только игрушечные программы.
|
||||
> Джон МакКарти, История Лиспа. [McCa78]
|
||||
|
||||
Первые лисперы не хотели управлять памятью вручную, но выбирали между счетчиками ссылок и сборщиком мусора. Выбрали сборщик потому, что хотели, чтоб `cons`-ячейка умещалась в одно слово. На IBM 704 это 36 бит. Адрес - 15 бит. Две группы по три бита - слишком мало для счетчика [McCa78]. Довольно удачное стечение обстоятельств для функционального программирования, которое не редко создает циклические ссылки. Но это удачное стечение обстоятельств, вероятно, не было критичным для появления ФЯ. Например, авторы SIMULA со временем отказались от подсчета ссылок в пользу сборки мусора потому, что проводили эксперименты и сравнивали производительность сочетания подсчета ссылок со сборщиком мусора для сборки циклов в куче и компактифицирующего сборщика. По крайней мере вспоминают про это [Dahl78]. Но, наверное, была какая-то польза от того, что лисперы начали работать над сборкой мусора раньше.
|
||||
Сделав выбор между счетчиком ссылок и сборщиком мусора, лисперы отложили имплементацию сборщика мусора потому, что писали игрушечные программы, и сборка мусора пока что не требовалась.
|
||||
|
||||
### THE GARBAGE COLLECTOR HAS BEEN CALLED
|
||||
|
||||
Ко времени первой публичной демонстрации Лиспа в 60-ом или 61-ом году сборщик уже работал. И был продемонстрирован, хотя это и не планировалось. Во время репетиции он не включался, но репетиция заняла достаточно памяти, чтоб сборщик мусора начал работать во время демонстрации и работал все оставшееся время выделенное для нее, печатая статистику [McCa78]. Трудно сказать, почему лисперы не хотели показывать свое главное, по мнению Тернера [Turn12], достижение. Но, к счастью, все кончилось хорошо.
|
||||
В выводе статистики сборки сборщик мусора уже гордо именуется сборщиком мусора, но в первой статье о Лиспе [McCa60] его еще стесняются так называть. МакКарти там слишком серьезный, но это скомпенсировано другими лисперами в других статьях.
|
||||
МакКарти пишет, что процесс "рекламации" занимает "несколько секунд". Это так, когда памяти 8192 слов. Но ко времени демонстрации сборщика это уже 32768 слов и процесс занимает по крайней мере четыре раза по "несколько" секунд. Не очень хорошо. Главная проблема [Wilk92] сборщика МакКарти: даже если живых объектов почти и не осталось к моменту сборки - все равно нужно обходить всю кучу, время работы сборщика зависит от размера кучи.
|
||||
И сторонники подсчета ссылок практически с самого начала критикуют [Coll60] метод МакКарти за то, что время работы сборщика не зависит от того, сколько памяти освобождается. Но то, что время работы не зависит от того, сколько памяти освобождается - это даже хорошо. Плохо в нем то, что время работы не зависит только от количества живых объектов.
|
||||
Получается, что рост памяти, которому мы так радовались на протяжении этой главы, несет не только новые возможности, но и новые вызовы. До следующей сборки проходит все больше времени, в которое можно уместить уже не только демонстрацию (но не вместе с её репетицией), но уже и какую-то более интересную работу. Но и перерыв в работе становится все более мучительным.
|
||||
Конечно, для функционального программирования совсем не подходит такой взгляд на проблему. ФП код аллоцирует достаточно много, чтоб быстро занять память. ФП может извлекать пользу из роста памяти, если время сборки не растет так быстро как память. Но лисперы МТИ пока не собираются функционально программировать. И если отказаться от ФП - можно придерживаться стековой дисциплины, избежать аллокации массы короткоживущих объектов в куче. Так что Гринблатт и другие делают MacLISP, который использует преимущественно стек. И если аллоцировать в куче поменьше, переиспользовать структуры данных, изменяя их на месте, то можно сохранять эту иллюзию решения, отодвигать сборку в будущее, а там может и работа уже закончена и можно не собирать вовсе.
|
||||
Такой подход маклисперов делает маловажной для них и другую проблему сборщика МакКарти, которая для ФЯ очень важна. Раз уж работа функциональной программы сводится к аллокации в такой значительной степени - аллокация должна быть быстрой. И получение памяти из списка свободных ячеек - не самый быстрый способ. Маклиспер просто аллоцирует на стеке - это быстро. Второй недостаток сборщика МакКарти особенно обостряется в сочетании с третьим.
|
||||
Первоначальные аллокатор и сборщик МакКарти не имеют этого недостатка потому, что оперируют только парами. Так что каждая ячейка в списке свободных подходит. Сегодня кажется само собой разумеющимся, что в языке со сборщиком мусора можно аллоцировать не только объекты с двумя полями, но когда-то было иначе. В статье про ленивый эвалуатор [Hend76] как раз про такую кучу только для пар и говорится как про само собой разумеющуюся. Еще в начале 80-х это была важная и распространенная разновидность сборщиков [Cohe81].
|
||||
Но, если вы не хотите в своем ФЯ использовать типы данных с представлением в памяти, как у композитных типов МакКарти, то вам нужен другой сборщик. И лучше этого не хотеть.
|
||||
Конечно, со временем объекты кучи разных размеров захочет получить главный заказчик MACLISP-фич Мозес. И его поддержат менее важные заказчики - создатели Антипрологов Хьюит и Сассман [Feni71]. Один из авторов PAL Эванс ознакомит их с работами имплементатора PAL Ричардса и работами над сборщиками мусора для Алгола 68. Но не с эдинбургскими работами над такими сборщиками. А Поплстоун претендует [Popp2002] на написания одного из первых таких сборщиков. Но первый контакт маклисперов с разработчиками сборщиков для Алгола скорее всего состоялся раньше и по другой причине, но об этом позже.
|
||||
Так вот, для интересующихся аллокацией объектов разных размеров сборщик МакКарти еще хуже. Поиск подходящего куска памяти требует больше времени. Память фрагментируется и используется менее эффективно. Уоррен считал, что сборщик мусора определенно создает больше проблем, если нужно аллоцировать объекты разных размеров. И потому для его имплементации Пролога еще важнее, чем для Лиспа, больше использовать стек и меньше использовать сборщик мусора [Warr77].
|
||||
Можно предположить, что у имплементатора ФЯ нет никакой надежды дождаться помощи от маклисперов и более естественный его союзник - имплементатор объектно-ориентированного языка, который в первое время почему-то не хотел использовать стек, где это возможно. Мы уже выяснили, что у этого нежелания были серьезные негативные последствия в виде непрактичности "языка восьмидесятых" SIMULA 67 и плохого впечатления от языков со сборкой мусора вообще. Но у этого есть и положительная сторона. Для разработчиков таких ООЯ тоже важна скорость аллокации и нет надежды сделать все что нужно до исчерпания памяти.
|
||||
Предположить можно, это логично. Но такая логика не может предсказать действия маклисперов, которые изобрели подходящий для ФЯ сборщик мусора. Сборщик, полностью или частично решающий все проблемы сборщика МакКарти, они изобрели, чтоб решить совсем другую проблему.
|
||||
|
||||
### _Миллиарды_
|
||||
|
||||
Памяти нужно все больше, и физическая память растет недостаточно быстро. Лисперы готовятся к переезду на машину с виртуальной памятью - пишут MacLISP для Multics. И это обостряет еще одну проблему сборщика МакКарти: нелокальность ссылок. Освободившиеся `cons`-ячейки находятся все дальше друг от друга. Пары, с которыми ведется работа в данный момент, занимают одну страницу с парами, которые не скоро понадобятся и содержат ссылки на пары в других страницах. Переход к ним заставит читать данные с диска!
|
||||
Мински изобретает решение проблемы: нужно обходить только живые пары в куче и сериализовать их в файл. После этого файл можно десериализовать в память и куча станет удобной компактной кучкой. Да, в наши дни сохранение сессии REPL в файл не особенно ассоциируется со сборкой мусора, но лисперы считают это изобретением копирующего сборщика мусора.
|
||||
Память тем временем еще выросла. Уже можно копировать прямо в неё, предлагают [Feni69] Роберт Фенихель (Robert Fenichel) и Джером Иохельсон (Jerome Yochelson). В старые времена, рассказывают они, сборка мусора была нужна для переиспользования небольшого адресного пространства. Сегодня, в ревущем 1968-ом адресное пространство практически безгранично. На Multics в него поместятся _миллиарды_ `cons`-ячеек (выделено Фенихелем и Иохельсоном). Лисп-система может работать "почти бесконечно". Но, конечно, производительность будет деградировать из-за нелокальности ссылок. Поэтому, делают вывод Фенихель и Иохельсон, современный сборщик мусора не ищет свободное место, а дефрагментирует кучу. Сборку надо начинать не при исчерпании свободного места, а реагировать на замедление работы. Ведь сборка никогда не необходима, а только желательна чтоб ускорять работу, когда фрагментация зашла слишком далеко. И уж конечно сканировать всю кучу, как придумал МакКарти, практически неосуществимо. Обходится только живая её часть. И небольшая живая часть может быть еще один ориентир для начала сборки. Например, можно ориентироваться на короткий стек. Короткий стек, вероятно, удерживает мало объектов - самое время копировать. Копирование из памяти в память означает, что нужно в два раз больше памяти, но это не беда, памяти полно. Но полно ли?
|
||||
Можно только позавидовать маклисперам, которые писать в ФП стиле не собираются, ведь даже первый компилятор ФЯ, написанный на ФЯ и использующий их сборщик мусора, аллоцирует с такой скоростью, что "почти бесконечность" 32бит адресного пространства закончится до конца рабочего дня. Даже на совсем не быстрых машинах того времени.
|
||||
Само изобретение Фенихеля и Иохельсона и делает эту скорость возможной, да и вообще делает возможным функциональное программирование. Для ФП очень полезно, что можно аллоцировать простым прибавлением числа, как при аллокации на стеке, а не выискивая подходящий свободный кусок памяти, как нужно делать при использовании сборщика МакКарти. И, конечно, при такой-то скорости аллокаций короткоживущих объектов в ФП очень полезно то, что нужно обходить только долгоживущие. Типичный ФП код аллоцирует гораздо больше короткоживущих объектов, чем долгоживущих. Это означает, что добавляя память, можно сделать цену сборки меньше и меньше. Копирование живых объектов занимает примерно столько же времени, а освобождает все больше памяти.
|
||||
Изобретение, правда, требует некоторой доработки напильником практичности. Алгоритм придуманный лисперами не совсем подходит для практического использования из-за того, что требует аллоцировать память на стеке во время обхода объектов кучи. Фенихель и Иохельсон пишут, что можно этого избежать с помощью разворота указателей [Scho67], хотя сами этого не делают. Но проблему можно решить проще и сделать алгоритм быстрее. Наш знакомый алголист из предыдущей главы Крис Чейни придумал в 1970-ом году другой алгоритм копирования [Chen70]. Он обходит граф объектов кучи в ширину, используя уже скопированные объекты в качестве очереди для их обхода. Да, обход в ширину производит не такую хорошую локальность ссылок, как обход в глубину, но комбинированный обход, копирующий детей объекта вместе с ним, в основном решает эту проблему. Но борьба сторонников этих двух разных обходов будет продолжаться еще какое-то время.
|
||||
Получившийся практический полезный копирующий сборщик обычно называют именем Чейни. Лисперы называют его "алгоритм Мински-Фенихеля-Иохельсона-Чейни-Арнборга" [Bake77]. Арнборг (Stefan Arnborg) - это имплементатор SIMULA 67 для PDP-10, который использовал в своей имплементации и несколько доработал этот сборщик. Сам Чейни-то, как мы помним, оказался слишком практичным, чтоб имплементировать сборщик для своего Algol68C.
|
||||
Арнборг как раз из тех имплементаторов ООЯ, которые приветствуют [Arnb72] перенос всей сложности из аллокатора в сборщик мусора, но мало что придумали для этого раньше лисперов, не очень этим интересовавшихся в описываемое время.
|
||||
В статье Фенихеля и Иохельсона очень нехватает экспериментов и измерений, проверяющих их идеи, но этого не хватает во многих статьях о которых мы еще расскажем в этой главе. Маклисперы пишут в основном о том, что планируют сделать, а не о том, что сделано. Но так или иначе идеи были проверены разными имплементациями Лиспа. В MULTICS MACLISP сделали копирующий сборщик [Moon74]. Это направление бегства с PDP-10 было быстро заброшено и мало что написано про результаты. Но впечатление о том, с чем столкнулись Лисперы МТИ, можно составить по более позднему опыту имплементаторов Interlisp на VAX [Bate82]. И они, испытав сборщик Чейни, сомневаются в его применимости для машин с виртуальной памятью. Если куча не умещается в физическую память - секунды сборки становятся минутами.
|
||||
Алголисты больше пишут о том, что сделано и публикуют какие-то измерения. Уже летом 71-го они проделали какие-то опыты, которые показали, что, возможно, копирующий сборщик не очень хорошая идея, когда надо работать на машине с виртуальной памятью и физической памяти не много. Статья [Baec72b] опубликована в конце 72-го.
|
||||
Возможно, что эта разность подходов повлияла на то, что к началу 80-х лисперы опубликовали больше всего материалов по сборке мусора, а алголисты заняли только второе место, по оценке Коэна в его обзоре сборщиков [Cohe81].
|
||||
Да, копирующий сборщик приводит кучу в состояние, желательное на машине с виртуальной памятью. Но приводит крайне неудачным для машины с виртуальной памятью путем. В процессе сборки нужно пройтись по значительной части кучи, поднять в физическую память с диска множество страниц и, чтоб освободить для них место, задвинуть на диск множество страниц из физической памяти. При большом количестве долгоживущих объектов это не намного лучше подхода МакКарти и может быть даже хуже. Потому, что копирующий сборщик требует в два раза больше памяти для сборки.
|
||||
С тем, для чего его придумали лисперы копирующий сборщик не справляется. Но он не полностью бесполезен для функционального программирования. Если вся куча находится в физической памяти, то он работает достаточно хорошо, хотя все еще делает много ненужной работы, обходя долгоживущие объекты чаще чем нужно. Но делает меньше ненужной работы, чем сборщик МакКарти. Не говоря о прочих его преимуществах, важных для имплементации ФЯ. Так что нужно просто подождать лет 15 до того времени, когда физической памяти будет достаточно. Но в МТИ, как мы помним, хотят запускать большие программы на Лиспе уже в начале 70-х. При этом надеются, что смогут для этого использовать машины с большим адресным пространством и диском, но небольшой быстрой памятью [Gree74]. И у лисперов МТИ есть кое-какие идеи о том, как можно исправить копирующий сборщик.
|
||||
|
||||
### Лисп-машина атакует!
|
||||
|
||||
> Следование ссылкам переадресации займет некоторое время.
|
||||
> К. Хьюит, Х. Либерман [Lieb80]
|
||||
|
||||
Не обязательно делать паузу на всю сборку всей кучи. Можно делать сборку параллельно, как предложил Стил [Stee75b] или хотя-бы инкрементально, как предложил МТИ-лиспер Бейкер (Henry G. Baker) [Bake77]. Сборщик Бейкера тоже копирующий, и проблема двойного потребления памяти при сборке еще усугубляется: сборка идет всегда и сборщику нужно тянуть в физическую память с диска все эти ненужные мутатору страницы. Компактность рабочей области хуже, рабочий набор больше. Есть и другие проблемы, особенно для ФЯ. Алгоритм Бейкера - из тех, которые заставляют больше платить за чтение объекта по ссылке, а не за изменение ссылки. Для доступа к объекту в куче нужно перейти по ссылке два раза. Естественно, для ФЯ предпочтительнее, когда нужно больше платить за изменение. Лисперы не собираются имплементировать этот метод сборки для Multics MacLISP, или какой-нибудь другой обычной машины. Только для Лисп-машин [Gree77]. И в 70-е все только собираются и собираются.
|
||||
Но самое главное - это то, что принципиальная проблема все равно не решается. Сборщик делает ненужную работу, регулярно обходя граф долгоживущих объектов, на смерть которых нет особой надежды. Если объект кучи быстро не помер - он проживет долго. Но копирующий сборщик Бейкера или Чейни может быть частью более сложного сборщика, который действительно будет работать.
|
||||
Если работать с одной большой кучей слишком тяжело, то почему бы не работать с множеством маленьких кучек? Алголист Беккер (H. D. Baecker) предложил [Baec72] добавить в Алгол 68 фичу из PL/I - возможность для программиста выбирать в какую арену аллоцировать. В отличие от PL/I, в Алголе 68 с этими аренами работал бы сборщик мусора. Явная работа программиста с аренами, конечно, нормальное решение для "языка семидесятых", но для ФЯ хотелось бы чего-то более автоматического и менее явного.
|
||||
Арнольд Рошфилд (Arnold Rochfeld) из Эдинбургского Университета предложил [Roch71] собирать копирующим сборщиком общую кучу (т.е. слишком много) и окружение блока кода (т.е. слишком мало) при выходе из этого блока (т.е. слишком часто). Автор подозревает, что работать сборщик будет слишком часто и предлагает аннотации для блоков, которые бы указывали, нужно ли собирать при выходе из такого блока. Статья получена издательством в октябре 69-го, но опубликована только в декабре 71-го года.
|
||||
Придумать, что нужно собирать мусор только в части кучи легко. Сложнее придумать, как это сделать, если между этой частью кучи и оставшейся могут быть ссылки. Для кого решение этой проблемы важнее всего в МТИ? Правильно, для антипрологосторителя Хьюита, которому так просто не обойтись стеком для всего короткоживущего, как прочим пользователям MacLISP-диалектов. Питер Бишоп (Peter B. Bishop), пишущий в МТИ диссертацию под руководством Хьюита, ссылается на эти работы и предлагает [Bish75] два решения. Можно делать ссылки между разными кучами двойными, ссылками на ссылки из одной кучи в другую. Можно поддерживать для сборщика мусора список ссылок на поля или объекты, в которых есть ссылки из одной кучи в другую. Второй вариант, конечно, лучше для ФЯ, но Бишоп, разумеется, выбирает первый. Да что не так с лисперами МТИ и этими их ссылками на ссылки? Почему они так хотят биться о память? Во всем этом виноваты Лисп-машины. Помните про поддержку этих ссылок на ссылки в них? Поддержку сборки мусора в части кучи или в одной из многих куч тоже планируют делать для Лисп-машин [Gree74] [Gree77]. Не игнорировать же фичу Лисп-машины? Надо пользоваться. Лисперы в МТИ, как мы помним, теперь хотят делать что-то только для Лисп-машин.
|
||||
Но 70-е годы подошли к концу и только в последний год десятилетия, 26 апреля 1980 выходит отчет [Lieb80] Хьюита и Генри Либермана (Henry Lieberman) в котором наконец-то обозначена концепция сборщика мусора, который обладает хорошей локальностью и быстро освобождает много места. То, что и нужно для функционального программирования.
|
||||
Маклисперы и Уоррен решают проблему аллокации короткоживущих объектов с помощью стека. Но, пишут Хьюит и Либерман, стековая дисциплина не совместима с решением FUNARG-проблемы и объектно-ориентированным программированием. Они предполагают, что не смотря на эту несовместимость, подавляющее большинство объектов в ООЯ и ФЯ все равно короткоживущие. Важно, чтоб размещение короткоживущих объектов в имплементациях таких языков было быстрым. Цель Либермана и Хьюита - сделать так, чтоб аллокация временных структур не была сильно медленнее аллокации на стеке, чтоб программист не наказывался рантаймом за написание более понятных программ. Как мы помним, ООП - это ответ Хьюита на Пролог и логическое программирование, а FUNARG-проблемой и ФП вообще к этому времени заинтересовался его коллега Сассман. Хьюит хочет освободиться от ограничений стековой дисциплины, но сохранить разумную эффективность.
|
||||
И у Либермана с Хьюитом есть идея, как уменьшить стоимость работы сборщика с короткоживущими объектами настолько, что сборщик мусора будет соперничать со стеком.
|
||||
Кучу надо разделять на части по возрасту объектов. Не нужно тратить время на бессмысленный обход объектов, которые уже пережили несколько сборок и, судя по всему, помирать в ближайшее время не собираются. Вместо этого нужно сначала работать с теми частями кучи, в которых располагаются молодые объекты. Обход такой области и копирование из нее быстро закончится, ведь большинство объектов долго не живут. Много места освобождается очень быстро.
|
||||
Так что больше нет куч A и B и структур для обозначения ссылок из A в B и из B в A. Есть куча 1 со старыми объектами и куча 2 с молодыми и ссылки молодых на старые - самые обычные. Их не нужно никак отслеживать и обозначать.
|
||||
На этом общепризнанные сегодня идеи заканчиваются и начинаются своеобразные. Некоторое своеобразие довольно безобидное. Например, поколения нумеруются не в том порядке, в каком их нумеруют сегодня. Но много необычных идей совсем не так безобидны. Поколения нумеруются не в том порядке, в каком объекты движутся по ним, переживая сборки, а в порядке создания поколений. Да, поколения постоянно создаются, их должно быть много. Как минимум, два самых молодых поколения должны содержать небольшую долю долгоживущих объектов. Потому, что для сборки самого молодого поколения n нужно обходить еще и поколение n-1. Дело в том, что если ссылки между поколениями "назад" во времени теперь самые обычные, вместо последовательно двойных, то для учета ссылок "вперед" во времени строятся структуры еще хуже, чем решил строить Бишоп. Казалось бы, куда еще хуже? Но хуже всегда может быть. Чтоб можно было ограничится обходом только одного поколения более старого, чем собираемое, все ссылки "вперед" могут быть только в соседнее поколение. N поколений означают (n-1)-кратную максимальную косвенность таких ссылок. Не только чтение обходится недешево, но и изменение ссылок может требовать создания множества объектов во множестве поколений для многократной переадресации.
|
||||
Но и это еще не все. Либерман с Хьюитом хотят использовать еще и специальную технику, которая увеличивает число таких ссылок. Сегодня есть такая техника уменьшения числа ссылок между поколениями - повышение. Новый объект, на который ссылается старый объект помещают в поколение старого объекта. Хьюит и Либерман планируют делать наоборот, понижать старый объект, перемещая его в молодое поколение, сборку которого он, конечно, переживет. И все ссылки на него из остальных старых объектов теперь превратились во множество скачков по памяти. Справедливости ради, в отчете пишут, что, возможно, стоит рассмотреть и повышение, но как и в случае со способами обозначить ссылки между поколениями у Бишопа, выбирают не то что нужно.
|
||||
Все это пока что только концепция. Хьюит с Либерманом не проверили на опыте гипотезу поколений о том, что большинство объектов умирают молодыми, не проверили насколько хорошо работают их идеи об организации ссылок между поколениями. Ну, хотя-бы сформулировали ясную цель для имплементаторов ФЯ.
|
||||
Хьюит и Либерман "говорили с Дэвидом Муном", который имплементирует сборщик мусора для Лисп-машин. Имплементация такого сборщика шла. Как шла и имплементация инкрементального сборщика Бейкера без поколений. Но в 70-е так никуда и не пришла.
|
||||
Не смотря на то, что в главном центре Лисп-разработки все работы над сборщиками мусора были для Лисп-машин, эти сборщики задержались существенно сильнее, чем Лисп-машины. Ранние Лисп-машины в МТИ не имели сборщика мусора много лет, а когда получили инкрементальный, пользователи предпочитали его отключать [Stee96]. Даже Хьюит и Либерман, изобретающие принципиальное решение проблемы, рассматривают отсутствие сборки как реальную альтернативу. И дело не только в Лисп-машинах. Имплементаторы Interlisp с копирующим сборщиком для обычного железа рекомендовали сборщиком мусора не пользоваться [Bate82]. Для нас такой итог разработки сборщиков мусора лисперами выглядит необычно.
|
||||
Сегодня не так просто сказать, насколько ненормальным и неправильным является то, что для имплементации Алгол 68 никак не могут сделать сборщик мусора. Какой код писали на Алголе 68? Может, все в порядке, сборщик мусора и не нужен? Ну а как насчет Лиспа, которому никак не могут сделать сборщик мусора? Как это вообще работает?
|
||||
|
||||
### GC considered harmful
|
||||
|
||||
Новый план лисперов идентичен их плану для первой демонстрации Лиспа, состоявшейся за пару десятков лет до того: работаем, пока память не кончится. Прошла пара десятилетий, а имплементация работающего сборщика все откладывается. Но что делать, когда память закончится? Ведь есть уже несколько неигрушечных программ. И не закончится ли память довольно быстро?
|
||||
Не обязательно. Лисперы стараются писать программы на диалекте MacLISP для Лисп-машин так же, как старались писать на всех прочих диалектах MacLISP - используя по возможности стек. Большинство программ, таких как компиляторы и текстовые редакторы были написаны так, чтоб избегать аллокации, явно переиспользовать структуры данных на месте. MacLISP делали "языком семидесятых" и потому разработка на нем EMACS для MULTICS и Лисп-машин - это не такой, скажем, "смелый" проект, как, например, попытка Netscape написать браузер на Java. Хотя и кажется таким на первый взгляд.
|
||||
После всех этих усилий по сокращению аллокаций, размера адресного пространства Лисп-машин хватало, а виртуальная память работала достаточно хорошо, чтоб Лисп-машиной можно было пользоваться дни. И когда эти в лучшем случае дни, а в не самом лучшем случае - один рабочий день проходят и место подходит к концу, нужно сохранить образ системы. Включить сериализацию кучи на диск и идти домой отдыхать. Чтоб на следующий день с новыми силами вернуться на работу и загрузить сохраненный образ, сделав таким образом сборку мусора а-ля Мински [Stee96].
|
||||
Да, с программой на функциональном языке так не поработаешь. И не все программы на Лиспе написаны как Гринберговский EMACS. Есть очень важная для лисперов программа, которая не так сильно отличается от компилятора ФЯ. MACSYMA аллоцирует 36Кб в секунду [Fode81]. Достаточно, чтоб заполнить адресное пространство Лисп-машины за полчаса работы. Получается не очень продуктивный рабочий день.
|
||||
Но адресное пространство-то можно еще увеличить, а где хранить столько страниц? Прогресс не стоит на месте, утешают себя лисперы, можно будет использовать дешевые средства хранения для совсем старых страниц. Например, VideoDisc. В этих страницах все равно почти гарантированный мусор, но если вдруг среди этих гигабайтов мусора затеряется уж очень долгоживущий и невостребованный объект, то когда он понадобится - система просто подождет, пока диск не будет найден и нужная страница считана. За ночь или даже за выходные, пока оператор Лисп-машины отдыхает, эти архивы страниц можно затягивать в гигантскую память специальной машины, выделенной для сжатия лисповых куч.
|
||||
Все это звучит не очень привлекательно. Что если Лисп-машины просто не будут использовать? Об этом Лисп-машинисты, уже поставившие будущее Лиспа на то, что программисты будут платить за компьютер в десятки и сотни раз больше только для того, чтоб использовать Лисп, старались не думать. Возможно, будет даже ниша для такого бизнеса, фантазирует [Whit80] важный имплементатор Лиспов Уайт. Машина будет машиной и в другом смысле, перемещаться по городу от офиса одного из многочисленных пользователей Лисп-машин к другому, как передвижной пылесос начала XX века, подключаться к их сетям и сжимать кучи за кучами.
|
||||
Эта леденящая душу антиутопия, в которой никакого ФП, разумеется, не могло бы быть, вычеркнута из истории Лиспа. В черновой версии статьи [Stee96] Стила и Гэбриела есть пометка авторов о том, что надо бы рассказать про неё. Но пометка так и осталась только пометкой. Вместо того, чтоб познакомить читателей с этим пиком лисповой мысли 70-х Стил и Гэбриел предпочитают объяснить еще несколько лисповых шуточных акронимов. Мы-то стараемся читателей не подвести.
|
||||
Но на рубеже десятилетий этот ужас был всегда рядом, не давал себя забыть разработчикам и имплементаторам сборщиков мусора для Лиспа. И Хьюит с Либерманом и разработчики Interlisp ссылаются на статью Уайта некритически. Десятилетие безуспешных попыток освоить виртуальную память деморализовало их.
|
||||
В результате такого потерянного десятилетия в разработке сборщиков мусора в 1980-ом имплементаторы ФЯ не могли позаимствовать у лисперов ничего готового из того, чего не было в 1970-ом. Практически полезный, подходящий для ФП, Лиспа и для обычных и даже для Лисп-машин сборщик с поколениями изобретут не лисперы, а имплементаторы другого языка, который в 70-е годы вовсе сборку мусора не использовал.
|
||||
|
||||
Похищение огня
|
||||
--------------
|
||||
|
||||
Времена, когда функционального программирования не было, подходят к концу. А вместе с ними и нулевая часть нашей истории. В которой мы попытались разобраться что было, когда функционального программирования не было. И почему того, что уже было еще не было достаточно для того, чтоб функциональное программирование было.
|
||||
Могло ли функциональное программирование появится раньше? Почти наверняка не могло в 60-е годы. Но в 70-е годы история ФП могла сложится иначе, при более удачном, но крайне маловероятном стечении обстоятельств. Если бы герои этой истории больше интересовались работами друг друга и внимательнее слушали доклады своих коллег. Если бы авторы PAL использовали для испытания своих последующих изобретений PAL. Если б те, кто хотел делать ФЯ в 70-е, имели доступ к таким же дорогим компьютерам, к которым имели доступ те, кто хотел делать ФЯ в 60-е. Если б лисперы МТИ захотели делать ФЯ раньше. Если бы разработки Йорктаун Хайтс были более открыты.
|
||||
Уоррен и алголисты могли бы сделать компиляторы функциональных языков, отличающихся от языков эдинбургской программы гораздо меньше, чем нам было бы удобно отличать.
|
||||
Избежало бы это более раннее функциональное программирование ловушку PDP-10? Могло бы выиграть от ИИ-бума? Было бы оно уничтожено ИИ-зимой? Ну, это был не последний ИИ-бум и не последняя ИИ-зима, так что мы еще увидим как и то и другое влияет на ФП.
|
||||
Конечно, не всегда обстоятельства складывались неудачно, не все возможности были упущены. Участники Эдинбургской программы могли бы и не оказаться в Эдинбурге и его окрестностях и продолжить обмениваться идеями со скоростью переизобретателей продолжений. Могли бы не иметь доступа и к тем машинам, к которым имели. Милнер мог бы увлечься резолюционизмом или ООП. Бурсталл мог бы не разговориться с незнакомцем в книжном магазине. Мики мог бы не забросить генетику. Поплстоун мог бы не спасти паттерн-матчинг. Функциональное программирование могло бы появиться и еще на десяток лет позже, дождавшись интернета и компьютеров необходимой мощности доступных даже хоббистам. Вырасти в 90-е на руинах языков уравнений вроде Axiom, и обломках Лиспов, выкинутых на мороз после провалившейся коммерциализации. Или не появиться вовсе.
|
||||
60-е и 70-е годы произвели много важных идей о функциональном программировании, но были не лучшим временем для имплементаторов этих идей. Идеи этих двадцати лет имеют определяющее влияние. Но влияние имплементаций - серьезно ограничено. Двадцатилетняя история разработки какого-нибудь сборщика мусора в 1980 году мало что значит. Потому, что за двадцать лет из этих двадцати мало что было сделано. Но сложно в этом винить тех немногих, кто имел к доступ компьютеру с памятью, как у сегодняшнего микроконтроллера. Достаточный доступ хотя-бы для того, чтоб написать 1KLOC за год, запуская компилятор не чаще раза в день.
|
||||
Новые, более доступные машины с большой памятью изменили это навсегда. Нужно констатировать, что микрокомпьютеры и интернет в 80-е и далее так увеличили производительность и связность имплементаторов, что наработки, которые копили до того десятилетиями были воспроизведены и улучшены за годы и даже месяцы. Жалкие построения 60-х и 70-х были сметены следующими, все большими волнами воспроизводителей и переизобретателей.
|
||||
Да, имплементаторы ФЯ пока что не умеют как следует использовать новую большую память, но это уже не остановит имплементацию. В последнюю зиму семидесятых в Эдинбурге, на новой машине с большой памятью, уже идет работа над первым компилятором функционального языка.
|
||||
Но не все будет хорошо и легко для имплементаторов ФЯ в 80-е. Их ждут и новые испытания. Посещавший SRI Фурукава Коити (Furukawa Koichi) уже нашел там ксерокопию ксерокопии ксерокопии распечатки FORTRAN-исходников Марсельского интерпретатора Пролога. Это событие не окажет влияние на то, быть функциональному программированию или не быть. Это уже решено. Функциональное программирование обречено состояться. Но это событие окажет решающее влияние на то, какие функциональные языки используются сегодня.
|
||||
|
||||
Литература
|
||||
==========
|
||||
|
|
@ -5717,6 +5811,7 @@ Algol68C работал на VAX c 81-го года [ALGOL81], и хотя ег
|
|||
[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
|
||||
[Arnb72]: Stefan Arnborg. 1972. Storage administration in a virtual memory Simula system. BIT 12, 2 (Jun 1972), 125–141. doi:10.1007/BF01932808
|
||||
[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
|
||||
|
|
@ -5726,11 +5821,15 @@ Algol68C работал на VAX c 81-го года [ALGOL81], и хотя ег
|
|||
[Baba81]: Babaoglu, Özalp and William N. Joy. “Converting a swap-based system to do paging in an architecture lacking page-referenced bits.” TR 81-474 October 1981.
|
||||
[Back59]: J. W. Backus. The Syntax and Semantics of the Proposed International Algebraic Language of the Zurich ACM-GAMM Conference. Proceedings of the International Conference on Information Processing, UNESCO, 1959, pp.125-132. Typewritten preprint.
|
||||
[Back63]: J. W. Backus, F. L. Bauer, J. Green, C. Katz, J. McCarthy, A. J. Perlis, H. Rutishauser, K. Samelson, B. Vauquois, J. H. Wegstein, A. van Wijngaarden, M. Woodger, and P. Naur. 1963. Revised report on the algorithm language ALGOL 60. Commun. ACM 6, 1 (Jan. 1963), 1–17. doi:10.1145/366193.366201
|
||||
[Baec72]: H. D. Baecker. 1972. On a missing mode in ALGOL 68. SIGPLAN Not. 7, 12 (December 1972), 20–30. doi:10.1145/987059.987062
|
||||
[Baec72b]: H. D. Baecker. 1972. Garbage collection for virtual memory computer systems. Commun. ACM 15, 11 (Nov. 1972), 981–986. doi:10.1145/355606.361886
|
||||
[Bake77]: Henry G. Baker. 1978. List processing in real time on a serial computer. Commun. ACM 21, 4 (April 1978), 280–294. doi:10.1145/359460.359470
|
||||
[Bake78]: Henry G. Baker. 1978. Shallow binding in Lisp 1.5. Commun. ACM 21, 7 (July 1978), 565–569. https://doi.org/10.1145/359545.359566
|
||||
[Bare92]: Barendregt, Henk P. "Lambda calculi with types." (1992).
|
||||
[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
|
||||
[Bate82]: Raymond L. Bates, David Dyer, and Johannes A. G. M. Koomen. 1982. Implementation of Interlisp on the VAX. In Proceedings of the 1982 ACM symposium on LISP and functional programming (LFP '82). Association for Computing Machinery, New York, NY, USA, 81–87. doi:10.1145/800068.802138
|
||||
[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
|
||||
|
|
@ -5741,6 +5840,7 @@ Algol68C работал на VAX c 81-го года [ALGOL81], и хотя ег
|
|||
[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.
|
||||
[Bish75]: Bishop, Peter B. "Garbage collection in a very large address space." (1975).
|
||||
[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
|
||||
|
|
@ -5783,9 +5883,12 @@ https://core.ac.uk/download/pdf/236248615.pdf
|
|||
[Cadi72]: J. M. Cadiou and Zohar Manna. 1972. Recursive definitions of partial functions and their computations. In Proceedings of ACM conference on Proving assertions about programs. Association for Computing Machinery, New York, NY, USA, 58–65. doi:10.1145/800235.807072
|
||||
[Camp85]: Campbell-Kelly, Martin. “Christopher Strachey, 1916-1975: A Biographical Note.” Annals of the History of Computing 7 (1985): 19-42.
|
||||
[Card2006]: Cardone, Felice and Roger Hindley. “History of Lambda-calculus and Combinatory Logic.” (2006).
|
||||
[Chen70]: C. J. Cheney. 1970. A nonrecursive list compacting algorithm. Commun. ACM 13, 11 (Nov 1970), 677–678. doi:10.1145/362790.362798
|
||||
[Chio2001]: S. Chiou et al., "A Marriage of Convenience: The Founding of the MIT Artificial Intelligence Laboratory"
|
||||
[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.
|
||||
[Cohe81]: Jacques Cohen. 1981. Garbage Collection of Linked Data Structures. ACM Comput. Surv. 13, 3 (Sept. 1981), 341–367. doi:10.1145/356850.356854
|
||||
[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
|
||||
[Coll60]: George E. Collins. 1960. A method for overlapping and erasure of lists. Commun. ACM 3, 12 (Dec. 1960), 655–657. doi:10.1145/367487.367501
|
||||
[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.
|
||||
|
|
@ -5795,6 +5898,7 @@ https://core.ac.uk/download/pdf/236248615.pdf
|
|||
[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
|
||||
[Dahl78]: Kristen Nygaard and Ole-Johan Dahl. 1978. The development of the SIMULA languages. History of programming languages. Association for Computing Machinery, New York, NY, USA, 439–480. doi:10.1145/800025.1198392
|
||||
[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
|
||||
|
|
@ -5826,6 +5930,7 @@ https://core.ac.uk/download/pdf/236248615.pdf
|
|||
[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
|
||||
[Feni71]: Robert R. Fenichel. 1971. List tracing in systems allowing multiple cell-types. Commun. ACM 14, 8 (Aug. 1971), 522–526. doi:10.1145/362637.362646
|
||||
[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).
|
||||
|
|
@ -5921,6 +6026,7 @@ https://core.ac.uk/download/pdf/236248615.pdf
|
|||
[Levi75]: Levi, G., Sirovich, F. (1975). Proving program properties, symbolic evaluation and logical procedural semantics. In: Bečvář, J. (eds) Mathematical Foundations of Computer Science 1975 4th Symposium, Mariánské Lázně, September 1–5, 1975. MFCS 1975. Lecture Notes in Computer Science, vol 32. Springer, Berlin, Heidelberg. doi:10.1007/3-540-07389-2_211
|
||||
[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
|
||||
[Lieb80]: Lieberman H, Hewitt C. A Real Time Garbage Collector that can Recover Temporary Storage Quickly. MASSACHUSETTS INST OF TECH CAMBRIDGE ARTIFICIAL INTELLIGENCE LAB; 1980 Apr.
|
||||
[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
|
||||
|
|
@ -6028,6 +6134,7 @@ 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.
|
||||
[Roch71]: Arnold Rochfeld. 1971. New LISP techniques for a paging environment. Commun. ACM 14, 12 (Dec. 1971), 791–795. doi:10.1145/362919.362937
|
||||
[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).
|
||||
|
|
@ -6038,6 +6145,7 @@ https://core.ac.uk/download/pdf/236248615.pdf
|
|||
[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
|
||||
[Scho67]: H. Schorr and W. M. Waite. 1967. An efficient machine-independent procedure for garbage collection in various list structures. Commun. ACM 10, 8 (Aug. 1967), 501–506. doi:10.1145/363534.363554
|
||||
[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
|
||||
|
|
@ -6050,6 +6158,7 @@ https://core.ac.uk/download/pdf/236248615.pdf
|
|||
[Slom89]: Sloman, Aaron. "The Evolution of Poplog and Pop-11 at Sussex University." POP-11 Comes of Age: The Advancement of an AI Programming Language (1989): 30-54.
|
||||
[Smit73]: Smith, David Canfield and Enea, Horace J. (1973) MLISP 2 http://i.stanford.edu/TR/CS-TR-73-356.html
|
||||
[Stee75]: Sussman, Gerald J. and Guy L. Steele. “An Interpreter for Extended Lambda Calculus: SCHEME,.” (1975).
|
||||
[Stee75b]: Guy L. Steele. 1975. Multiprocessing compactifying garbage collection. Commun. ACM 18, 9 (Sept. 1975), 495–508. doi:10.1145/361002.361005
|
||||
[Stee76]: Steele Jr, Guy Lewis. "LAMBDA: The ultimate declarative." (1976).
|
||||
[Stee76b]: Steele, Guy L. and Gerald J. Sussman. “Lambda: The Ultimate Imperative.” (1976).
|
||||
[Stee77]: Guy Lewis Steele. 1977. Debunking the “expensive procedure call” myth or, procedure call implementations considered harmful or, LAMBDA: The Ultimate GOTO. In Proceedings of the 1977 annual conference (ACM '77). Association for Computing Machinery, New York, NY, USA, 153–162. doi:10.1145/800179.810196
|
||||
|
|
@ -6108,6 +6217,7 @@ http://www1.cs.columbia.edu/~waltz/Papers/Understanding%20Line%20Drawing%20of%20
|
|||
[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
|
||||
[Wils92]: Wilson, P.R. (1992). Uniprocessor garbage collection techniques. In: Bekkers, Y., Cohen, J. (eds) Memory Management. IWMM 1992. Lecture Notes in Computer Science, vol 637. Springer, Berlin, Heidelberg. doi:10.1007/BFb0017182
|
||||
[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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue