Блог типа

Добавил Вики

Вики-статьи проекта LOMO лежать будут тут. Тем временем, продвигаются работы по осмысливанию методом тыка параллельной модели работы агентов. Надо соблюдать осторожность с параллелизмом в Go. Иногда очень неприятные моменты проявляются.

To Ast Or Not To Ast

AST или не AST?

Каждый раз возникает проблема, где хранить AST, хранить ли его вообще и если не хранить, то как быть? Однозначно хранить. Во-первых, изучать вывод компилятора в лог утомительно, лучше сразу сохранить структуру AST и поизучать ее на предмет ошибок. Во-вторых, AST должна быть слегка независима от модулей компилятора, поэтому лучше будет, если на момент передачи AST в интерпретатор/кодогенератор контекст компиляции уже будет потерян. И в-третьих, для экспериментальных языков выводом в AST все может и закончиться, ибо дешевле и проще проинтерпретировать AST, нежели писать кодогенератор для птичьих IR типа llvm.

Для хранения AST уже перепробовал много разных форматов. Видимо, самый удобный все-таки XML, несмотря на общую многословность.

Lomo

Про LOMO

Приступил к реализации LOMO, language of message objects, такой себе наследник LoLa, только вместо радиодеталей будут программные агенты.

Язык декларативный, попроще чем LEAF в каком-то смысле, пока двигаюсь интуитивно, без EBNF и даже смутного понимания, как оно устроено в декларативных языках.

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

Чо Тут

Что это такое?

Практикуюсь в изобретении бессмысленных вещей. После проекта fw, в котором интерпретировался выхлоп уже готового компилятора, написание своего компилятора было неизбежным. Вот он и реализовался. Проект компилятора и интерпретатора. Все довольно упростилось, язык LEAF структурно даже проще обычного Оберона. Система типов банальная. Хотя есть комплексные числа. Но это простой тип, он не усложняет систему вообще. Зато списки есть, и множества для любых значений, и ассоциативные массивы. Все довольно примитивное.

Основная особенность в том, что все статическое. И передается по значению. Есть пара обобщенных типов: значение вообще и указатель на значение вообще, вот по указателю уже динамическое значение будет, в куче. Работа с ними (с значениями вообще) получилась неудобной, ведь язык строго типизированный.

Зато структурно в языке всё очень по Дейкстре. Хотя он бы не одобрил такое обращение со сложными структурами (я про передачу по значению). Процедуры, два вида циклов (и никаких FOR), ветвление. Модульность уже по Вирту, почти как в Обероне. А пользовательских типов нет. Да и зачем, основная идея в том, что пользовательский тип это обязательно либо RECORD либо ARRAY OF, RECORD хорошо ложится на ассоциативный массив, а ARRAY на простой список. Дальше возникает кагбэ “проблема”: тип полей и элементов массива не указать, в LEAF значение в списке всегда ANY.

Ну что тут поделаешь, язык LEAF как раз и нужен чтобы проверить, как оно вообще, жизнеспособна ли такая идея или нет. Первая версия компилятора и рантайма написана на golang где-то за месяц. Теперь надо остановиться и подумать, как это сделать эффективным и не глючным.

P.S. Этак можно и лолу переписать на golang, где бы только время взять.

Подробнее

Подробнее про придумку

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

Попробую описать будущую модель среды и агентов. Напомню, есть агенты, у них есть входные и выходные каналы сообщений, в которые могут быть переданы собственно сообщения.

Изначально нет никого, в какой-то момент поступает команда на создание первого агента известного типа. Этот агент (Топ) может создать конечное число других агентов, а может и не создать. Создание агента равносильно объявлению переменной c типом – идентификатором модуля.

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


Ситуация, когда Топ создает агентов, и не ожидает от них сообщений тоже возможна, при этом дальнейшей судьбой этих агентов Топ может не интересоваться, или интересоваться на общих основаниях, широковещательно (продумать этот момент)

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


В свою очередь созданные агенты (Фиб, Факт) реально вступают в действие после того, как возник запрос на их данные в итерации Топа, после ее окончания. Эти агенты получают так же сообщение во входные каналы n.

Фиб проверяет значение n и решает, что необходимо запросить значение для выходного канала у другого агента, попутно Фиб инициирует другого агента Фибi, которому передает значение входного параметра, уменьшенное на 1. Так как возник запрос, и больше нет действий, итерация завершается и переходит в состояние ожидания. Однако, если условие n # 0 становится ложным, ожидание значения для res реализуется по месту, константой, и следовательно, итерация Фибi завершается, одновременно с этим отправляя сообщение Фибi-1, который тоже завершает ожидание. В итоге, в первоначальный Фиб придет значение n-го числа Фибоначчи.

Факт поступает по другому. Он не инициирует своих собратьев, но вместо этого каждый раз передает нужное значение в собственный регистр x, который сохраняет значение между итерациями одного агента Факт (после завершения итераций регистр всё же пропадает). Так как выходное значение, которое требуется от агента не передано в выходной канал, итерация повторяется. Здесь возникает странный момент, что считать завершающей итерацией агента? Удовлетворение всех выходных сообщений, всех ожиданий и отсутствие выполняемых действий? И опять проблема дедлоков.

Временной график

↓шаг агент→ Top Fib Fact Fib…
0   NEW      
1   <-Fib, <-Fact      
2     NEW NEW  
3     <-Fib @  
4       @ NEW
..   здесь порождаются Fib i-ые .. ..res<- ..
N-3         res<-
N-2     res<-    
N-1   x<-, y<-