Изучение теории («матчасть»)

Разработка ОС и компилятора.

Съездил на Озон за книгой Вирта. Интересно, что я сейчас ровно тем и занимаюсь — разрабатываю ОС и компилятор. Литература в тему. Слева — старое издание, которую я купил в 2010 году (обновлённое издание 2013 года доступно в онлайн, англ.). Справа — вышедший в 2015 году русский перевод. Разумеется, на родном языке изучать «матчасть» (как выражаются «погоны») удобней.

Конечно же, сразу залез в главу про сборку мусора. Она подтвердила (стр. 253) тот очевидный факт, что счётчик ссылок на объекты это просто одна из реализаций сборки мусора. По Вирту есть всего два способа реализовать сборку мусора:

  1. Подсчёт ссылок (the reference counting).
  2. Просмотр пометок (the mark-scan schemes).

Когда здесь пытались противопоставить подсчёт ссылок сборке мусора — просто сознательно сбивали с толку (много выскажем в своё время профессиональным обманщикам «с гибкой психикой», и не только я). К науке такое противопоставление отношения не имеет. Проверил по новейшему изданию 2013 года, в этой основе основ изменений нет.

Соглашусь, что Оберон использует второй подход. Можете заглянуть в TFM и прочитать, почему. Всё объяснено. Также приводятся два научных аргумента в пользу сборки мусора:

  1. Программист обычно не знает, когда запросить освобождение.
  2. «Подсказка» программиста может не заслуживать доверия. Ошибочное освобождение, случившееся, когда ещё существуют ссылки на рассматриваемый объект, может привести к повторному выделению одного и того же пространства с пагубными последствиями.

Следовательно, заключает профессор, кажется благоразумным полностью положиться на системное управление, чтобы выявить, какие области памяти действительно можно повторно использовать.

Эти аргументы убедили профессора Вирта отказаться в Обероне от паскалевского Dispose() и оставить только New() — сократив синтаксис языка и увеличив его выразительную мощь. Это и есть научный подход, за который агитирует Вирт. Язык должен становиться проще, не давая программисту совершать уже изученные ошибки и позволяя решать более сложные задачи.

Отсутствие Dispose(), повторюсь, удовлетворяет требованию компактности входного языка ПМК, которое выдвинул ещё товарищ Трохименко.

Предвижу возражения «настоящих программистов», кто не доверит рантайму взять Dispose() на себя, считая собственный код безошибочным. У науки нет способов заставить людей её использовать. Хотите использовать вместо структурных операторов GOTO с метками или вообще хранить в уме адреса для безусловных переходов — вперёд, остановить вас на пути деградации некому. Чтобы внедрять научные знания, часто требуется смена поколений с естественным вымиранием тех, кто до последнего вздоха отстаивает устаревшие представления, как религиозные догмы.

Есть много интересных концепций, которые хотелось бы видеть в компактном Обероне. Не все получится реализовать, но вариант со сборкой мусора будем рассматривать.

Метки публикаций: 
Русский

Комментарии

Надо просто читать, что пишут другие. Подсчет ссылок противопоставлялся не сборке мусора, а сборщику мусора. Более того, сразу было сказано, что и подсчет ссылок в калькуляторном языке будет нужен только после достижения некоторого уровня необходимости в оных, а именно введения объектных типов.

И еще просьба не использовать термин "научный" где ни попадя. Наука - это теория разработки компиляторов для абстрактной ЭВМ. Вклад Вирта, одного из, здесь признан. Оберон - конкретный инженерный проект со своими ограничениями (изначальная нацеленность на встроенные системы), "тараканами" и неизменно обретаемым за годы "тяжелым наследием". Этот вклад уже не является общепризнанным.

1. Не пытайтесь сохранить лицо, играя словами. Уже не получится. Сборщик мусора это часть операционной системы или рантайма, которая и производит сборку мусора — по методу 1 (подсчёт ссылок) или методу 2 (просмотр пометок).

2. Вводить «объектные типы» не нужно, как и вообще привлекать в некоммерческий проект ООП с её уродливым псевдонаучным кривоязом. Достаточно ввести типы данных, процедурные переменные и позволить расширять эти типы данных («наследовать» на ООПшном кривоязе).

Сборка мусора же потребуется в ПМК, если в добавок к двум стекам (десятичный и стек возвратов) будет реализована динамическая память (куча). Её можно делать либо на уровне науки 1970-ых годов (с New и Dispose), либо на более современном — с New и сборкой мусора.

3. Оберон — научная теория. Математически точная научная нотация для формальной записи алгоритмов. Она проверена экспериментально (в конце 1980-ых годов). Это одно из требований к научным теориям в любой области, не только в компьютерных науках (computer science). По этой теории проф. Вирта публикуются научные работы, защищаются диссертации. «Инженерные», точнее коммерческие проекты это ваши C++, Java и прочее тяжёлое наследие индустрии. Образованные разработчики применяют эту научную теорию частично (как авторы Java) или полностью (как авторы Компонентного Паскаля). Безграмотные разработчики порят отсебятину или вообще используют антинаучные подходы — например, неограниченно увеличивая сложность входного языка вместо работы над его упрощением (так сделано в C++).

Да, даже фундаментальные научные результаты не сразу обретают всеобщее признание. Некоторые твердолобые люди так и умирают, неспособные признать, что Земля вертится вокруг Солнца, что гомосексуальность это разновидность нормальной человеческой сексуальности — или увидеть различие между Обероном, предложенным и развиваемым университетами, как научная теория, и «конкретными инженерными проектами», созданными корпорациями ради наживы в той или другой области рынка.

Наука одна, это человеческое невежество и алчность корпораций разнообразны и безграничны.

От тебя таких ляпов не ожидал.

Сборщик мусора это часть операционной системы или рантайма, которая и производит сборку мусора — по методу 1 (подсчёт ссылок) или методу 2 (просмотр пометок).

Для организации подсчета ссылок не нужен сборщик мусора. Простейший пример - реализации интерфейсов в COM или shared pointers в стандартной библиотеке Си++11.

Освободись от религии, займись наукой.

"Подсчёт ссылок также известен как один из алгоритмов сборки мусора" (с) Википедия

Об чём спор ? Арви забыл в классификации пункт №3, когда подсчёт ссылок - это часть языка (C++) ? :-)

Подсчёт ссылок - это фактически сборщик мусора для бедных. Здесь нет противоречия.

Сядь лучше за изучение науки, а не C++ и COM. Индустриальные языки делают практики — иногда они уважают достижения науки, иногда делают всё наперекосяк и пишут бессмысленные талмуды коммерческой чепухи вроде ООП.

Научная терминология как раз строга. Это религия могла бы «отпустить грехи» и помочь невежественному человеку вывернуться. А тут ты сел в лужу, и наука это бесстрастно показывает.

Ватник, например, уже понял термины, предложенные профессором Виртом в Обероне и начал ими успешно оперировать. Обгонит тебя, если вместо изучения науки будешь упорствовать в своём невежестве.

Юмористы вы, ребята. Хотите отождествлять "сборку мусора" и "сборщика мусора" - флаг в руки. На сем завершаю.

Собирать мусор с помощью алгоритма сборки мусора без сборщика мусора, бугагагага!

С утра повеселили новыми шутками, спасибо. Мыслю можно развить: подсчитывать ссылки с помощью подсчитывателя, а удалять объекты, разумеется, с помощью удалятеля. Чего только не придумают, лишь бы матчасть не посмотреть, например, по упомянутому выше IUnknown. В очередной раз ключевые слова вы пропускаете, что в очередной раз подтверждает.

Ну хорошо. Счётчик ссылок можете не называть сборщиком мусора. Хотя та часть программы, которая занимается проверкой счётчика ссылок и вызовом delete является по сути простым сборщиком мусора.
Но это в любом случае "сборка мусора". И что это даёт ?

И вы говорите неправду, никакой IUnknown выше не упоминается. И вы снова обвиняете в пропуске не существующих ключевых слов, симптоматично.

Понятия не имею насчёт терминов Вирта, каюсь, ничего не читал об Обероне. И книг Вирта, насколько помню, в глаза не видел. Я конечно исправлюсь, но пока из меня обгоняльщик паршивый. Я в основном функциональщину щупал, там общепринятые термины используются, в компьютерных науках. Может быть поэтому мы друг друга понимаем? "Структура и интерпретация компьютерных программ" и всё такое.

Терминология Вирта последовательна. Её использование всё упрощает, как законы Кеплера упростили наши представления о движении планет, убрав эпициклы и прочую ересь. В то время, как ООПшники раздувают щёки в беседах о классах и объектах (это вызывает уважение инвесторов), Вирт продолжает разговор о типах и переменных. Вместо «наследования» типы расширяют, добавляя новые поля в запись. Ничего лишнего, и романтика в этом.

Функциональное программирование это тоже научная школа, просто с другого континента. Она не настолько влиятельна, но каждый выпускник MIT AI Lab (нынче CSAIL) изучал Лисп. Поэтому его можно найти в Emacs и много где ещё.

К сожалению о Лиспе судят по Емакс Лиспу, а это самый его убогий и иделогически вредный диалект. Возможно Сергей ничего кроме Автолиспа и Емакслиспа не видел, поэтому у него и сложились такое пренебрежительное мнение. На самом деле, если ознакомиться с Common Lisp, то там эта идея расширения без наследования былв реализована лет 30 назад (точнее ещё до принятия стандарта), кстати потом поверх накрутили ООП систему, но КАКУЮ, Ей до сих пор нет равных. Искусство мета-объектного протокола - это мега тема, по которой написаны целые книги. Так что здесь мы в одной упряжке. То же самое в функциональщине, тот же OCaml в основе устроен так что пользоваться его ООП фичами не хочется, т.к. не ООП механизмы даже мощнее.

Форт тоже от этого страдает. В нём есть родные выразительные средства. Но ООП так разрекламировано и профинансировано, что появляются многочисленные подражания C++ даже в Форте и Лиспе. Последний пример был упомянут на этом сайте, кстати не самый плохой — Object-Oriented Development Environment, ODE (англ. pdf).

Во всём этом есть рациональное зерно и что-то позаимствовать в ПМК можно и нужно. Но как не запихать в язык кучу ненужных фич, а именно развить его основу, сделав ещё более простым и могучим — это важно продумать.

Конечно же, в язык надо ввести записи и синтаксис обращения к полям должен быть привычным: квадрат.лв.x , квадрат.лв.y

Уже одно это потребует работы над лексическим уровнем и революционного паржера. Должна быть возможность хранить в переменных (и полях) ссылки на подпрограммы. Должна быть возможность расширять тип записей, создавая новые типы на основе своих и библиотечных. Всё это азы Оберона, которые богачи ООП пытаются насильно приватизировать и нагло возглавить.

Но как эти вещи ввести во входной язык ПМК и сделать органичными, а не дешёвым ООПшным уродством, ещё предстоит увидеть. Вполне возможно, что структура классической словарной статьи Форта/Каллисто может быть переосмыслена, как запись. А поле кода — как обычное поле записи с типом "процедура" («функция-член» из кривояза ООП).

В этом случае слово EXECUTE должно эволюционировать в обычный вызов «функции-члена» p.cfa , а многострадальные слова типа N>BODY станут доступом к полям записи словарной статьи, в данном случае p.body

Такое развитие фундаментально улучшает язык и переводит на новый уровень, но требует глубокого продумывания и не любит спешки.

Я бы сказал, что Форту надо двигаться в сторону Лиспа в плане гладкости работы всех механизмов. В классическом Форте слишком всё торчит напоказ. В Лиспе например символьный идентификатор, это повсеместный расходный материал, написать 'my-favorite-long-symbol - как два байта переслать.
Также легко строятся списки этих символов, '(one two three). В Форте надо задумываться о каких то словарях, в Лиспе тоже есть пакеты, куда всё падает, но программист локально об этом мало задумывается. В Лиспе один главный недостаток - синтаксис вынуждает использовать много скобок :-) В принципе история знает кучу разных вполне успешных вариантов постороения аналогов Лиспа без скобок: Dylan, Nemerle, в какой то мере Python, Ruby (изначально назывался MatzLisp), со скобками но разными и приглаженным синтаксисом современный диалект - Clojure. Для завтравки неплохо выглядит причёсывание s-выражений в виде sweet expressions, но не хотелось бы иметь двумерный синтаксис: http://readable.sourceforge.net/

Вот хочется сохранить многое из идеологии Форта и Лиспа, но чтобы это более читабельный и хорошо структурированный язык. И чтобы в нём была МИКРОМОДУЛЬНОСТЬ, а не просто модульность. Чтобы параметризируемый модуль, являющийся объектом первого класса (аля Ocaml), можно было создать походя. Для галимого Форта и Лиспа - это вопрос настройки словарей/пакетов. В Common Lisp это большая беда, там есть "большие пакеты", в рамках которых можно многое скрыть, но проблема с маленькими, то есть создать пакет конечно это одна команда, но ирерахически они не организованы и вообще это слишком крупная семантическая категория, не подходящая для мимоходно созданного модуля. А в ПМК, не смотря на необходимость некой дисциплины, всё равно всё будет создавать мимоходно и на коленке. Чем меньше сущности (тут слова Форта и функции Лиспа дадут фору всем остальным), тем легче их скомпоновать на коленке. Недопустимо, чтобы надо было рассказывать:
ОБЪЯВИТЬ КЛАСС МойБольшойЖирныйКласс
НАЧАЛО
МЕТОД МойБольшойЖирныйМетод НАЧАЛО
// Тело большого жирного метода
КОНЕЦ МЕТОДА
КОНЕЦ

Ради того чтобы создать потом экземпляр этого г и вызвать этот метод (подход жабы).

В Форте и Лиспе чтобы сделать работу не создают классы, хотя в Лиспе ВСЁ является объектами и установлена их иерархия начиная от t (true, тип от которого все наследуются) до nil (аналог NULL заодно играет роль false). В переводе на русский:

(ОПРЕДФУН СделатьВсёКакНадо (АРГ1, АРГ2)
(СделатьВсёЧтоНадо ARG1, ARG2))

Аналог на Форте получается ещё короче и практичнее.
Только он как правило write-only.

Короче хотелось бы Форт с механизмами Лиспа, чтобы был так же лаконичен, но более читабелен.
Возможно БЕЗ обратной нотации и явного стека !!! Я тут прикидывал, можно попробовать
Форт перевести в ПРЕфиксную нотацию, а где формулы и в ИНфиксную, полностью функционал сохранится, но читабельность резко поднимется.

А ещё надо метапрограммирование вывести на уровень удобства макросов Лиспа, чтобы каждый лопоухий юзер мог написать свой нетленный макрос и родить недостающие ему языковые элементы :-)

Согласен с читабельностью и желательностью поднять абстракцию адресов и словарей Форта до указателей и списков. И да, из-за этой форы и взял Форт за основу Каллисто.

Кстати, переход от языка МК-161 к Каллисто уменьшает write-only и добавляет редактируемость описаниям слов. Это благодаря отсутствию адресов переходов, со структурным IF и циклами, где даже метки не нужны.

Когда мы лишаем простой паржер Форта девственности ради обращений к полям записей, не проблема присобачить в нагрузку инфиксный рекогнайзер с рекурсивным спуском. Проблемы возникают при проектировании языка. Из инфиксной записи можно обращаться к слову, определённому пользователем.

1. Как описывать такие слова? Что будет проверяться — количество аргументов, их тип?

2. Это всё одно и тоже?

a b f
f(a,b)
a f(b)

Современные Форты и Лиспы без ридеров-рекогнайзеров не бывают, так что всё ОК. Надо это дело расширять до разумных пределов, для доступа к полям и индексаторов.

Парсер должен автоматически перобразовывать x.y в типа x ' y @slot
А x.y[i] в x ' y @slot i @arr

>Как описывать такие слова? Что будет проверяться — количество аргументов, их тип?

Может фиксировать количество аргументов и возвращаемых значений, а на тип положить (проверять динамически если не объявлен явно) как в Лиспе, всё таки это динамический язык (и Форт, и Лисп). А как оно в хацкеле понимает что к чему, там применение функции имеет приоритет вроде и можно писать
f1 x * f2 y z, значит знает кол-во аргументов. А если оно переменное, то заключать в скобки
make-my-list [x y z].

1) a b f и f(a b) тоже самое
2) a f(b) -> два значения на стеке (если f(b) возвращает одно)

Идея рекогнайзера, который бы преобразовывал инфиксную запись в постфиксную, привлекательна. Если рекогнайзер успешно провёл синтаксический разбор нераспознанного слова, сканер не обращается к WORD, а берёт из очереди уже готовый «перетасованный» поток лексем. Подумаю над этим.

Это по науке, т.к. не смешивает синтаксис с семантикой и решает проблему, указанную мной. Если выявлено несоответствие по аргументам при вызове процедуры, рекогнайзер выдаёт ошибку. Но можно вызывать процедуры и без рекогнайзера, в общем входном потоке:

a b f    (* нормально, обычный код Каллисто/Форта *)
f(a,b)+1 (* сработал рекогнайзер, в очереди лексем: a b f 1 + *)
a f(b)   (* ошибка, неизвестное слово f(b) *)

В каком-то смысле это обновление устаревшего слова NUMBER — к которому обращался INTERPRET, если слово в словаре не найдено. Всё равно интерпретатор буду переделывать для исполнения кода из файлов и строк.

Кстати, есть альтернативный путь развития. В colorForth Чак Мур вообще отказался от командной строки и объявил анафему слову WORD — введённое слово ищется в словаре и исполняется сразу по нажатию пробела, введённые числа кладутся на стек тогда же. Его система позволила сократить количество клавиш до минимума, а это полезно для ПМК. Идеально это реализуется, если клавиатуру заменить на сенсорный экран.

В Лиспе для таких дело есть макросы ридера (лисповский вариант рекогнайзера). Ридер встречает спец.символ, ищет какой макрос назначен и разбирает выражение из строкового потока, затем разбор возвращается к стандартному, но обычно это используется для разбора единичных лексем, а не целых выражений. Целые выражения разбираются обычными макрами (например известная макра Infix) и там накладывается требование не склеивать операторы с операндами (whitespace важен) и т.п. То есть это по сути обычные списки, которые макрос преобразует к годным Лисп выражениям. Например (X + X) => (+ X X) и т.д. Можно и это дело развить, но нам же не надо на данном этапе окончательно изменить язык, надо сделать его более дружелюбным. Трансляторы Оберона и других вещей в Форт лучше делать не "изнутри" Форта, слишком уж много ограничений у встраиваемых языков.

Встроить разбор инфиксной записи в NUMBER это один из вариантов. Он, кстати, весьма дружелюбен. "x←2+2" читается лучше, чем "X := 2 + 2" при типично фортовском подходе с пробелами между слов. Там тоже такие реализации инфиксной записи известны.

Сейчас я рассматриваю много различных вариантов обновления входного языка. Выбирать буду уже после релиза Каллисто-2. Когда уже заработает, например, самокомпиляция на компьютере и будет яснее, что людям нужно.

Осталось решить проблему с приоритетом инфиксных операций, определяемых программистом. Был вариант, уже намекал на него, когда можно «встроиться» в любое синтаксическое правило — хоть во множитель, хоть в слагаемое. Можно взять и страуструпный, конечно, когда переопределяются только стандартные операции.

Автоматическое управление памятью (в частности сборка мусора) не нужна в проектах уровня МК-61, где просто нет никаких больших и сложных структур данных. Ещё такая сборка не нужна в реализациях сред выполнения примитивных языков вроде Бейсик, Рапира и т.п., там просто негде потерять помять. Там же где создаются динамические структуры и связываются друг с другом, очевидно необходима сборка мусора, в том числе и потому что юзера ПМК напрягать рутинным управлением памятью - это ОЧЕНЬ плохая идея. Подсчёт ссылок не годится для ситуаций, где могут быть зацикленные структуры, поэтому его можно сразу отбрасывать, т.к. мы не знаем, что придёт в голову юзеру, а напрягать его слежением за ссылками мы не будем.

Кроме того автоматическое управление памятью избавляет от необходимости передавать всё по значению (естественно при таком раскладе нет зашаренных структур и памяти некуда утекать и сразу ясно что можно уничтожить, а что нет). В современности без передачи больших структур данных по ссылке не решить ни одной задачи, иначе ПМК захлебнётся в копировании огромных матриц, и невозможно будет работать с деревьями и т.д.

Вы умело обошли конфликтные темы и сказали главное.

Уже в Паскале, где началась работа со сложными структурами данных, не помешала бы сборка мусора. Но ввели её лишь в Обероне, через два поколения языков. Объективно сложный вопрос, который учёным пришлось решать более 10 лет. И найденный ответ парадоксальный. Мы все привыкли, что научный и грамотный подход это begin…end и open…close, забывать явно освобождать ресурс это ошибка — а здесь правильное решение оказалось асимметричным. Делать new и не делать dispose.

Интересней продумывать идеальный входной язык ПМК не только «сверху», реализуя Оберон — но и с практической стороны, «танцуя» от задачи. Какие требования предъявляет СКМ к типам данных и особенно к иерархии типов?

Жаль, профессора Дьяконова больше нет с нами. Он занимался ровно этим вопросом по приглашению крупной международной корпорации и мог бы дать готовые ответы. Теперь придётся копаться самим в исходных кодах открытых СКМ и анализировать, какую поддержку разработчикам СКМ захочется иметь от языка.

Я в общем то не копенгаген в компьютерных науках, наоборот скорее самоучка благоговеющий перед правильным научным подходом взамен придумывания квадратных леспедов на коленке. Надо найти ответ на вопрос: решена ли проблема АВТОМАТИЧЕСКОГО определения рамок жизни объекта по анализу потоков данных в программе. КАКИМ должен быть язык, чтобы можно было эффективно выявлять места сдыхания объектов и собирать их автоматически, избавив программистов от низкоуровневой деятельности. Например языки на основе редукции графов позволяют проводить исчерпывающий анализ потоков данных, тот же Clean даже имеет в составе систему доказательства свойств кода.
Есть ли в Обероне какие то специальные языковые находки, которые бы облегчали эту проблему ? Учитывая уровень формализации, я подозреваю, что ответ будет положительный ???

Как раз читаю эту главу. Проф. Вирт хорошим и научно точным языком описывает оба подхода (счётчик и пометки). Можно реализовать в ПМК подсчёт ссылок, конечно. Есть плюсы и минусы.

Но для Оберона профессор выбрал вторую, двухпроходную схему — при этом реализовав её не в языке, а в операционной системе (мы тоже можем так сделать). Динамические объекты создаются с помощью New() и удаляются, когда запускается сборщик мусора.

Сборщик мусора проходится по всем «объектам» (научная терминология — записям), проходит по ссылкам и помечает участки памяти «этот участок используется». Тут Вирт уходит в свою любимую тему, обход деревьев. На мой первый взгляд, это можно проще сделать. Но глубоко пока здесь не копал.

После этого сборщик мусора добавляет в списки свободной памяти все её участки, ссылок на которые не обнаружено. Эти два прохода реализованы эффективно, есть исходный код и авторское описание. Но при сборке мусора система парализуется на ощутимое время, секунду или доли секунды. Для ПМК это, скорее всего, пройдёт незаметно. Но вот когда айфон немного подвисает, я всегда задаюсь вопросом — это сейчас мусор собирают или что?

Языковые находки это слово NEW и отсутствие слова DISPOSE (есть alloc и нет free, если кто от Си не вылечился). Кардинальное упрощение языка. Чтобы обеспечить такую простоту, применяется несколько закулисных механизмов. У каждой записи, каждого участка памяти есть определённые поля, невидимые для прикладного программиста, обеспечивающие эффективную сборку мусора.

UPDATE. Эту тему творчески развил ученик профессора в Active Oberon — он ввёл активные объекты, в которых «поддерживается жизнь» за счёт параллельного программирования. С ними связаны отдельные потоки исполнения. Пока они не завершены, объект считается активным и не выкидывается из памяти даже при отсутствии ссылок на него. Очень интересная концепция. Только когда активный объект «умирает», его могут выкинуть из памяти, при отсутствии ссылок.

Образные выражения в «кавычках», а научные термины выделил курсивом.

Всё таки отслеживать ссылки - довольно накладная операция. Если анализировать где создаются и используются структуры данных, то можно определить рамки их жизни и не размещать под управлением сборщика, а например размещать на стеке и выбрасывать при выходе из лексической области. Как минимум выделение памяти для объекта из динамической операции можно было бы превратить в статическую (априорное пакетное выделение N байт на стеке) после прохода по программе. Если идёт интенсивное выделение памяти и последующее уничтожение объектов - затраты на сборку мусора могут превысить пользу от его использования. Например образуются промежуточные матрицы и тут же уничтожаются. Если их хотя бы выделять локально и повторно использовать одно и то же место, т.к. в такой то строчке программы старая матрица уже никогда не будет использоваться, то накладные расходы будут не выше С++.

Пришёл домой и сверил терминологию с книжкой.

Есть три области памяти — область блоков (модули), рабочая область (стек) и динамическая область (куча). Области видимости локальных идентификаторов, автоматическое удаление локальных переменных из стека — это всё есть в Обероне. Образованный программист всем этим арсеналом пользуется, в том числе для оптимального кода. В практических реализациях есть разные прагмы и указания компилятору, где он сможет сэкономить.

Куча же используется для более сложных вещей, которые в общем случае требуют автоматической сборки мусора. На всё это можно накладывать различные оптимизаторы, конечно. Но концептуально это разные вещи.

Образованному программисту достаточно и статического выделения памяти. А пользователь ПМК априорно считается обезьяной (без гранаты). Поэтому давать ему какие то хитрые механизмы (гранату) - это утопия. В идеале компилятор САМ должен выяснить где сдохнут объекты и размещать ли их на стеке или в статической памяти, или всё таки отдать под управление сборщика мусора. Всё это в целом реализовано во всяких Лиспах,OCAML а потом в Java и .NET.

Я так понимаю Сергей в своём полемическом задоре намекает на то, что его любимая Рапира в виду примитивности и дубовости (статичности структур данных) не способна организовать утечки памяти и вообще избавляет от необходимости управлять чем то ? Ну так каждый может :-)
Мне вот нужен язык, на котором удобно будет написать например шахматный движок, RPL оказался в этом плане довольно коварным, там многие вещи передаются по значению и хронический недостаток сложных структур данных. А уж писать это на каком то геморрое типа Рапиры - оставим для очень сильных духом людей. Я одного такого знал, который на CASIO Basic написал шахматный движок (правда без ИИ). Не ну я понимаю, раньше и байты памяти по тетрадке выделяли. Видимо в это светлое время хочет нас вернуть(ткнуть носом) Сергей ???

Согласен, обычный владелец ПМК не обязан знать тонкости реализации. Тем более, что мы сами ещё не знаем, ведь язык следующего поколения на стадии раннего планирования. Общее правило — в куче содержатся только безымянные переменные (созданные NEW), локальные именованные переменные в стеке, а глобальные в блоках (модулях).

МК-161, Рапира, Паскали и Бейсики хороши для «программирования в малом». Закодировать математический алгоритм, примеры этого для ПМК есть в справочнике Дьяконова. На таком уровне мы вызываем подпрограммы, программируем циклы и условные операторы,…

Входной язык ПМК следующего поколения (уровня Оберона) должен поддерживать «программирование в большом» — собирать приложения из модулей, при необходимости расширяя определённые в них типы. Более высокий уровень абстракции. Выстраиваем отношения между крупными, цельными, строительными блоками (разработанными по старой технологии структурного программирования: процедуры, циклы, см. выше), дорабатывая и создавая на уже готовой основе модули покрупнее, мощнее, заточенные под новые задачи.

Вот эти средства «программирования в большом» и надо заранее продумывать, обсуждать — как внести во входной язык ПМК модульность и расширение типов. Которых, увы, нет в МК-161, Рапире, Паскале и Бейсиках, но которые были научно введены в Модуле-2 и Обероне. Конечно, кое-что из этого добавляла индустрия самостоятельно в виде заплаток, как юниты в Turbo Pascal'е. Но не в Рапиру, насколько я знаю.

Даже Каллисто, успешно доработав входной язык ПМК до важного уровня структурного программирования, пока не поддерживает «программирование в большом» и остаётся на уровне Паскаля, Рапиры и прочего.

Первой ласточкой были библиотеки функций в HP-48 и TI-89. А теперь в HP Prime паскалеподобный язык, там модульность уже гораздо лучше. Для счастья нужно было как минимум две вещи: отвязать модульность от встроенных типов объектов, разрешить создать произвольные типы (и свой интерфейс пользователя), добавить возможность генерации кода и остальные фишки приличных языков вроде лямбда функций, замыканий и т.п., без которых писать код - всё равно что заниматься сексом стоя в гамаке.

Кстати, интересная тема.

Модульность важна в компьютерной науке, да и на практике без неё уже никуда. Индустрия пыталась её реализовать в виде библиотек, а также пресловутой «инкапсуляции» — где обычное для модулей скрытие реализации от интерфейса извращенцы ООП внезапно склеили с совершенно инородной вещью, описанием типа записи.

Согласен, библиотека это лучшее «внедрение в производство» модулей. Разница только в том, что модули это высокоуровневый инструмент языка. Библиотека же это (как всегда в индустрии) низкоуровневая примочка от операционной системы, к которой кое-как присобачена полуглючная надстройка над языком. Между тем, как программирование «в большом» требует возможно даже большей аккуратности и дисциплины, чем «в малом».

В Обероне разработка модулей глубоко продумана и реализована, «как надо» на уровне и синтаксиса, и семантики. Меня впечатлило, что в Обероне проф. Вирт ушёл от идеализма Модулы-2 в сторону практичности и сделал экспортную часть менее многословной и более компактной. Будто специально двигался в сторону нашего будущего ПМК. :-)

AtH wrote: Пришёл домой и сверил терминологию с книжкой.

Есть три области памяти — область блоков (модули), рабочая область (стек) и динамическая область (куча). Области видимости локальных идентификаторов, автоматическое удаление локальных переменных из стека — это всё есть в Обероне. Образованный программист всем этим арсеналом пользуется, в том числе для оптимального кода. В практических реализациях есть разные прагмы и указания компилятору, где он сможет сэкономить.

Куча же используется для более сложных вещей, которые в общем случае требуют автоматической сборки мусора. На всё это можно накладывать различные оптимизаторы, конечно. Но концептуально это разные вещи.

"О, сколько нам открытий чудных..." (с)
Неважно, что терминология специфичная для Оберона и статические переменные в ней надо поискать, ты уже приблизился к классам памяти и управлению оной в программе. Следующий шаг - открыть, что в средах типа Java/C# и даже в Delphi (где сборщика мусора нет, но необъектные типы все еще можно создать на стеке) сознательно урезали эти механизмы, все создается в куче, в динамической памяти, даже т.н. value type типа структур. Чтобы любой новичок чувствовал себя комфортно.

Следующий шаг - открыть, что в средах типа Java/C# и даже в Delphi (где сборщика мусора нет, но необъектные типы все еще можно создать на стеке) сознательно урезали эти механизмы, все создается в куче, в динамической памяти, даже т.н. value type типа структур.

Чё правда что ли ? Да, в .NET cтатические переменные размещаются на куче вне зависимости от типа значения, что логично для этих сред выполнения, там же нет никакой статической области памяти.

А вот локальные value type хранятся и передаются на стеке. Не знали ? А ведь любой новичок C# это знает, ай яй яй, Сергей !!!

Совершенно верно, любой новичок в C# начинает с заучивания догм "reference type создаются в куче, а value type - на стеке". Через некоторое время может прийти понимание, что это не совсем так, что переменные могут там создаваться но не обязаны (например, value type-переменные внутри блока-итератора или поля класса), и решает это среда. А может и не прийти. Надеюсь, к вам придет.

Никто вас за язык не тянул:

все создается в куче, в динамической памяти, даже т.н. value type типа структур. Чтобы любой новичок чувствовал себя комфортно.

И сразу же:

это не совсем так, что переменные могут там создаваться но не обязаны

Сели в лужу, так хоть не изворачивайтесь, а то выглядит неприлично.

И кстати, главная разница наблюдается ПРИ ПЕРЕДАЧЕ значения в вызов функции, для value type она происходит через стек (кроме каких то псевдофункций вроде вроде лямбда выражений), даже если само значение сидело на куче будучи полем в какой нибудь lambda функции, иначе случались бы ОЙ какие неприятности со сторонними эффектами.

И главное вы не умеете читать ключевые слова, мы именно такое поведение обсуждали с Арви, чтобы среда сама определяла как эффективнее хранить данные, на стеке или на куче, когда их можно уничтожить (так как доступ к ним гарантированно теряется и т.д.) Не понимаю к чему эти ваши попытки поучать и что то рассказывать про управление памятью. Вы не преподавателем работаете (с таким то "владением" формальной логикой) ??? :-)

Преподавателем Сергею уже не работать. С его воинствующим отрицанием науки, нежеланием использовать научные термины и агрессивным стремлением навязать окружающим личный профессиональный жаргон — это уже ум наёмного работника, а не учёного или учителя.

Таким платят за хороший конечный продукт, а какими словами Сергей жонглирует, для общества давно не важно. Коллегам и подчинённым приходится привыкать, насилие над мозгом компенсирует хорошая зарплата — которую нам, к счастью, за такое не платят. Давайте оставим его воевать со своими тараканами и вернёмся к обсуждению нового входного языка ПМК.

Кидать все переменные в кучу — возможно, мы к этому придём. Но при правильном проектировании системы необходимости не должно возникнуть. По крайней мере в Обероне удаётся успешно использовать блок для глобальных переменных.

Кстати, я использовал два современных термина из книги 2015 года, спасибо переводчикам-профессионалам — русская терминология прокладывает себе путь, не все пряники англоязычным:

  1. Область памяти (англ. storage space) — на жаргоне Сергея, набранным на помойке зарубежных коммерческих систем, это внезапно опять «класс». Зачем ООПшники в который раз «перегружают» многострадальное слово «класс»? Видимо, таковы актуальные соображения классовой борьбы.
  2. Блок (англ. block) — область, объединяющая код и данные (code and data space). Блоки выделяются для модулей в области блоков (англ. block space).

Когда переменная размещена в блоке, а не куче, доступ к ней осуществляется гораздо быстрее и выгоден по размеру кода. С другой стороны, если заимствовать списки из Лиспа, их придётся размещать в куче — возможно, вместе с их элементами.

Это из трупа страуса, сишно-плюсовая терминология обозначающая виды памяти по размещению и доступу, довольно запутанная.

Термины могут быть только в науке. Сишно-плюсовый новояз это профессиональный жаргон, не более того.

Почему я так и отношусь трепетно к книжке про Оберон и её переводу — у нас появляется твёрдая почва, чтобы рассуждать на родном языке о меняющихся вещах, которые в каждом языке каждый Вася Пупкин как захочет, так и называет. Нам, кстати, тоже придётся вводить свои слова для описания входного языка ПМК. И чем лучше у нас получится следовать терминологии, тем лучше.

Выстраивание правильной терминологии это важная часть работы учёного. Именно за это профессора зарплату получают. Это и есть настоящий, бесценный результат проекта Оберон — код операционной системы и компилятора лишь поясняют, весьма точно, что профессор называет той же областью памяти, кучей или блоком.

Теперь точные термины компьютерных наук приходят в русский язык. Читаю английское и русское издание, радуюсь. :-) Например, мы приверженцы разных школ — вы говорите «парсер» (по современному), я по-старинке «паржер». Переводчики, видимо, с этим конфликтом уже сталкивались. Мы-то друг друга понимаем. Но если нам нужно будет сойтись на общем языке, мы можем использовать их нейтральный вариант «синтаксический анализатор».

При беседе на английском языке этот термин звучит однозначно parser. Английская терминология выстроена хорошо. Хотя разные Страуструпы тоже делают свою работу, и их предложения чаще влияют на развитие науки, чем предложения наших специалистов.

AtH wrote: Преподавателем Сергею уже не работать. С его воинствующим отрицанием науки, нежеланием использовать научные термины и агрессивным стремлением навязать окружающим личный профессиональный жаргон — это уже ум наёмного работника, а не учёного или учителя.

Понимаю, что переход к ad hominem легче, чем аргументирование по сути, однако - очередной забавный ляп. Где, кому и что я преподаю можно узнать из соответствующих научных публикаций, размещенных в том числе в открытом доступе.

Очевидно то, что легко доказывается. Фразы типа "Там же где создаются динамические структуры и связываются друг с другом, очевидно необходима сборка мусор" совершенно неочевидны. Фразы типа "подсчёт ссылок не годится для ситуаций, где могут быть зацикленные структуры, поэтому его можно сразу отбрасывать", мягко говоря, некорректны с инженерной точки зрения. А фразы типа "автоматическое управление памятью избавляет от необходимости передавать всё по значению" просто ложные.

Очевидно лишь, что программист, высказывающий подобные мысли, сильно ограничен в своих знаниях предмета так как, скорее всего, пришел в отрасль без базового образования и сразу приступил к программированию в средах типа Java/C#/VB.

Остаётся только в бессильной злобе перечислять неочевидность очевидных всем кроме вас фраз и пытаться оскорбить собеседника, гадая о его образовании на не очевидной кофейной гуще. А уж выдёргивать слова из контекста - это совсем для нищих духом. Может быть вы всё таки дадите себе труд прочитать ВЕСЬ текст, а не отдельные фразы ?

Там написано, что ПОЛЬЗОВАТЕЛИ ПМК не обладают вашим замечательным базовым образованием и опытом писания на чём то отличном от Java/C#/VB. Если у вас нет сборки мусора (куда безусловно относится и подсчёт ссылок), то вы складываете управление памятью на хрупкие плечи не ожидающего от вас такой пакости ПОЛЬЗОВАТЕЛЯ ПМК.

А ещё там написано, что так как пользователь скорее всего БУДЕТ создавать циклические ссылки, мы не можем втюхать ему счётчик ссылок, в качестве негодного сборщика мусора.

Если фраза "автоматическое управление памятью избавляет от необходимости передавать всё по значению" ложная, то наш капитан очевидность должен был сперва доказать её ложность.
Хотите сказать, что с автоматическим управлением памятью остаётся необходимость передавать ВСЕ аргументы функций(процедур, подпрограмм) по значению?

Может быть вам пора снова получить ваше базовое образование, вы видимо прогуливали курс логики :-) А если вы хотите, чтобы к вашим словам отнеслись серьёзно, то просто обязаны сформулировать свои мысли в корректной инженерной форме, а не пытаться подсунуть нам какую мутную кашу про простоту сферических коней в вакууме, а все аргументы оспаривать в манере "это не корректное с инженерной точки зрения высказывание".

Я тут уж все бюджеты извёл, даже с запасом. Пришлось книжку качнуть (русский перевод).
Просмотрел по диагонали. Про гуйню местами занятно. А в целом книга ни о чём.
Всякая "Архитектура компьютера" Таненбаума более забориста. А язык Оберон (не знаю может Active Oberon интереснее), это какой то недозревший Delphi 100 летней давности. Вы точно хотите тратить свою жизнь на это ? Может лучше сразу закурите Ocaml и Haskell, потом документы Microsoft Research по поводу создания правильных с формально доказуемыми свойствами операционных систем на правильных по науке сделанных языках (Singularity OS) ? От Вирта с Обероном, уж извините, несёт нафталином гораздо сильнее, чем от Форта и древних реализаций Лиспа.

Я реально не хотел обидеть, просто не могу не сказать, как на самом деле думаю. Имхо, мы должны брать от прошлого самое лучшее, но двигаться то в будущее. Я вот понимаю, что ни исконный Форт ни Common Lisp даже в современной реализации этому будущему уже не удовлетворяют, благо что они программируемые языки программирования и их можно облагородить и многое починить и исправить. Но Оберон то - обычный дубовый язык с фиксированной грамматикой и, что хуже, семантикой. Можно из него взять какие то идеи наверное и дух Вирта, но облагородить не получится.

Оберон точно интересней Дельфи. Но давайте сперва про нафталин. В науке использование инструментов, разработанных Ньютоном или Эвклидом, не зазорно. Наоборот, удержавшееся в науке веками это самое мощное и интересное. Хотя происходят революции, вроде теории относительности и квантовой механики, законы Ньютона до сих пор работают и используются на практике.

Дельфи и Object Pascal с их наследником Free Pascal это успешная реализация небольшой выборки из тех фундаментальных знаний, которые «впервые — и в наиболее чистом виде» сформулированы в Обероне. Так архитектор изучает научную литературу, выбирает из справочников подходящие формулы и проектирует полезный дом или мост через реку. Разумеется, изучать архитектуру других зданий и мостиков надо — но пренебрегать первоисточником и кормиться исключительно объедками непрофессионально.

Оберон не просто оказался полезной научной теорией, влияя на множество коммерческих трансляторов от Дельфи до Java — он послужил основой для последующих работ в компьютерных науках (тот же Active Oberon). Эти достижения будет легко использовать, т.к. последующие языки развивают терминологию Оберона, вводя минимум нужных сущностей, а не «полиморфно инкапсулируют в статических объектах класса».

Ну и самое главное. Сейчас русская информатика, преподающаяся в университетах и школах России, пытается избавиться от превращения в НИИ богатейших зарубежных корпораций. Лучшие учителя страны бьются за выгон всяких C++ из университетских аудиторий, чтобы распространять и развивать научные знания, а не готовить за бюджетный счёт обезьянок-кодеров для корпораций.

Оберон выбран флагманом этой борьбы и «трачу свою жизнь на это» я далеко не в одиночку. Оберон не просто «работает» и позволяет писать программы — он стабилен и за десятилетия меняется незначительно, объём знаний минимален и может быть изучен за семестр. Оберон разработан в рамках института науки и наследует Паскалю, который уже хорошо себя показал в науке и образовании России.

Скаченная вами книга — да, это такой Таненбаум, только в области языков программирования. Финский студент, обученный на Таненбауме, смог успешно разработать Линукс. Оберон поможет успешно разработать входной язык ПМК.

Согласен про фиксированную грамматику и синтаксис Оберона. Это даже было целью профессора — сделать минимальный, но практичный набор языковых средств для формальной записи алгоритмов.

Достоинство в том, что эти средства уже стали стандартными. Они носятся в воздухе со времён Паскаля, на них нацелено преподавание информатики в России. Осваивать их «необразованному программисту» ПМК будет просто.

Гибкость в Обероне появляется, когда из этого небольшого числа лего-кирпичей разработаны модули. Тут уже Оберон курирует, как эти модули соединять друг с другом — не в последнюю очередь с помощью проверки и расширения типов. Здесь программисту и потребуется определённая культура, которую проектировщики языков часто бросают на произвол.

Тут ещё вопрос, кто кого облагораживает. Использование науки облагораживает человека и помогает проекту. Изучив Оберон и позаимствовав из него пару идей, корпорация Sun смогла создать Java — вполне себе успешный язык, повлиявший на весь земной шарик. Нам тоже надо свою часть работы проделать, создавая компактный диалект Оберона и скрещивая его с входным языком ПМК. Мне любопытно, что на этом пути сохранится от Форта и может оказаться полезным от Лиспа.

Тем более, что в случае Лиспа можно посмотреть как на уже построенное здание компактного языка RPL, так и на стоящую за ним науку МТИ. Ваши знания по Лиспу здесь востребованы — в диалоге с вами можно будет как минимум найти ответ на вопрос «как возникшую проблему решили в Пало-Альто».