В чем смысл "квази" в квазикобратах?

Некоторые языки, такие как Haskell (или Nemerle), имеют квазиотображения. Интересно, что означает "квази", а также существуют "цитаты" без "квази".

+39
источник поделиться
5 ответов

Я считаю, что это понятие происходит от языков Lisp.

Программа, написанная в Lisp, состоит из серии списков списков списков и т.д., например:

 (defn f [x y] (+ x y))

Из-за такой однородности можно представлять и манипулировать таким кодом как данные, поэтому последовательность символов выше интерпретируется как литеральный список. Это очень полезная функция Lisps, одна из их отличительных особенностей. Для удобства Lisp языки позволяют "указывать" значимые последовательности, превращая их из определений и выражений в списки. Это выглядит так:

 '(defn f [x y] (+ x y))

В этом случае это литеральный список, непосредственно доступный для деструктуризации с использованием аналогов Haskell head и tail и других методов. Итак, "quote" означает "сделать буквальное значение из списка".

Однако манипулировать списками напрямую с помощью head - и tail -подобных функций. Он становится заметным, когда вы начинаете писать сложные макросы или даже макрогенерирующие макросы. Итак, здесь происходит "квазивокация", буквально "почти цитата". Обычно квазивокация выглядит как простая цитата (но с другим символом цитаты):

`(defn f [x y] (+ x y))

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

 (let [z 10] `(defn f [x y] (+ x y ~z)))

Здесь мы привязываем переменную value 10 to z, а затем подставляем ее в квазиквазу. Это выражение дает

 '(defn f [x y] (+ x y 10))

Это простой пример; Языки Lisp позволяют делать много других полезных вещей с квазикварталами.

Это понятие перенесено на другие языки, которые поддерживают манипуляции с деревьями синтаксиса. Например, объект Haskell здесь Template Haskell, и он полностью поддерживает квазикотирование, т.е. Создает шаблоны и заполняет их значениями из внешней области. В языках со сложным синтаксисом (например, Haskell) квази- и простые цитаты становятся почти единственным разумным способом манипулирования деревьями синтаксиса.

UPD: Хм, похоже, что в Haskell это более сложная функция, чем простая подстановка. Quasiquote в Haskell выглядит как произвольный трансформатор и оценщик выражений, который может быть определен пользователем.

+40
источник

Эти понятия существуют на языке Lisp и его вариантах.

В этих языках всякий раз, когда интерпретатор видит список (a b c ... z), он оценивает его, применяя a к другим элементам b ... z.

Если вы хотите, чтобы список не оценивался (и, следовательно, его интерпретировали как список), вы должны его процитировать. Например, '(a b c) оценивается как список с тремя элементами, а не как a, примененный к b и c. Вы можете увидеть цитату как остановку оценки.

Теперь квазивокация ведет себя как цитата, за исключением того, что вы можете возобновить оценку внутри частей списка. Вы quasiquote с обратным апострофом `, и вы позволяете некоторым подвыражениям быть без кавычек с оператором запятой (по крайней мере, на Схеме, я не знаю о других вариантах Lisp). Например,

`(a ,(b c))

оценивает список с двумя элементами: a и результат оценки (b c).

Это особенно полезно для создания шаблонов, где вы заполняете дыры по незаметности. Пример (взято из там):

(define (create-shipping-employee-association name)
  `((name ,name)
    (employee-id-no ,(get-next-employee-id!))
    (department shipping)
    (hire-date ,(get-day) ,(get-month) ,(get-year))))
+18
источник

В Nemerle квазикомиссия имеет вид (http://nemerle.org/metaprogramming.pdf):

"

Метаязык - это язык программирования таких операций. Обычно он имеет свой собственный синтаксис для описания различных конструкций объектного языка.

Например, в нашей системе:

<[ 1 + f (2 * x) ]>

обозначает синтаксическое дерево выражения:

1 + f (2 * x)

Эта идея называется квазикокцией.

Префикс quasi происходит от возможности вставки значений выражений метаязыков в цитируемый контекст.

если g(y) - такое выражение, мы можем написать:

<[ 1 + $(g(y)) ]>

который описывает дерево синтаксиса, вторая часть которого заменяется результатом оценка g(y)

"

+5
источник

Цитата - это просто строковый литерал. Квазикварталы "цитируются" в том смысле, что они представляют собой вход в некотором смысле, а не компилируемый код; они просто представляют его в форме, которую легче манипулировать изнутри процесса компиляции (абстрактное синтаксическое дерево, которое можно трансформировать различными способами, которые несколько безопаснее, чем работа с текстом).

+2
источник

Квази в основном означает, что вы можете поместить знак доллара внутри цитаты и снова переключиться на код без кавычек:

<[ WriteLine( $(ReadLine()) ) ]>

Это приведет к выводу во время выполнения строки, введенной во время компиляции (на самом деле я не думаю, что это будет работать, например, в Visual Studio, поскольку ReadLine требует ввода консоли, но вы можете читать из файлов, сети и т.д.),.

+2
источник

Посмотрите другие вопросы по меткам или Задайте вопрос