#clojure #racket #dsl #clojurescript
#clojure #racket #dsl #clojurescript
Вопрос:
Поскольку Clojure (Script) — это Lisp, все примеры DSL (языков, специфичных для домена) в нем используют круглые скобки для кодирования выражений were begin и end (как это делает Lisp). Однако, по крайней мере, в другом диалекте Lisp (Racket) есть много примеров DSL без скобок (создание языков в Racket, DSL1, DSL2). Я могу использовать какой-нибудь специальный метод для преобразования:
if (a > 10) { print "Ok!" } ==> (if (> a 10) (print "Ok!"))
Я хотел бы знать, есть ли какое-нибудь руководство по передовой практике или библиотека для выполнения этих преобразований в Clojure. Или, может быть, кто-то перенес функции Racket, которые выполняют эти преобразования, в Clojure (я не пользователь Racket). Может ли пользователь Racket указать мне на некоторую документацию Racket о том, как он обрабатывает такие DSL?
Ответ №1:
Clojure намеренно не добавлял определяемые пользователем макросы для чтения. Какие функции используются для преобразования кода верхнего уровня. Clojure включает их, они просто не определяются пользователем, поэтому их фиксированное количество.
Одним из примеров является макрос #_ reader, который полностью удаляет следующее выражение. (вы можете складывать их)
#_#_#_(:println 1) (println 2) (println 3) (println 4)
4
Что вы можете сделать, так это определить помеченные литералы, которые решают многие из тех же проблем, хотя на самом деле они не предназначены для определения внешних DSL. В большинстве случаев у вас будет макрос dsl-start верхнего уровня, и тогда вам не нужно использовать какие-либо ()
s, кроме начальных двух, окружающих начальный символ. С тем ограничением, что то, что вы представляете на своем языке, должно состоять из удобочитаемых выражений (symbolc, карты, векторы, списки и т. Д.)
(with-my-special-language
if (a > 10) { print "Ok!" }
if (a > 42) { print "Even Better!" }
)
Если вы действительно хотите избежать раскрытия этих двух ()
для человека, пишущего этот код, вы можете прочитать этот код в строку, добавить () самостоятельно, а затем оценить его. Очень удобно иметь прямой доступ к читателю, подобный этому.
Комментарии:
1. У вас есть указатель на код, который может реализовать это с помощью функции / макроса на моем специальном языке?
2. Это в основном вся ваша программа, поэтому она будет слишком большой для формата вопросов и ответов. Макрос with-my-special-language, скорее всего, будет иметь подпись типа
(defmacro with-my-special-language [ amp; expressions] ... lots of code to parse and make sense of your language ... )
3. Можете ли вы изложить суть программы и опубликовать ссылку здесь?
4. Мне просто нужна часть, которая преобразует формат, отличный от Lisp, в формы Lisp.
5. Это зависит от дизайна «не-lisp» языка, который вы хотите преобразовать в Clojure. Существует больше вариантов, чем существующих языков, отличных от lisp, и все они делают разные варианты дизайна. Это действительно вопрос языкового дизайна, и на самом деле я не могу ответить. Создание языков — это ВЕСЕЛО, дерзайте!
Ответ №2:
Существует библиотека под названием chiara, которая позволяет вам писать Clojure без использования круглых скобок. Из README:
(ns my-ns
(use chiara))
(use-chiara) (chiara
defn foo [x]
map inc (range x)
def my-list
foo 10
)
Он вводит синтаксические макросы, которые позволяют выполнять необходимые преобразования.