Andy Melnikov (nponeccop) wrote,
Andy Melnikov
nponeccop

Category:

Требования к языкам, компилирующимся в JS

По просьбе общественности, детализирую требования

Вот мне интересно, есть ли языки, компилирующихся в JS и удовлетворяющие требованиям:

1. человекочитаемый выходной код

- красиво отформатированный (pretty printed, не в одну строчку и с отступами)

- с понятными идентификаторами, передающими смысл программы (в противоположность состоящим из фиксированного префикса и sequence number, вроде a$42, vBA0EF). Эти идентификаторы можно синтезировать из идентификаторов входной заведомо читаемой программы и выполняемых компилятором трансформаций. Например, если у нас была функция fold c локальной переменной х, и компилятор заинлайнил - то x или fold_x в выходном файле всяко лучше x1 или v0233 в том месте, где раньше был х.

- с понятной структурой - если компилятор генерирует из 100 функций на входе 1 функцию со 100 локальными переменными - то он в процессе компиляции разрушил входную структуру, а выходной не создал. Выходную структуру опять же можно создавать из входной, но также можно эвристически синтезировать с нуля. Например, большой граф промежуточного представления на маленькие бьются кластеризацией с заданным целевым размером кластера и кластеры компилируются в отдельные модули, а 100 глобальных переменных раскидываются по скоупы доминаторным анализом.

- не замутненный бойлерплейтом - т.е. если мы компилируем hello world из 1 строчки и на выходе получаем 500 строк, из которых 499 строк - инициализация рантайм-системы, то эта инициализация должна быть отделена от смыслового кода и вынесена в отдельный генерируемый модуль или функцию выходного языка.

2. старый дизайн выходного кода (никаких остающихся на выходе ленивостей, алгебраиков, гигантских говнорантаймов, идиотского кода вроде f.call(null) и хуй-эр-пэ)

Нельзя использовать неидиоматичные конструкции, которые человек никогда бы не написал. Напишу на примере Си т.к. при генерации Си нарушить требование 2 очень просто. В Си могут быть goto и longjump в отдельных местах, но если компилятор использует эти конструкции в генерируемом им Сишном коде повсеместно, то на выходе получаем кашу, с которой человек работать (профилировать, оптимизировать, ловить баги во входном коде путем анализа стектрейсов в выходном) не может. Если я пишу в Хаскеле main = print "foo" >> print "bar", а компилятор из Хаскеля в Си выдает мне что-то отличное от int main (void) { puts("foo"); puts("bar"); return 0; } - например, копипастит в выходной файл библиотеку редукции графов, сборщик мусора, реализацию регулярных выражений и другой "мусор" - то требование 2 не выполняется. Если у нас во входном языке списки - это рекурсивный алгебраический тип, а выходной язык Си - то списки должны транслироваться в struct foo { int data; struct foo *next}; а не во фреймворк симуляции рекурсивных алгебраических типов в Си. Понятно, что при трансляции в JS списки - это массивы, и т.п.

3. новая система типов

Языки, не добавляющие ничего к системе типов Javascript, не интересны. Должна быть или хорошая (как в Эрланге) сильная динамическая типизация, или статическая система типов. Желательно не система типов 50-х годов, как в Обероне, а что-то более совершенное, но это опционально.

4. новый синтаксис

Языки типа Typescript, просто навешивающие на не самый приятный синтаксис JS новые фичи, не интересны. Аналогично не очень интересны языки с архаическим синтаксисом с точками с запятой и фигурными скобочками, но это можно потерпеть.

5. компактный новый язык

Языки типа Typescript и Coffeescript, сохраняющие тот же развесистый набор примитивов, что в ECMAScript, неинтересны. Язык должен отличаться от джаваскрипта малым размером спецификации и продуманным набором базовых конструкций, которые, с одной стороны, можно идиоматически (с выполнением требований 1-2) транслировать в джаваскрипт, а с другой стороны, сокращают когнитивную нагрузку на программиста при изучении языка (надо учить 2 способа написания цикла вместо 10).

Вот таблица языков из предыдущего поста:

Coffeescript, LiveScript - [1, 2, 4]
TypeScript - [1, 2, 3]
Ur, Fay, Roy, Elm, Haxe, Agda, Idris, Kotlin, F*, FunScript, Websharper - [3, 4, 5]
ClosureScript - [1, 4, 5]
MetaJS - [2, 4, 5]
Erlang JavaScript compiler, Wisp - [1, 2, 4, 5]
OberonJS - [1, 3, 4, 5]
JScala.org - [1, 2, 3, 4, 5]
Subscribe

  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 105 comments