Что означает "квази" в квази-цитатах?

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

5 ответов

Решение

Я считаю, что это понятие пришло из языков Лисп.

Программа, написанная на Лиспе, состоит из серии списков списков списков и т. Д., Например:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Теперь квази-цитата ведет себя как цитата, за исключением того, что вы можете возобновить оценку внутри частей списка. Вы квазицитируете с обратным апострофом `и разрешаете неквотировать некоторые подвыражения оператором запятой (по крайней мере, в Scheme, я не знаю о других вариантах 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))))

В Nemerle квази-цитата является ( http://nemerle.org/metaprogramming.pdf):

"

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

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

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

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

1 + f (2 * x)

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

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

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

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

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

"

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

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

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

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

Другие вопросы по тегам