Yupiel - языко-ориентированный язык программирования основанный на механизме перезаписи строк.
Синтаксис В языке есть только одна конструкция - правило. Вся программа на Юпиель представляет из себя список правил вида: Type :: Pattern => Replacement или Type :: Pattern
Type - терм, обознающий тип выражение.
Pattern - набор символов и нетерменалов.
Нетерминалы обозначаются как |var : Type|, где var - имя переменой (может быть любой последовательностью символов, кроме `|` и ` `.
Replacement - набор символов и нетерминалов вида |var|.
Всякий набор правил Юпиель называется модулем (module).
Текст, подаваемый в модуль, называется источником (source).
Текст, выдаваемый модулем, называется целью (target).
Задача модуля - превратить код из языка Source в код языка Target.
Универсальность и встраемость Юпиэль - транспилятор. У него нет рантайма, а это значит, что ты можешь писать код (с любым синтаксисом, который ты поделаешь), и запускать его в браузере или на Go-сервере, или... да где угодно. Хоть ардуину программируй.
Твоя говноконтора программирует на говноязыке X? Просто прозрачно превращай свой идеальный язык Y в говноязык X с помощью Yupiel.
Выразительность Код на Юпиель такой, каким ты хочешь его видеть.
Простота В Юпиеэль есть только одна вещь - правило.
Простая отладка Просматривай поэтапно процесс транспиляции.
> имплементация? Её пока нет. Однако будет создан proof-of-concept транспилятор Yupel.
>>2019590 По-сути, в правила Юпиэль - это макросы, но с произвольным синтаксисом. Правила Юпиель можно рассматривать как правила парсера Эрли, но с дополнительной частью в виде замены. Невероятно просто, однако, почему-то это еще никто не реализовал.
Алсо, макросы во всех языках могут работать только с термами языка, а не с произвольными синтаксическими конструкциями. К примеру, лишп. В лишпе макросы могут работать только с s-exp.
>>2019598 ОП, как мне статически тайпчекнуть то что оно высрет в итоговой программе? Ведь я пишу только исходную программу. Без этого твой язык мне не нужен.
Второе: допустим я написал траспилятор на твоём языке. Потом траспильнул вторым транспилятором. Где гарантии типобезопасности на target?
сделай нормально, иначе можно и на racket макросы бомбить
>>2019804 > как мне статически тайпчекнуть то что оно высрет в итоговой программе? Статический тайпчек это тоже самое что синтаксический анализ. Статический тапочек доказывает над термами, а синтаксический анализ доказывает над синтаксическими конструкциями переводя их в термы.
Предположим, что мы имеем правило Natural (его определение опустим). Тогда определение операции (+) над Natural будет очевидным: Natural :: |x : Natural| + |y : Natural| => (+ |x| |y|)
Таким образом мы можем проверить статично не только синтаксическую корректность кода, но и семантическую.
Однако, не скрывая правды, target не обязан быть корректным. Если Source и Target представляют из себя Тьюринг-полный языки, то нельзя исключить левую рекурсию. Как ты понимаешь, это не проблема Yupiel, а проблема остановки.
К тому же есть очень большой, но никаким образом неразрешимый минус статичной типизации - все данные поступаемые извне невозможно проверить статично. Для этого придется добавлять тайпчек в рантайм. Для говноязыков, типа js, придется создавать функции-предикаты и оборачивать ими input-эффекты. Для языков с встроенной сильной системой типов, можно обойтись и нативным для этого языка тайпчеком.
Важно так же отметить, что Yupiel - гибкая штука. Она не накладывает никаких ограничений на код. Нормально делай - нормально будет.
К примеру, для надежной системы нужно соблюсти следующие паттерны:
- Отделить выражения и эффекты. Не допустить конструкции вида ‹print(x) + print(print(y))› Есть выражения, которые что-то возвращают, а есть действия/эффекты, которые что-то делают, но сами ничего не возвращают. Взболтать но не смешивать.
- Запретить общую рекурсию. Если в Source-язык не может в общую рекурсию, то есть четкие гарантии того, что твой код не упадет в бесконечную петлю. Используй только структурную рекурсию над конструкторами, и соответствующие комбинаторы для этого.
Первое - все лиспы имеют рантайм. Нет лиспа без рантайма. Это сразу выносит на нет возможности бесшовной транспиляции.
Второе - лисп, как и все остальные языки, ограничен синтаксисом, а именно s-exp. Если начнешь расширять s-exp кастомным парсером, то просто создашь ограниченную версию Yupiel.
Третье - лисп это язык (хоть и с мощным метапрограммированием). Yupiel - это метаязык. Как EBNF.
>>2019934 Несешь бред. Грамматика нулевого уровня типа Semi-Thue это иная, очень упрощённая концепция, и что важно неюзабельная концепция. Погугли Thue lang. Yupiel использует CFG (Context Free Grammar), а это нихуя не нулевой уровень.
>>2019999 > Pattern => Replacement У тебя нет ни ограничения по длине слов, а значит это уже не уровень 1, и хотя про уровень 2 уже нельзя говорить, у тебя
> Pattern - набор символов и нетерменалов. нет ограничений по нетерминалам слева, какой нахуй контекст фри граммар.
В любом случае, советую почитать про нормальный алгоритм Маркова, мб, ты переизобретаешь велосипед, только корявый.
>>2020045 > нет ограничений по нетерминалам слева, какой нахуй контекст фри граммар. В случае паттерна, исключением из символов является соответственно (=>). Если нужно использовать (=>) как символ используй экранирование (\=>). Тоже касается табов (\t), перевод строки (\n). Так же, для удобства один символ пробела (" ") считается за (whitespace+). Т.е паттерн "print x" соответствует "print x", так и "print x".
>>2019822 Твой яп наверное не в вакууме работает а в каком-то вычислительном устройстве "рантайме". С точки зрения теории яп все реальные языки имеют рантайм. И уже поэтому твои заявления мягко говоря странные.
>>2021075 > Ииииии, мы изобрели s-expressions. Я действительно не понимаю где тут связь.
Чтобы вы поняли, что такое Юпиэль, я приведу пример программы.
# модуль HelloWorld.ypl
Effect :: say |n : Note|! => console.log("|Hi World|") Letter :: |x : or C D E F G B A| Octave :: |x : 1 2 3 4 5 6 7 8| Note :: |l : Letter||o : Octave| => note("|l|", |o|)
# source source.txt say C4!
# после запуска в консоли "yupiel -m HelloWorld -s source.txt -t target.js" в папочке с проектом появится target.js с таким содержанием: console.log(note("C", 4))
Теперь понятно, что такое Юпиэль?
> Твой яп наверное не в вакууме работает а в каком-то вычислительном устройстве "рантайме". Хех, у него действительно нет рантайма. Юпиэль не знает ни о операции (+), ни о IO. Юпиэль занимается транспиляцией только и всё, соответственно "паразитируя" на других языках. Как в примере выше. Используется встроенная в js console.log. Можно транслировать в какой хочешь язык.
>>2021398 > И в чём основное преимущество такого подхода перед обычными языками? Всё предельно просто - тотальная универсальность. Yupiel можно использовать буквально везде. Это всё сочетается с тем, что ты делаешь язык под код, а не код под язык. Можно писать действительно человеко-читаемый код на языке который больше подходит задаче проекта, чем какой-либо язык общего назначения.
Нет проблем с производительностью самих DSL. Можешь транслировать либо в C, либо в какой-нибудь Python, или даже в ASM. Производительность зависит от выбранного Target и от прямости рук самого программиста.
>>2019820 спасибо за ответ, ОП. Извини, что я плохо во всём таком разбираюсь. У меня есть только хотелки сумелок нет
Хотелка 0 (?): Мне всё-таки кажется что я хочу корректный таргет. Понятно, что source программу я не смогу запустить, а только таргет. Если некорректно был написан сорс, то запуск таргета может выдать непонятную балалайку в консоль и ищи свищи где в сорсе ошибка. Там же будет в этом юпиэле тайп инфиренс, хиндли милнер вот это всё? Я правильно понимаю, что нормальные сообщения об ошибках невозможно получить, так как это проблема останова уже?
Хотелка 1: Так как это языко-ориентированный язык, хочу писать собственные DSLы (например JSON-подобные (в которых будут в том числе enumerable типы полей)), хочу под каждый такой dsl сгенерированный language server, чтобы в редакторе мне подсказочки выдавало при написании на таком dsl, и говорило валидный у меня файл или невалидный, выдавало где ошибочки. DSL безо всяких вычислений, чисто декларативная простыня чтобы для конфигов. Сможет ли юпиэль в такое? Я знаю существует Xtext и Jetbrains MPS. Но они выглядят всратыми, даже лень осиливать такое. Кроме того они требуют целые IDE.
Хотелка 2: хочу писать и запускать домэйн специфик стэйт машины. Xtext такое кажется умеет
Вопрос: Сущестует ли что-то более лайтвэйт на рынке чем xtext и mps? Просто лень эти читать простыни из документации для того чтобы написать dsl уровня "пук-среньк"
Похвалить: У юпиэль отличная маркетинговая стратегия: собирать лидов на три строчки синтаксиса
>>2022089 > Хотелка 0 (?): Надо еще думать о возможности создавать прозрачный для кода дебаг. Сильной стороной Yupiel является (будет) прозрачная встраиваемость. Что если в рантайме появился эксепшен? Как фиксить? Над этим стоить думать. Решением может быть: - На этапе создания DSL: юнит-тесты языка. - На этапе использования DSL: зависимые типы.
> Хотелка 1: Будет поддержка Yupiel в каких-нибудь VSCode. Если где-то появилась синтаксическая ошибка, редактор пометит. Для всех остальных фич редакторов не может быть универсального решения. Можно только создать универсальный формат для написания документации, откуда его можно будет транслировать в специфичный формат редактора.
> Вопрос: Ну, я знаю Racket. Но там тоже ахуеешь всю документацию языка читать.
Единственным решением является, ВНЕЗАПНО, Юпиэль. Не просто так я её решил создать. Если бы был, хотя бы даже шизотреический, язык с свойствами схожими с Юпиэль, то мысль о создании этой утилиты у меня даже бы не появилась.
> У юпиэль отличная маркетинговая стратегия: собирать лидов на три строчки синтаксиса Хех, это да. Лиды делают DSL, джуны на этих DSL пишут.
>>2021153 > Хех, у него действительно нет рантайма. Юпиэль не знает ни о операции (+), ни о IO. Юпиэль занимается транспиляцией только и всё Это слишком тупой троллинг. х86 цп знает что такое транспиляция? А +- он знает. Так КАК твой дупель делает транспиляцию на железе с +- и без транспиляции?
Ты на какой доске вообще решил дерьма в уши людям лить придурок?
>>2022231 Ты компиляцию от рантайма отличаешь? Ясен хуй, что транспилятор/компилятор это программа, которая запускается на компьютере. Однако с рантаймом это не связано. Есть этап компиляции/транспиляции, есть рантайм. Yupiel занимается только транспиляцией. Что там в рантайме произойдет уже не забота Юпиэль, а забота какого-то другого компилятора/интерпретатора (V8, ghc, python, к примеру).
>>2022235 > Учи лисп. Чел, я пишу прототип Yupiel на Racket. Лисп и Yupiel это совершенно разные языки. Ты где вообще взаимосвязь нашел?
Интересно как в юпеле записать что в случае чисел от 10 до 20 делать одно, а в случае от 21до 23 другое. Ну например это часть имени функции - делать21 например.
Теперь определим функцию (if): |A| or |B| :: if |e : Boolean| then |A : Expr| else |B : Expr|
Теперь определим (and): Boolean :: |Boolean| and |Boolean|
Определим дунофинг: Nothing :: do nothing => null
Ну, а теперь выполняем то, что просил. λ x . if x > 10 and x < 20 then do nothing else do nothing
Конечно, правила можно было бы сделать рекурсивными. Тогда Yupiel было Тьюринг-полной, и пикрилейтед-код был бы допустимым в Yupiel. Однако, хоть пикрилейтед невероятно элегантен, если слишком много «против» против рекурсивных правил.
>>2019822 > Первое - все лиспы имеют рантайм. Нет лиспа без рантайма. Это сразу выносит на нет возможности бесшовной транспиляции. Есть лиспы, которые паразитируют транспилируются в другие языки, та же Clojure, Fennel.
>>2021153 Пиздос, а не легче самим ручками написать в .js файле console.log чем описывать его в каком то юпель несколькими строками кода, которые ещё и хуй поймёшь как работают
>>2022544 > Пиздос, а не легче самим ручками написать в .js файле console.log Это просто пример. Понятное дело, Yupiel нужно для простого создания DSL.
>В языке есть только одна конструкция - правило. Вся программа на Юпиель представляет из себя список правил вида: Type :: Pattern => Replacement или Type :: Pattern >первый пример: какие-то стрелки, ООП Быстро ты сломался, как и твой недо-пролог с уебищной парадигмой.
>>2022563 > ООП Чел, у тебя каша в голове. Какой еще ООП? Ты где его увидел? Да и прологом Yupiel не является, хотя имеется логический вывод (переменные логические) для того чтобы разрешать типы.
> какие-то стрелки Сначала изучи Term Rewriting. Yupiel это про Term Rewriting. Когда познаешь Лямбду и перезапись терминов, тогда приходи.
>>2022683 Алгоритм Маркова это совершенно иная вещь, сколько раз объяснять. В Нормальном Алгоритме Маркова паттерны рассматриваются по полному точному соответствию. То есть в алгоритме Маркова у правил нет параметров и переменных. Простой пример: Пусть будет правило (a ->. b), тогда применив его к (aab) мы получим (bbb) Но возьмем задачку посложнее: Написать такую функцию, которая меняла свои аргументы местами: (swap x y) -> (swap y x). В алгоритме Маркова это невозможно выполнить очевидным способом, потому что нет понятия о переменных и параметрах функций. Алгоритм Маркова это Тьюринг-полная грамматика, который важен так же как и брейнфак.
Напротив, Yupiel не является Тьюринг-полной (по понятной причине). У правил Yupiel есть параметры, и с помощью их можно обрабатывать конечные рекурсивные структуры, что делает их CFG.
>X0: >Решением может быть: >- На этапе использования DSL: зависимые типы. вот это пожалуйста. можно? голосую за зависимые типы
>X1: >Будет поддержка Yupiel в каких-нибудь VSCode. Требуется поддержка не самого юпиел в вскод а автоматическая поддержка созданного dsl. Понятно, что скорее всего одним ypl не обойтись надо вот так чтоб: https://youtu.be/5WA8kCdg6Ek?t=997 и как-то так https://youtu.be/ESRk7NmCDFA?t=608
>>2022867 > Требуется поддержка не самого юпиел в вскод а автоматическая поддержка созданного dsl А в чем принципиальная проблема? Не всё сразу, конечно. Но автоматизация всей рутины, это то, чем должен заниматься программист в первую очередь. > А пакеж сорсы. К сожалению, оставил зарядку от ноута в общаге. Сам иногда удивляюсь своей неряшливости. Однако, истины ради, не сказать, что я там успел что-то значимое сделать. Я сначала хотел адаптировать Nearley-parser для своих задач, но это сложнее (хотя прототип почти рабочий и хеллоуворд отрабатывает), проще самому Earley алгоритм имплементировать в Racket.
Оп изобретатель велосипеда. Транскомпилятор, делающий ровно то, что описано в оп посте, мало того что давно существует, но ещё и не требует для своей работы понятия специального языка программирования. В общем, это поридж-тред, официально. Ах да, забыл сказать, выше я говорю о facebook transcoder. /поридж-тред
Добавлю, что оп "изобрел" т.н rule-based transpiler, которые не только менее эффективны, чем пейсбуковский транскодер, но и требуют от пользователя знаний в обеих (сорс и таргет) языках, чего нет в транскодере.
>>2023789 > говно на нейронках Ты серьезно? Ты вот сейчас реально серьезно, блядь? Мне даже не хочется объяснять тебе, почему твое говно - говно, но так уж и быть, объясню.
Во-первых, нейронки не предназначены для прувинга. Нейронка - черный ящик, допускающий неточность. Во-вторых, нейронка не универсальна. Её надо будет дообучать, чтобы она смогла хоть как-то что-то да выдать. В-третих, transcoder нужен для транспиляции существующих языков программирования. Ты не сможешь использовать его для создания DSL (а Yupiel создаётся именно для этого). Для нейрнок требуется нормальный такой датасет, а где ты его найдешь для еще не созданного DSL?
>>2023804 > DSL Боярское программирование, лол. Что тебе мешает определить что угодно через дефайн и использовать для любой предметной области любой язык общего назначения? Насчёт неточности нейросетей, зря ты веруешь, что rule-based transpiler будет сильно точнее.
>>2023825 > Что тебе мешает определить что угодно через дефайн Ты про #define? Это достаточно хреновый инструмент, на самом деле. > предметной области любой язык общего назначения? Который, естественно, привязан к своей экосистеме? Нет, спасибо. > Насчёт неточности нейросетей, зря ты веруешь, что rule-based transpiler будет сильно точнее. "Rule-based" означает, что система завязана на точной математической логике. Я даже планирую добавить в STD Yupiel рационалы, вместо дырявых float.
>>2023832 > Ты только что PEG. Так Юпиэль это CFG, я уже весь тред это говорю. Можно сказать, что Yupiel это продукт, как NPM к примеру. Пакетные менеджеры и до этого существовали, никто же не говорит, что NPM Inc. создало велосипед. Когда создавалась Scala никто не говорил, что разработчики Scala изобрели ФП, тоже самое с Clojure и Racket.
Алсо, Yupiel это не PEG. В PEG невозможны создания грамматик с левой рекурсивной частью типа: Expr -> Expr "*" Expr, а в Yupiel возможны, потому что под капотом Earley, а не PEG.
ОП, давай скорей пиши. Уже давно такое надо. Сразу его в индустриальные задачи и будем монетизировать бабло грести лопатами. DSLы будем писать для домохозяек. DSLы для управления башенными кранами, авторучками и газовыми горелками. DSL чтобы выйти из дома, открыть дверь, потушить свет в коридоре. DSLы в терминах бизнес сущностей, чтобы мышкой программировать серверлес приложения в реальном времени разворачиваемые на облаке. ДСЛ для неба и даже для велосипеда
>>2028118 > можно сделать быстрее регулярками на перле Если смешать регулярки с перлом. Но там ебейшая темная магия происходит. И нет, не быстрее, потому что грамматики могут быть весьма сложными, а твой код будет полон синтаксического мусора. Как в своей грамматике разбираться будешь?
POC делается за вечер https://pastebin.com/YQLp47gT по внятному описанию. У ОПа какая-то каша в синтаксисе >>2019584 (OP), такое ощущение, что он примеры на ходу придумывает. Вот это >>2022496 я вообще не знаю, как воспринимать.
import Text.Parsec hiding (letter) main = either (putStrLn . show) (putStrLn) . parse effect "-" =<< getContents
effect = do { string "say"; spaces; n <- note; string "!"; () ==> "console.log(" ++ n ++ ")" } letter = l oneOf "CDEFGBA" octave = l oneOf "12345678" note = do { l <- letter; o <- octave; () ==> "note(\"" ++ l ++ "\", " ++ o ++ ")" }
l p a = do { c <- p a; return $ c:[] } infixl 0 ==> _ ==> b = return b
Да вообще на любых парсер-комбинаторах.
Проблема всех этих метакомпиляторов в тулинге. Начиная от внятных сообщений об ошибках и заканчивая поддержкой редакторов. Что в Yacc, что в C preprocessor, что в шаблонизаторах, что в других подобных. Задумка ОПа, кстати, больше всего похожа на OMeta. У которой была та же проблема с тулингом, и которая в итоге выродилась в никому ненужный Ohm. JetBrains придумали MPS и вроде сделали автогенерацию тулинга, но у них там вообще всё своё, включая уёбищный редактор. Впрочем, я давно его смотрел, не знаю, как сейчас.
>>2030053 > Если все равно нужно все писать вручную, тогда не ясно, чем это Чтобы сделать ПРАВИЛЬНЫЙ язык, даже если он транспилируется в НЕправильный язык (C++, JS).