В программировании M-выражения (или метавыражения ) были ранним предложенным синтаксисом для языка программирования Lisp , вдохновленным современными языками, такими как Fortran и ALGOL . Нотация никогда не была реализована в языке и, как таковая, она никогда не была завершена. [1]
M-выражения являются синтаксисом для кода LISP и обеспечивают нотацию функций , синтаксис для cond
формы и для встроенных литеральных данных (через S-выражения) в программы. Таким образом, M-выражения использовали S-выражения для литеральных данных. Синтаксис для S-выражений («Язык данных») и M-выражений («Метаязык») определен на страницах 8 и 9 руководства Lisp 1.5. [2]
M-Expressions также имели соответствующее представление S-Expression. Код вручную транслировался из M-Expressions в S-Expressions. В M-Expressions встраивались литеральные данные, которые затем приходилось заключать в кавычки в S-Expressions.
Форма M-выражения
add[listvar;(ПАРИЖ БЕРЛИН НЬЮ-ЙОРК ТОКИО)]
затем необходимо преобразовать в форму S-выражения
(ДОПОЛНИТЬ СПИСОК (ЦИТАТА (ПАРИЖ БЕРЛИН НЬЮЙОРК ТОКИО)))
Джон Маккарти опубликовал первую статью о Lisp в 1960 году, будучи научным сотрудником Массачусетского технологического института . В ней он описал язык символических выражений ( S-выражения ), который мог представлять сложные структуры в виде списков. Затем он определил набор примитивных операций над S-выражениями и язык метавыражений (M-выражения), который мог использоваться для определения более сложных операций. Наконец, он показал, как сам метаязык может быть представлен с помощью S-выражений, что привело к системе, которая потенциально могла бы размещаться сама по себе . [3] Черновая версия этой статьи известна как «AI Memo 8». [4]
Маккарти планировал разработать автоматический компилятор Lisp ( LISP 2 ), используя M-выражения в качестве синтаксиса языка и S-выражения для описания внутренних процессов компилятора. Стивен Б. Рассел прочитал статью и предположил, что S-выражения являются более удобным синтаксисом. Хотя Маккарти не одобрил эту идею, Рассел и его коллега Дэниел Дж. Эдвардс вручную написали программу- интерпретатор , которая могла выполнять S-выражения. [2] Эта программа была принята исследовательской группой Маккарти, установив S-выражения в качестве доминирующей формы Lisp.
Маккарти размышлял о судьбе М-выражений в 1979 году:
Проект точного определения M-выражений и их компиляции или, по крайней мере, перевода в S-выражения не был ни завершен, ни явно заброшен. Он просто отступил в неопределенное будущее, и появилось новое поколение программистов, которые предпочли внутреннюю нотацию любой нотации типа FORTRAN или ALGOL, которую можно было придумать. [5]
— История Лиспа
В книге Джона Аллена «Анатомия LISP» дается определение M-выражений, и они используются на протяжении всей книги для объяснения Lisp и его реализации. [6]
Определения функций apply и eval взяты из руководства Lisp 1.5, стр. 13.
применить[fn;x;a] = [атом[фн] → [eq[fn;CAR] → caar[x]; eq[fn;CDR] → cdar[x]; eq[fn;CONS] → cons[car[x];cadr[x]]; eq[fn;ATOM] → атом[car[x]]; eq[fn;EQ] → eq[car[x];cadr[x]]; T → применить[eval[fn;a];x;a]]; eq[car[fn];LAMBDA] → eval[caddr[fn];parlis[cadr[fn];x;a]]; eq[car[fn];МЕТКА] → применить[caddr[fn];x;конс[cons[cadr[fn];каддр[fn]];a]]]
оценка[e;a] = [атом[e] → cdr[ассоц[e;a]]; атом[кар[е]] → [eq[car[e],QUOTE] → cadr[e]; eq[car[e];COND] → evcon[cdr[e];a]; T → применить[car[e];evlis[cdr[e];a];a]]; T → применить[car[e];evlis[cdr[e];a];a]]
Использование функции eval для s-выражения.
eval[(EQ (QUOTE A) (CAR (CONS (QUOTE A) (QUOTE (BCD)))));NIL]
MLisp был современным (1968–1973) проектом по реализации интерфейса M-expression-like для Lisp. Было включено несколько дополнительных функций, таких как гигиенические макросы , сопоставление с образцом и возврат . В конечном итоге он превратился в заброшенный проект LISP70. M-LISP (MetaLISP) 1989 года был еще одной попыткой смешать M-expressions со Scheme. [7]
Синтаксический анализатор для M-выражения « AI Memo 8» доступен в Common Lisp , но автор рассматривает его как аргумент против M-выражений из-за его предполагаемой неспособности справляться с макросами. [8]
CGOL ( 1977 ) был реализован в MacLisp и преследует схожую цель внедрения синтаксиса, подобного Algol, с инфиксными операторами. [7] Известно, что он работает на Armed Bear Common Lisp . [9]
Более поздним (около 2003 г.) вариантом является I-выражение , которое использует отступы для неявного указания скобок и, таким образом, в некотором роде является промежуточным между S-выражениями и M-выражениями. I-выражения были введены в Scheme Request For Implementation 49 как вспомогательный синтаксис для Scheme , но они не получили широкого распространения. [10]
Дальнейшее развитие - "сладкое" t-выражение , которое имеет инфиксные операторы без приоритета. Как и I-выражения, t-выражения - это всего лишь простое преобразование из S-выражений, так что теоретически их можно использовать на любом диалекте Lisp и не мешать таким функциям, как макросы. [11]
Дополнительные синтаксисы включают Dylan от Apple (маркеры, подобные Algol) и добавление Clojure других литеральных синтаксисов. [7]
Давайте новичкам поиграем с ними и поймем, насколько они непрактичны. Обратите внимание, например, что мы больше не можем использовать макросы, поскольку их синтаксис должен быть известен парсеру M-выражений.