Информация об изменениях

Сообщение Re[7]: TypeScript стал С++ от 27.10.2020 18:42

Изменено 27.10.2020 19:02 VladD2

Re[7]: TypeScript стал С++
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Какие гигабайты выхлопа?


Обычные. В выхлопных каталогах. Там формирвется море промежуточного говна. Мы в этот вопрос еще лет 10 назад разбирали.

EP>Он порождает парсеры compile-time, результат которых — это тип.


Это делается страшными побочным эффектами. А в промежутке там формируются тонны шаблонных классов, которые порождают гигабайты временных файлов даже на примитвной грамматике, а компиляция идет неприлично долго.

EP>Ну я уже выше привёл пример — там for — он по строке, и в compile-time.


Это слишком простой пример. Он не показывает достижим ли результат. Нужно чтобы на вход было нечто вроде:
parser<"rule1 = 'test';">();

а в результате формировался, например, вот такой код:
bool rule1(std::string str)
{
  if (str.length() < 4)
    return false;
  return str[0] == 't' && str[1] == 'e' && str[2] == 's' && str[3] == 't';
}

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

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

EP>В какой строке? Ты о чём? Metaparse пораждает парсеры compile-time строк, а не его граматика задаётся в compile-time строке, хотя если нужно, можно и граматику в строке задать


В строке переданной в качестве параметра. Пример я выше привел.

EP>Кому должна?


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

EP>Молодец, скопипастил кучу include'ов, using'ов, и мёртвый код для pre-C++11 — возьми с полки пирожок.


Какой есть в бусте. На инглюды я бы глаза еще закрыл. Их можно и в один свести. А вот на говнокод вместо грамматики я глаза закрывать не хочу. Я хочу иметь грамматические правила вроде:
| Add        = Expr sm '+' sm Expr

а не вот этотот вот говнокод:
typedef
  foldl_reject_incomplete_start_with_parser<
    sequence<one_of<plus_token, minus_token>, prod_exp>,
    prod_exp,
    eval_plus
  >
  plus_exp;

typedef last_of<repeated<space>, plus_exp> expression;


EP>Ну этот "сфероконь на типах", таки пораждает compile-time парсер, нравится тебе это или нет


Не порождает. Приведенный в теме пример порождает типы, т.е. сфероконя.

EP>Речь не идёт о хождении в базу compile-time, речь идёт о генерации о проверки запросов compile-time, которые ходят в базу в runtime. Как linq2db, только, только без runtime-оверхеда.


Так нет никаких проверок в компалйтайм. И базы нет. Есть самопальная БД на типах и хождение к ней. Ты хотя бы в коде разобрался бы. Нам на входе списки описанные на типах, а на выходе типы описывающие списки. Чистый сфероконо, который не применим на практике. Там в типах обрабатываются данные.

EP>Первое — давно возможно. Доступ к строкам в compile-time есть, полный по-тьюрингу язык для их обработки тоже есть, причём не один.


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

EP>Второе — нет, так как нет API для доступа к DB, чтению файлов и т.п. Но для таких редких use-case'ов внешнюю кодогенерацию не в лом использовать. Ну то есть например нормальный макросы — да, хотелось бы. Доступ к DB в compile-time — не особо


Ага. Это как в классическом: Не дает, ну и не очень то и хотелось! (ц)

Нормальные макры тупо не имеют таких ограничений. Это просто код — плагин к компилятору, который может читать любые данные (включая код проекта) и порождать новый. При этом у него нет проблем прочитать и метаданные из внешней БД, например.

Вот представь себе, что вместо:
#define(x) строка#x

Ты можешь написать нечто вроде
Expression #define(CppStringLiteral expr)
{
   здесь разбираем выражение и генерируем код парсера, которые компилируется в набор классов или функций
}

expr — это твой литерал. Вот это и есть макрос о котором я говорю. В другом макросе в строке может быть передан URI БД. И мы просто сходим туда во время компиляции и прочтем от туда метаданные, по которым скомпилируем функции доступа к ней.
Re[7]: TypeScript стал С++
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Какие гигабайты выхлопа?


Обычные. В выхлопных каталогах. Там формирвется море промежуточного говна. Мы в этот вопрос еще лет 10 назад разбирали.

EP>Он порождает парсеры compile-time, результат которых — это тип.


Это делается страшными побочным эффектами. А в промежутке там формируются тонны шаблонных классов, которые порождают гигабайты временных файлов даже на примитвной грамматике, а компиляция идет неприлично долго.

EP>Ну я уже выше привёл пример — там for — он по строке, и в compile-time.


Это слишком простой пример. Он не показывает достижим ли результат. Нужно чтобы на вход было нечто вроде:
parser<"rule1 = 'test';">();

а в результате формировался, например, вот такой код:
bool rule1(std::string str)
{
  if (str.length() < 4)
    return false;
  return str[0] == 't' && str[1] == 'e' && str[2] == 's' && str[3] == 't';
}

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

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

EP>В какой строке? Ты о чём? Metaparse пораждает парсеры compile-time строк, а не его граматика задаётся в compile-time строке, хотя если нужно, можно и граматику в строке задать


В строке переданной в качестве параметра. Пример я выше привел.

EP>Кому должна?


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

EP>Молодец, скопипастил кучу include'ов, using'ов, и мёртвый код для pre-C++11 — возьми с полки пирожок.


Какой есть в бусте. На инглюды я бы глаза еще закрыл. Их можно и в один свести. А вот на говнокод вместо грамматики я глаза закрывать не хочу. Я хочу иметь грамматические правила вроде:
| Add        = Expr sm '+' sm Expr

а не вот этотот вот говнокод:
typedef
  foldl_reject_incomplete_start_with_parser<
    sequence<one_of<plus_token, minus_token>, prod_exp>,
    prod_exp,
    eval_plus
  >
  plus_exp;

typedef last_of<repeated<space>, plus_exp> expression;


EP>Ну этот "сфероконь на типах", таки пораждает compile-time парсер, нравится тебе это или нет


Не порождает. Приведенный в теме пример порождает типы, т.е. сфероконя.

EP>Речь не идёт о хождении в базу compile-time, речь идёт о генерации о проверки запросов compile-time, которые ходят в базу в runtime. Как linq2db, только, только без runtime-оверхеда.


Так нет никаких проверок в компалйтайм. И базы нет. Есть самопальная БД на типах и хождение к ней. Ты хотя бы в коде разобрался бы. Нам на входе списки описанные на типах, а на выходе типы описывающие списки. Чистый сфероконо, который не применим на практике. Там в типах обрабатываются данные.

EP>Первое — давно возможно. Доступ к строкам в compile-time есть, полный по-тьюрингу язык для их обработки тоже есть, причём не один.


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

EP>Второе — нет, так как нет API для доступа к DB, чтению файлов и т.п. Но для таких редких use-case'ов внешнюю кодогенерацию не в лом использовать. Ну то есть например нормальный макросы — да, хотелось бы. Доступ к DB в compile-time — не особо


Ага. Это как в классическом: Не дает, ну и не очень то и хотелось! (ц)

Нормальные макры тупо не имеют таких ограничений. Это просто код — плагин к компилятору, который может читать любые данные (включая код проекта) и порождать новый. При этом у него нет проблем прочитать и метаданные из внешней БД, например.

Вот представь себе, что вместо:
#define(x) строка#x

Ты можешь написать нечто вроде
Expression #define(CppStringLiteral expr)
{
   здесь разбираем выражение и генерируем код парсера, которые компилируется в набор классов или функций
}

expr — это твой литерал. Вот это и есть макрос о котором я говорю. В другом макросе в строке может быть передан URI БД. И мы просто сходим туда во время компиляции и прочтем от туда метаданные, по которым скомпилируем функции доступа к ней.