Разрабатываю тут язык программирования goviaji. https://github.com/sorrge/goviaji По-моему каждый уважающий себя программист должен однажды сделать свой язык. Это какая-то веха на жизненном пути, отмечающая уровень развития программиста, и раскрывающая круг его интересов. Нет области, открывающей больший простор для полета программистской фантазии, чем программирование ради программирования, а разработка языков это самая его суть. goviaji уникален тем, что выводит идею о программировании-для-программирования на новый, невиданный доселе уровень. Это язык, предназначенный для создания языков программирования. Работа на goviaji выглядит так: вы описываете синтаксис и семантику нового языка программирования в виде правил вывода (подобных Natural deduction), затем пишете программу в виде выражения на goviaji. Интерпретатор goviaji проверяет, соответствует ли программа синтаксическим правилам, а затем исполняет программу, используя шаг выполнения, описанный в семантических правилах вывода. Все это делается методом доказательства соответствующих утверждений. Для примера на картинке формальное описание простого языка из книги Types and Programming Languages, а ниже соответствующее ему определение на goviaji. Оно работает, и позволяет выполнять любые программы на этом языке (примеры в репо). Также сейчас работает нетипизированное лямбда-исчисление, как чистое (где только лямбды), так и с дополнительными значениями.
А разработку кучи domain-specific языков с интерпретаторами можно засчитать за веху в жизненном пути программиста?
>вы описываете синтаксис и семантику нового языка программирования >затем пишете программу Так работает любой ЯП, где можно переопределять операторы и писать свои функии.
>>17438 Веха - это какое-то конкретное достижение. Для меня это разработка языка программирования ради него самого, как самоцель. Обычные DSL вроде прикручивания Lua скриптов к игре или парсера конфигурации дают опыт в этом деле, но по-настоящему ты дозреваешь, когда пишешь программу, в которой язык занимает центральное место. >>17447 В каком-то смысле ты прав. Например, на Лиспе можно сделать примерно то же, что у меня в goviaji. Принципиальных отличий, которые и есть основные мотиваторы разработки, тут три: 1) в goviaji описывать языки гораздо удобнее, например см. оппик - логическое определение переводится в код почти напрямую. 2) в goviaji нет никаких синтаксиса и семантики целевого языка, кроме тех, что определил сам программист. Ты должен полностью описать свой язык, и в нем не будет ничего лишнего, никаких посторонних эффектов. 3) goviaji предоставляет неограниченные возможности по определению языков. Технически самый близкий к goviaji язык это Пролог, но в goviaji другая логическая модель, которая мне больше нравится своей чистотой, и по-другому работает синтаксис. В качестве примера работы на картинке - вычисление выражения 3 == 2 + 1 в кодировке Черча на чистом лямбда-исчислении. Язык - чистое лямбда-исчисление - определен правилами вывода, а конкретные символы (equal, c3, snd, fls и пр.) это просто синонимы для соответствующих лямбда-выражений. На каждом шаге для выражения E доказывается утверждение eval E X, и X становится выражением для следующего шага. Начинается вычисление с "equal c3 (scc c2)", которое кодирует в Черча "3 == 2 + 1", а заканчивается tru, истиной в кодировке Черча.
>>17448 А что-нибудь НЕ функциональное там сделать можно?
> goviaji Не удержался, простите.
>>17450 Конечно, можно, и довольно просто. В чистом функциональном языке нет побочных эффектов, т.е. состояние вычисления полностью описывается вычисляемым выражением. Поэтому аргументы у eval это просто сами выражения. Для языков с побочными эффектами eval будет иметь форму "eval (prev_state, prev_term) (post_state, post_term)", т.е. состояние вычисления будет также содержать некое окружение. Например, в императивном языке с присваиваниями это будут значения переменных в текущем контексте. Потом я сделаю примеры таких языков. Можно описать в окружении что угодно, хоть память в виде массива байт для ассемблерообразного языка, хоть динамическую аллокацию в абстрактной куче, хоть параллельные вычисления в нескольких тредах. На картинке определение чистого нетипизированного лямбда-исчисления и кодировки Черча для bool, nat и list, которые были задействованы в картинке >>17448. Единственный нетривиальный момент - это подстановки и переименование переменных в лямбдах (посередине). Про аксиоматизацию этого процесса защищено немало диссертаций, совсем простого решения так и не нашли. В интуиционистской логике, лежащей в основе goviaji, это описывается так.
> Это какая-то веха на жизненном пути, отмечающая уровень развития программиста Мне кажется, что веха на жизненном пути, отмечающая уровень развития программиста не создания своего языка, а создание своего вируса.
>>17590Это или слишком просто, или слишком долго, в зависимости от взгляда на вещи. С перерывами пишу универсальный инфектор уже пятый год как.
Не пробовал твоё поделие, но описание звучит как сорт yacc'a.
>>17456 Ня, ты знаешь λ-функции! Можно кое-что спросить одна девочка про них только в Википедии и читала, так что не взыщи? Если использовать терминологию отсюда → https://en.wikipedia.org/wiki/Lambda_calculus_definition#Normalization , то у тебя, как я понимаю, происходит call-by-value редукция и в результате получается (если повезёт) weak-head-normal-form. Так вот, вопрос: почему не использовать normal strategy, если она более универсальна? и, кстати, как это в общих чертах доказать — то, что normal-order-reduction сходится при условии существования нормальной формы? А ещё Prolog странный язык! Кот-то говорит декларативный, а у девочки всё одно императивный код, только что блоки в строку развёрнуты, да вместо управляющей конструкции — short-circuit имплицитного OR того, что между правилами с одинаковой левой частью.
>>17629 У пролога императивная семантика что бы ни говорили. Посмотри datalog, он ближе к правильному логическому.
А ты смотрел racket? Им можно создавать языки, в том числе произвольный синтаксис. https://docs.racket-lang.org/guide/languages.html