-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Смена (уточнение) концепции #33
Comments
Функции реализованы в рантайме, поэтому рантайм может распечатывать содержимое копилки в отладочном дампе (или при завершении программы при наличии макроса R05_DUMP_BURIED). Уточнена документация на эти функции. Остальные функции копилки добавить сравнительно несложно, добавлю их по потребности.
Согласно Mazdaywik/refal-5-framework#5, библиотечные файлы фреймворка должны находиться в переменной среды |
Помимо неявно декларируемой цели
была и другая неявная цель: Написать прозрачный задокументированный компилятор Рефала, который мог бы служить учебным пособием по написанию компиляторов Рефала. Отсюда, кстати, и минимализм — чем меньше объём, тем проще изучить и понять, и хорошая подробная документация. Т.е. это должен быть как Minix, но компилятор Рефала. Среди целей, описанных в документации, понятность и прозрачность исходников (следствие «учебного пособия») обозначены как второстепенная цель и граничное условие: Lines 28 to 34 in 035ffcd
Разумно эту цель проявить и внести в документацию. |
Критикуя, предлагайСтарая концепция раскритикована, поставлены новые задачи, они, по большей части, выполнены, но новая цель (на которую направлены эти задачи) явно не артикулирована. Попробуем её выявить, рассмотрев особенности актуального и предполагаемого (#35, #38) Рефала-05.
При решении задачи #38 уже почти любая программа на Рефале-5 будет компилироваться Рефалом-05 и, возможно, работать точно также. Компилироваться не будут те программы, в которых есть дублирующиеся внешние ссылки, неиспользуемые функции и внешние ссылки. Работать будут иначе программы, которые ссылаются на отсутствующие возможности встроенных функций (например, длинную арифметику) или используют Таким образом, высока вероятность (после #38), что программа, написанная для Рефала-5, будет компилироваться Рефалом-05 и выполняться с тем же поведением без дополнительных правок, вроде добавления всяких '*$EENUM`’ов. Так что, можно говорить, что Рефал-05 — не только «совместим с Рефалом-5», но и является его альтернативной реализацией! Неполностью совместимой альтернативной реализацией. А почему не полностью совместимой?
Отдельно остановлюсь на ошибках о неиспользуемых объявлениях и определениях. Конечно, можно их сделать и предупреждениями, и вообще убрать (заменив на молчаливое удаление таких узлов из синтаксического дерева). Но они полезны — и как воспитательная мера, и для упрощения рефакторинга (переписал код, компилятор напоминает удалить неиспользуемые). Кроме того, имена считаются используемыми (и будут считаться после #38!), если в тексте программы есть идентификатор с данным именем:
Можно возразить, что существуют корректные программы на Рефале-5, такие что (а) на них выдаёт ошибку Рефал-05, (б) после удаления «неиспользуемой» локальной функции программа перестанет работать или станет работать неправильно. Например:
Эта программа, будучи откомпилированной и запущенной Рефалом-5, выдаст
Компилятор Рефала-05 выдаст ошибки на функции
Таким образом, в одном месте поведение изменилось (программа стала работать иначе), в другом и вовсе упала. Но ведь, даже если бы эта программа компилировалась Рефалом-05 молча или с выдачей предупреждения (вместо ошибки), то она и так работала бы иначе. В данном случае она тоже вывела бы
но это совпадение. Данная программа опирается на поведение функции Вообще, можно показать, что если
то эта программа не работала бы правильно на Рефале-05, если бы он такую программу компилировал бы молча. Так что данное предупреждение я оставлю. ПредлагаюПредлагаю определить Рефал-05 так: Рефал-05 — альтернативная реализация Рефала-5, минималистичная, эффективная, прозрачная и компилируемая в Си. Реализация имеет отличия в семантике некоторых встроенных функций, сделанные ради минимализма и компиляции в Си. |
Переписать сопоставления с образцомАктуальная реализация сопоставления с образцом сложная, костыльная и неэффективная. Она унаследована от Простого Рефала, а как правильно компилировать сопоставления с образцом, я тогда не знал. Костыли в ней, например, в необходимости запоминать диапазоны при сопоставлениях с открытыми переменными. Предлагается сделать сопоставления с образцом в духе диссертации Романенко — каждый распознанный элемент кладётся на стек, диапазоны открытые — это просто края уже распознанных элементов. Система команд Романенко предлагает стек времени выполнения и два «регистра» границ — следствие того, что команды интерпретируются и ради уменьшения объёма байткода (у команд меньше аргументов). Очевидно, что положение сопоставленных элементов на стеке известно во время компиляции, так что вместо стека будет простой массив ячеек и команды будут ссылаться на ячейки явным образом. Такое представление системы команд очевидным образом допускает выделение общих префиксов — оптимизацию совместного сопоставления с образцом в её простейшем варианте. Возможно, её реализую, если это не займёт много кода. Сопоставление с образцом в духе диссертации Романенко будет гораздо проще задокументировать — фактически нужно пересказать своими словами соответствующий раздел учебника Турчина. Тоже самое предполагается в дальнейшем сделать и в Рефале-5λ — bmstu-iu9/refal-5-lambda#204. P.S. Перенесено в отдельную заявку: #40. |
Поведение на избыточные
|
Теперь код типа $EXTERN …, Prout, …; приводит к ошибке в компиляторе Рефала-05. Согласно Mazdaywik/refal-5-framework#9 здесь должно быть предупреждение.
Это не следует из других явно заявленных целей, но при этом соблюдается. Значит, это самостоятельная цель. Назовём её педантичность. Рефал-05 педантичный — в нём некоторые стилистические ошибки считаются ошибками синтаксиса. Имеет смысл это направление расширить и углубить. |
Спасибо. Именно благодаря Рефал-05 написал интерпретатор Рефала. При этом для меня, привыкшего к императивным языкам, наибольшую ценность представляли исходники на Си, как генерируемые, так и refal05rts.*. |
Спасибо, @STrusov! Значит, Рефал-05 написан не зря! |
Помимо семантики расхождения в семантике Речь идёт о стартовой точке. В Рефале-05 стартовая точка всегда
Для устранения этого расхождения проще всего входную точку Рефала-05 заменить на
В этом случае исходники, содержащие входную точку |
Ещё одно отличие, которое не позволяет считать Рефал-05 подмножеством Рефала-5 — функция Есть мысль довести до предела совместимость между Рефалами — заставить функцию |
(Дамп потока сознания.)
Декларированные цели
Недавно я задумался: в Рефал-05 сравнительно несложно внедрить условия и блоки (upd: #35). Для этого потребуются совсем минимальные изменения рантайма (рекурсивный вызов рефал-машины и псевдофункции
FuncName$n
) плюс некоторое количество кода на Рефале (парсер, дерево, генератор). Т.е. технически проблем никаких нет. Но есть идеологические проблемы — противоречие целям, заявленным в README и документации.Я затрудняюсь сказать, останется ли в этом случае Рефал-05 минималистичным. Возможно, останется, возможно, нет, нужно смотреть, на сколько объём кода увеличится.
Но в любом случае пришлось задуматься над целями и пересмотреть их. Исходно цели декларировались так:
Но получился язык, в котором в отличие от Рефала-5, идентификаторы являются именами функций (отсюда костыль с псевдокомментариями и
$ENUM
) и есть синтаксис для нативных вставок. Обе вещи несколько противоречат минималистичности…В процессе разработки спонтанно родилась новая цель: компилятор как фреймворк для разработки инструментальных средств, и частично она достигнута (однако, не доведена до ума — см. #27).
Критика концепции
Получился язык, не полностью минималистичный, но частично совместимый с Рефалом-5. Важнейшие отличия от Рефала-5
*$ENUM
и*$EENUM
. Без псевдокомментариев исходники невозможно было бы собрать Рефалом-5.Можно ли было бы, сохранив стремление к минимализму, получить другой результат?
Можно было бы генерировать интерпретируемый код по диссертации Романенко, код прозрачен, компактен и эффективен. Тогда бы «встроенные функции» пришлось бы делать встроенными. Расширяемости не было. Но при этом получилось бы подмножество Рефала-5. Точное подмножество без геморроя с объявлением пустых функций.
Можно было бы пожертвовать раздельной трансляцией — всю программу транслировать в один исходник на Си. В этом случае тоже символы-слова были бы символами-словами.
Можно было бы оставить C++ и трюк с генерацией идентификаторов.
Можно было бы добавить отдельную фазу линковки, которая строит глобальную таблицу идентификаторов. Это, конечно, несколько усложнило бы компилятор.
Можно было бы пожертвовать эффективностью, генерируя таблицу идентификаторов во время выполнения. Например, в начало каждой функции добавлять вызов функции отложенной инициализации:
В этом случае тоже получили бы классический Рефал-5 или хотя бы его точное подмножество. Но это тоже несколько усложнило бы компилятор.
Почему так вышло? Потому что неявной подразумеваемой целью была другая:
Сделать Простой Рефал совместимым с Рефалом-5, эффективным и компилирующимся в Си.
Отсюда раздельная компиляция, как в Простом Рефале. Отсюда странная реализация символов-слов, поскольку в чистом Си их по-другому не сделаешь, а проверки времени выполнения снижают эффективность. Отсюда желание сохранить расширяемость языка — каждая функция компилируется в одноимённую функцию на Си.
В любом случае, компиляция в Си не вытекала из цели минимализма, а сама была неявно декларируемой целью. И было не декларируемое явно стремление сохранить свойства Простого Рефала — эффективность, раздельную компиляцию и удобный интерфейс с Си. Поэтому получилось то, что получилось.
Но Рефал-05 как язык обладает тем же недостатком, что и Простой Рефал: он не нужен. Не нужен новый диалект Рефала, который не совместим с кодовой базой и не привносит ничего принципиально нового.
Чтобы программу на Рефале-5 можно было откомпилировать Рефалом-05, нужно, чтобы в ней не было копилки (она выкинута), не было символов-слов в двойных кавычках, остальные символы-слова были именами функций в текущей области видимости, в ней не использовались условия и блоки (для этого её можно пропустить через 5-to-basis). Слишком много возни.
Отсюда следует и ненужность фреймворка-компилятора. Инструментальные средства, разрабатываемые на нём, будут столь же бесполезны.
Кроме того, наличие нативных вставок затрудняет реализацию инструментальных средств. Один из подпунктов в #27 гласит:
Я выделил ключевую в этом контексте фразу: без нативных вставок. Потому что если в файле есть хотя бы одна нативная вставка, то никакие преобразования кода мы сделать не можем. Мы не можем, например, переименовать или удалить локальную функцию — мы не знаем, использует ли её нативная вставка. Мы не можем переставлять нативные вставки и функции с ними местами. Кроме того, нативные вставки гвоздями прибивают нас к языку реализации.
Нативные вставки безусловно удобны при изменениях представления данных, например, при описаниях функций через дескрипторы. Пример такого изменения — #14, 5dc0c8e — в коммите не менялись объявления функций, см. также и
Library.sref
в bmstu-iu9/refal-5-lambda@6f1a366. Но того же эффекта можно было достичь и аккуратным использованием макросов.Нативные вставки позволяют смешивать в исходном файле код на Рефале и код на целевом языке, но это преимущество немного сомнительно. Оно было актуально раньше в Простом Рефале/Рефале-5λ, поскольку позволяло смешивать оба языка в
Library.sref
, сохраняя при этом единый файл. Сейчас это не так актуально и там (поскольку если уж рантайм рассыпался на кучу файлов, можно рассыпать иLibrary
), и здесь (встроенные функции Рефала-05 несложно описать и на Си).Что же делать?
Менять концепцию.
Хороший фреймворк для Рефала-5, безусловно, нужен (по моему мнению,
prefal
— плохой фреймворк). Фреймворк для странного языка Рефала-05 не нужен. Компилятор странного Рефала в Си пускай будет.Поэтому есть предложение отказаться от идеи делать фреймворк на базе Рефала-05, вместо этого развивать 5-to-basis как подобный фреймворк. Парсер в том проекте полностью поддерживает классический Рефал-5.
(Либо, вообще можно подумать о фреймворке на базе Рефала-5λ.)
Задачу #27 перенести в 5-to-basis и решить её там.
В Рефал-05 можно добавить условия и блоки, фронт-энд сделать общим с 5-to-basis. Соответственно, здесь останется только рантайм, кодогенератор и расширения парсера (разбор псевдокомментариев
*$ENUM
, проверка имён-идентификаторов).Как унифицировать фронт-энд между обоими проектами — отдельный вопрос.
Из Рефала-05 выкинуть нативные вставки,
Library.ref
переписать на Си. В ней на Рефале написаны толькоMu
иListOfBuiltin
, их переписать на Си несложно. Можно добавить дополнительные встроенные функции для большей совместимости с классическим Рефалом-5.5-to-basis видоизменить так, чтобы он мог компилироваться Рефалом-05.
Ревизия 2019-03-31 — подзадачи
#27в 5-to-basis (перенесена: Уточнение API и примеры использования фреймворка refal-5-framework#4).Arg
Смена (уточнение) концепции #33 (comment).В комментарий этот список выносить нельзя, поскольку тогда интерфейс GitHub его не увидит.
The text was updated successfully, but these errors were encountered: