Сравнение макросов Common Lisp и возможностей метапрограммирования Forth

Каждый программист на Common Lisp знает, что макросы - мощный инструмент. Макросы Common Lisp использовались, среди прочего, для добавления объектной ориентации поверх Lisp без изменения спецификации языка; макросы чтения - это еще одна конструкция, обладающая потрясающими возможностями.

Еще одна программа, позволяющая метапрограммировать, - это Forth. Форт делает это немного по-другому, используя «слова» и «генерировать слова».

Я хотел бы узнать от человека, который пробовал себя в обоих языках, если общие макросы lisp и другие конструкции сопоставимы по ширине / мощности: есть ли что-то, что вы можете сделать с первым, чего не можете сделать со вторым? Или наоборот?

Конечно, я не говорю о полноте по Тьюрингу двух языков: я говорю о возможностях метапрограммирования. C является полным по Тьюрингу, но только глупец может заявить, что макросы C сравнимы по мощности с макросами Common Lisp.


person user3750103    schedule 18.06.2014    source источник
comment
Это гораздо более конкретно, чем в предыдущей версии, Макросы Lisp и Forth [приостановлено], что хорошо. Конечно, теперь по этому вопросу повторное голосование, а по нему закрытое голосование, так что есть некоторая путаница в отношении того, какой из них должен оставаться открытым. Гораздо яснее, что вы ищете в этом вопросе, но, вероятно, это все еще не по теме, потому что вопрос сравнения плохо подходит для [Stack Overflow], потому что ответы, которые можно им публиковать, не ограничены.   -  person Joshua Taylor    schedule 18.06.2014
comment
Здесь применяется близкая причина слишком широкая: либо слишком много возможных ответов, либо хорошие ответы были бы слишком длинными для этого формата. Это совсем не плохой вопрос; это просто не очень хорошо подходит для Stack Overflow. Например, этот вопрос может быть полезен для comp.lang.lisp.   -  person Joshua Taylor    schedule 18.06.2014
comment
Конкретный подвопрос: есть ли что-то, что вы можете сделать с первым, чего не можете сделать с последним? Или наоборот? вероятно, самый конкретный здесь. Он по-прежнему может допускать слишком много ответов, но если есть что-то, что может сделать один, чего не может другой, вероятно, можно дать относительно канонический ответ.   -  person Joshua Taylor    schedule 18.06.2014
comment
Против закрытия для слишком широкого. Пример ответа: в LANG1 вы не можете реализовать foo, который был реализован в LANG2, потому что вам не хватает bar, которое у LANG1 есть, а у LANG2 нет. В Почему некоторые вопросы отмечены как отложенные? нет упоминания о слишком большом количестве ответов, поскольку вопросы причины должны быть закрыты.   -  person user3750103    schedule 18.06.2014
comment
Фактически, он находится прямо там, на странице, на которую вы ссылаетесь: слишком широкий - если на ваш вопрос можно ответить целой книгой или у него много правильных ответов, он, вероятно, слишком широк для нашего формата Либо существует слишком много возможных ответов, либо хорошие ответы будут слишком длинными для этого формата. Добавьте подробности, чтобы сузить набор ответов или выделить проблему, на которую можно ответить в нескольких абзацах.   -  person Joshua Taylor    schedule 19.06.2014
comment
«Макросы Common Lisp использовались, среди прочего, для добавления объектной ориентации поверх Lisp без изменения спецификации языка». Звучит неправильно. Например, CLOS - это нечто большее, чем просто макросы, и для него были изменены спецификации различных языковых средств.   -  person Rainer Joswig    schedule 12.10.2014
comment
На этот вопрос есть очень хороший ответ в замечательной книге Дуга Хойта Let Over Lambda - 50 Years of Lisp, большая часть которого находится в сети. Он опускает только две последние главы, одну о производительности, а другую о реализации форта на Lisp, где вы найдете лучший ответ. Я купил книгу и очень рад, что купил. И Forth, и Lisp - это мощь, потому что вы можете реализовать что угодно поверх любого из них, включая любые макросы (код, который пишет код). Эту книгу стоит приобрести, потому что она раскрывает и обучает макросам, а также отвечает на ваш вопрос.   -  person MicroservicesOnDDD    schedule 06.12.2019


Ответы (3)


На мой взгляд, макросы Common Lisp похожи на немедленные слова Форта. (На самом деле, они больше всего похожи на макросы для чтения Lisp.)

  • Оба они являются процедурными макросами, т. Е. Могут использовать все возможности языка.

  • У них обоих есть доступ к исходному коду.

  • Оба они могут выводить все, что можно выразить на языке. (Например, объектно-ориентированное расширение в Lisp или базовые конструкции потока управления в Forth.)

Основное различие, возможно, будет заключаться в том, что вводимые «макросами» Forth являются символьными строками, а макросы Lisp работают с деревом синтаксического анализа.

person Lars Brinkhoff    schedule 18.06.2014
comment
Макросы Lisp работают с S-выражениями, которые, как я полагаю, могут выглядеть как деревья синтаксического анализа для не-Lisp'ов, но все же. Я упоминаю об этом различии, потому что практически во всех диалектах Лиспа фаза чтения предшествует фазе компиляции, и поэтому Лисперы видят код как данные при написании макросов. Ура гомиконность! (Вы все это четко знаете, поскольку [common-lisp] - это главный тег для вас, но я думаю, что другие читатели тоже должны понимать разницу.) - person Chris Jester-Young; 18.06.2014
comment
Непосредственные слова Forth также могут работать на уровне слов, а не на уровне входного потока - это в основном зависит от того, какие точки настройки предоставляет реализация. Они также могут оставить входной поток нетронутым. Кроме того, с [ и ] для выключения и включения компиляции, соответственно, вы можете определять слова на лету, то есть получать константы времени компиляции и т. Д. Это, кстати, тупо сложно в Python, поэтому для меня Python и FORTH + LISP делятся на два разных класса. Python больше похож на C ++, если бы у него был открытый API парсера constexpr ... - person Kuba hasn't forgotten Monica; 01.07.2021

Я разработчик Forth и имею большой опыт работы с Forth, полдюжины реализаций, несколько сотен проблем с проекторами. Я также сделал небольшое объектно-ориентированное расширение (маленькое, то есть с десяток строк или около того). Мой опыт в LISP гораздо больше на уровне курса, но я думаю, будет справедливо сказать, что средства метапрограммирования LISP более систематичны и на практике более мощны.

Строить абстракции поверх абстракций в LISP относительно легко. В Forth, если я хочу определить матрицу в линейном пространстве, определяемом объектами с нетривиальными определениями, я переключаюсь на Python.

Причина тоже очевидна, по крайней мере, для меня. Создатели LISP, в котором математики, в то время как Чак Мур являются ярким примером практического программиста, никогда не тратящего свое время на теоретические проблемы.

Это распространяется на этот вопрос следующим образом. Макрос lisp имеет структуру в контексте Lisp и, по крайней мере, предлагает значение, которое соответствует общим принципам lisp. Непосредственное слово Forth - это просто еще одна программа, которая может означать и делать что угодно, включая приготовление из него обеда для собак.

person Albert van der Horst    schedule 09.02.2015
comment
Проделав довольно много работы в LISP, Python и FORTH, я бы сказал, что слова FORTH для непосредственного использования имеют, пожалуй, наибольшую силу и обеспечивают высокую выразительность предметно-ориентированных языков. Попробуйте внести исправления во входной поток парсера в Python ... даже в LISP это не для слабонервных. Между прочим, матрица сложных объектов работает лучше в FORTH, потому что вы платите только за те свойства объекта, которые вам действительно нужны - при условии, что ваша реализация не просто копирует Python. В Python таблица виртуальных методов object огромна и является серьезным узким местом при масштабировании. - person Kuba hasn't forgotten Monica; 01.07.2021
comment
В FORTH непосредственные слова - это точка настройки компилятора, похожая на один виртуальный метод. Математически их семантика вполне определена и ее нетрудно окончательно формализовать - за исключением того, что детали, конечно, различаются в зависимости от реализации, поскольку некоторые реализации эффективно предоставляют несколько таких виртуальных методов для переопределения. Но для любой конкретной реализации нетрудно формализовать непосредственные слова. - person Kuba hasn't forgotten Monica; 01.07.2021

Извините, если приведенное ниже обсуждение может показаться немного расплывчатым, но сказать слишком много.

У меня только теоретические знания Лиспа, а не практические.

С другой стороны, у Форта могло быть (но у нормального Форта нет) полное метапрограммирование внутри языка. Но метапрограммирование предполагается и возможно, но без связного синтаксиса. Я думаю, что то же самое происходит в Лиспе.

Я реализовал очень чистое решение, которое включает эту возможность в небольшой парадигме языка Forth. Чтобы иметь возможность метапрограммирования, мы должны иметь возможность ссылаться на то, что пишем. Итак, когда мы пишем программу, которая будет выполняться немедленно, как:

bread eat

мы также должны иметь возможность ссылаться на ту же фразу с намерением вместо того, чтобы выполнять ее, чтобы сохранить ее для дальнейшего использования. Это можно сделать в письменной форме, например

{ bread eat } 

Вышеупомянутая фраза могла, как следствие, оставить созданный объект в стеке. Но поскольку мы создали новое слово как { и }, мы также имеем право ссылаться на него.

Итак, мы хотели бы сослаться на:

{ bread 

Как мы могли это сказать? Предварительный синтаксис: {{ { bread }}.

Если мы дадим название XXX предыдущей фразе, мы можем записать начальную фразу как:

XXX eat }

и фраза выше должна работать правильно, оставляя в стеке

{ bread eat }

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

Очевидно, у нас есть первый бесконечный уровень и каждый последующий уровень. Таким образом, уровни исполнения основаны на математической бесконечности.

Я реализовал все это внутри своего рода форта, и на первом уровне (ниже бесконечности) все работает плавно. Так, например, я могу изменить синтаксис:

{ bread eat } { tomatos eat } x 3 = if 

в:

{ bread eat | tomatos eat } x 3 = if 

Это делается путем определения | как } {, как показано ниже:

{{ } { }} "|" define

или, если вам больше нравится:

2{ } { 2} "|" define 

Вышеупомянутый метод принимает внутри языка с правильным синтаксисом метаязык и делает его языком.

Так что, на мой взгляд, и Лисп, и Форт имеют возможность метапрограммирования, но оба лишены этой возможности как интегрирующей части языка.

У меня есть более подробная информация об этом на napl.wikispaces.com.

person George Kourtis    schedule 28.07.2014
comment
У меня только теоретические знания Лиспа, а не практические. ... Я думаю, что то же самое происходит в Лиспе. - person Rainer Joswig; 12.10.2014