flang — язык с доказуемым завершением Своя поверхность: как написать тот же язык по-французски
0%

Своя поверхность: как написать тот же язык по-французски

Своя поверхность: как написать тот же язык по-французски

Обычный язык программирования пишут по-английски, и это не решение, а привычка. if, while, return — английские слова, и человек, для которого английский не родной, каждый день читает код на языке, на котором не думает.

В flang слова языка живут в таблице, а не в грамматике. Таблица знает четыре набора слов — русский, английский, эсперанто и китайский. Компилятор не спрашивает, на каком языке написан файл: он узнаёт слова. Такой набор слов называется поверхностью.

Одна программа, четыре записи, одно дерево

В репозитории языка лежит факториал, записанный четырежды: docs/examples/rosetta/factorial.flang, factorial-english.flang рядом с ним, docs/examples/surfaces/factorial.eo.flang и factorial.zh.flang. Вот одна и та же функция на русской, эсперантской и китайской поверхностях:

тотальная функция «Произведение»
  принимает элементы: список числа
  возвращает число
  пример «Произведение четырёх»
    дано элементы равно [1, 2, 3, 4]
    ожидается 24
  свёртка элементы начиная с 1 как акк и эл → акк умножить на эл
totala funkcio «Produto»
  akceptas eroj: listo de nombro
  redonas nombro
  ekzemplo «Produto de kvar»
    donite eroj egalas [1, 2, 3, 4]
    atendata 24
  faldo eroj komencante per 1 kiel akumulo kaj elem → akumulo fojoj elem
完全 函数 «乘积»
  接受 诸项:列表 数字
  返回 数字
  示例 «四数之积»
    给定 诸项 等于 [1,2,3,4]
    期望 24
  折叠 诸项 起始于 1 作为 累加 和 当项 → 累加 乘以 当项

Проверяется это командами, которые можно повторить в клоне репозитория:

$ flang check docs/examples/rosetta/factorial.flang
docs/examples/rosetta/factorial.flang: проверено — разбор, типы, завершаемость, ядро и примеры; замечаний нет
$ flang check docs/examples/surfaces/factorial.eo.flang
docs/examples/surfaces/factorial.eo.flang: проверено — разбор, типы, завершаемость, ядро и примеры; замечаний нет
$ flang check docs/examples/surfaces/factorial.zh.flang
docs/examples/surfaces/factorial.zh.flang: проверено — разбор, типы, завершаемость, ядро и примеры; замечаний нет

flang ast показывает, почему так: деревья разбора совпадают по форме. Мы сравнили вывод flang ast всех четырёх файлов на 0.7.29, убрав позиции в тексте и заменив строки заглушкой: пять функций, одинаковые узлы, типы и примеры. Различаются только имена, которые написал автор, — элементы, items, eroj, 诸项.

Поверхность кончается на лексере: она не влияет ни на типы, ни на доказательство завершения.

Где живут слова

Таблица — в flang/self/lexer.flang, в самом компиляторе, написанном на flang. У неё две формы, обе строками:

|тотальная:total|  totala:total|  完全:total|
|total@ru:тотальная|total@en:total|total@eo:totala|total@zh:完全|

Первая отвечает на вопрос «какое понятие стоит за этим словом» — ею пользуется разбор. Вторая — обратная: «каким словом назвать понятие на такой-то поверхности», ею пользуется диагностика.

Понятий в таблице на 0.7.29 — 159 (счёт пар понятие@поверхность в flang/self/lexer.flang):

поверхность понятий
русская 159
английская 158
китайская 143
эсперанто 138

На всех четырёх открыто 137 понятий. У 22 слова где-то нет, и это решение, а не недоделка.

Поверхность не обязана быть полной

Пример — эсперанто и слово «модуль». На эсперанто напрашивается modulo, но это слово уже занято: английская поверхность называет им остаток от деления (opMod@en:modulo). Одно слово не вправе называть две конструкции, поэтому эсперантская поверхность здесь молчит, и factorial.eo.flang начинается английским словом:

module «Faktorialo»

Вот все 22 понятия, у которых на какой-то поверхности слова нет:

понятие по-русски нет на
alias это en, eo, zh
ensures, requires обеспечивает, требует eo, zh
claim, qed утверждаем, следовательно доказано eo, zh
forall, exists, suchThat, namely для всех, есть такой, таких что, а именно eo, zh
induction, follows индукция по, следует eo, zh
byExample, byHypothesis, byProperty по примеру, по предположению, по свойству eo, zh
decreases убывает eo, zh
module, not, nested, embedding, supervision, hash256 модуль, не, вложен объект, вложение, надзор, хеш256 eo
opPercent процентов zh

Закономерность видна: на эсперанто и китайском не открыт словарь доказательств. Причина записана в docs/surfaces.md репозитория: у этих понятий нет устоявшегося слова ни в эсперанто, ни в китайском, а придуманное слово хуже отсутствующего.

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

模块 «混合»

完全 函数 «放在前面»
  接受 首项:数字,诸项:列表 数字
  返回 列表 数字
  обеспечивает «на один длиннее» (长度 结果) 等于 ((长度 诸项) 加 1)
  示例 «放入空列表»
    给定 首项 等于 1
    给定 诸项 等于 空列表
    期望 [1]
  前置 首项 到 诸项
$ flang check --proof mix.zh.flang
…
  постусловие «на один длиннее» функции «放在前面» — доказано сведением цели с телом функции …
mix.zh.flang: ПРОВЕРЕНО САМОСТОЯТЕЛЬНО — утверждений 1: доказано 1, …

Одна граница всё же есть, и она не в словах, а в генерации кода. Китайская программа переводится в python, java, csharp и elixir, а c, go, rust и другие цели отказываются: иероглифические имена схлопываются в один идентификатор, и flang emit честно называет столкновение («имена «乘积» и «前置» дают один идентификатор»).

Сообщения компилятора по-английски

Поверхность меняет слова программы, а язык сообщений задаётся отдельно: переменной FLANG_LANG=en или строкой language = en в .flangrc. Переводы лежат в таблице flang/messages/catalog.tsv. На 0.7.29 у этого две оговорки, обе проверены запуском:

  • переведены рамка и итог (FLANG_NOT_TOTAL in file …, line 10, column 19, not verified — problems found: 2), а текст большинства отказов остаётся русским — английский шаблон есть у 13 кодов из 144 (docs/guide/settings.ru.md);
  • в готовой сборке v0.7.29 таблицы переводов нет, и бинарник отвечает по-русски с предупреждением no message catalog was found. Работает, если указать таблицу из клона: FLANG_MESSAGE_DIR=<клон>/flang/messages.

Что придётся решить, а не перевести

Поверхность — не словарь, и главная работа в ней не переводческая.

Слово должно быть одно на понятие. История с modulo — типичный случай: в любом языке найдётся слово, которое хочет назвать две вещи. Решает это автор языка, и решение записывается в таблицу вместе с причиной.

Слово должно быть отделимо. В китайском пробелов внутри фразы нет, поэтому между ключевыми словами китайской поверхности пробел обязателен — ровно как между тотальная и функция. Полноширинные : , ( ) делят поток наравне с обычными.

Буквы должны быть известны лексеру. Надстрочные буквы эсперанто (Ĉ Ĝ Ĥ Ĵ Ŝ Ŭ) стоят в таблице заглавных букв flang/self/lexer.flang отдельными парами: без них Se в начале строки не свелось бы к se. Для французского то же касается É È Ê À Ç Ô Û.

Как добавить французскую поверхность

1. Выбрать слова. 159 понятий, из них хотя бы 137 — те, что открыты на всех поверхностях. Для каждого нужно французское слово, не занятое другим понятием ни на одной поверхности: fonction, accepte, retourne, exemple, étant donné, attendu, si, alors, sinon. Слова из нескольких слов допустимы.

2. Дописать таблицу. Обе формы в flang/self/lexer.flang: прямую (fonction:function) и обратную (function@fr:fonction). Компилятор написан на flang, поэтому правка — это правка программы на flang, и она проходит те же проверки. После неё компилятор нужно пересобрать (глава «Компилятор, написанный на самом себе»).

3. Добавить буквы. Диакритику — в таблицу заглавных, рядом с эсперантской.

4. Написать пример и сравнить деревья. factorial.fr.flang, слово в слово с русским оригиналом:

$ flang check docs/examples/surfaces/factorial.fr.flang
$ flang ast docs/examples/surfaces/factorial.fr.flang > fr.json
$ flang ast docs/examples/rosetta/factorial.flang     > ru.json
# деревья обязаны совпасть по форме: те же функции, узлы, типы и примеры

Если форма разошлась, какое-то слово попало не на то понятие, и это видно сразу.

Чего поверхность не даёт

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

Нашли неточность? Выделите фрагмент текста — рядом появится жучок.

Нужен разбор именно вашей ситуации?

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

Доска запросов