LINUX.ORG.RU

Нужны ли макросы в лиспе?

 


2

2

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

Yes, there is a macro mechanism in PicoLisp, to build and immediately execute a list of expressions. But it is seldom used. Macros are a kludge. Most things where you need macros in other Lisps are directly expressible as functions in PicoLisp, which (as opposed to macros) can be applied, passed around, and debugged. For example, Common Lisp's DO* macro, written as a function:

(de do* "Args"
   (bind (mapcar car (car "Args"))
      (for "A" (car "Args")
         (set (car "A") (eval (cadr "A"))) )
      (until (eval (caadr "Args"))
         (run (cddr "Args"))
         (for "A" (car "Args")
            (and (cddr "A") (set (car "A") (run @))) ) )
      (run (cdadr "Args")) ) )

Есть в сети и еще примеры, довольно много, где макросы откровенно отсасывают. Их часто сравнивают с фэкспрами, причем, оказывается, в лисп среде, до появления компиляторов, лисперы действительно считали макросы достаточно слабым и редкоиспользуемым инструментом. Насколько я понимаю, основная претензия к ним, не столько в том, что они громоздки, многословны и невыразительны, хотя это тоже, сколько в том, что они не first-class.

Так может быть легенды о мощности лисповских макросов сильно преувеличены? Может быть, их использование — это, всего лишь, дань моде и вынужденный компромисс между выразительностью языка и возможностью компиляции?



Последнее исправление: phill (всего исправлений: 1)

picolisp не компилируемый //походу
разница в том что в Common Lisp макросы могут быть раскрыты вовремя компиляции. Вот как вычисления на шаблонах С++.

Bad_ptr ★★★★★
()

PicoLisp интерпретируемое встраиваемое говно (хоть и хорошее), разумеется там макросы не нужны, чего не скажешь о нормальных лиспах. Тебе слова compile-time и eDSL о чём-нибудь говорят? Посмотри на cl-irregsexp хотя бы.

mix_mix ★★★★★
()

Нужен ли очередной лиспосрач?

/fixed

tailgunner ★★★★★
()
Ответ на: комментарий от unlog1c

Эвал - это функция, почему она не first-class? Функции в лиспе, обычно считаются first, вроде бы.

(set 'a 1)
(set 'test (quote(x y) (x y)))
(w (test eval 'a))
Тут eval не first, по Вашему? Почему?

phill
() автор топика
Ответ на: комментарий от mix_mix

PicoLisp интерпретируемое встраиваемое говно (хоть и хорошее)

А почему, кстати, если интерпретируемый, то сразу говно? Я смотрел тасты, Picolisp быстрый, и в большинстве случаев, быстрей CL. Если язык выигрывает в мощности, и не проигрывает в скорости, а при этом еще проще и легче, то чем он хуже компилируемого?

phill
() автор топика
Ответ на: комментарий от phill

при чем тут eDSL

Можно встроить в язык абсолютно всё, что хочешь, посмотри на loop в качестве самого простого примера.

mix_mix ★★★★★
()

Убогие интерпретаторы не нужны. Макросы это тупо расширения компилятора. Кто компиляцию не осилил, тот может гулять мимо.

anonymous
()
Ответ на: комментарий от phill

Ололо. Это говно на два порядка тормознее чем CL.

anonymous
()
Ответ на: комментарий от phill

Ну давай, реализуй на своих чмошных fexpr-ах эффективный движок регулярных выражений, а потом еще и генератор lalr(1) парсеров. Обосрешься.

anonymous
()
Ответ на: комментарий от unlog1c

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

phill
() автор топика
Ответ на: комментарий от elyadow

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

Мне кажется, что чтобы понять суть макросов, много ума не нужно. Они делают то же самое, что фэкспры, только бесильны в рантайме. Т.е. — это урезанное, по самое небалуйся, ограниченное компилтаймом метапрограммирование, без рефлексии и интроспекции. Какая еще у них «особая» суть?

phill
() автор топика
Ответ на: комментарий от phill

Они делают то же самое, что фэкспры, только бесильны в рантайме.

На хера делать в рантайме то, что надо делать во время компиляции?

без рефлексии и интроспекции.

Оно не нужно.

anonymous
()
Ответ на: комментарий от unlog1c

Scheme

(define y 10)
(let ((y 1)) (eval '(+ y 1))); 11
Picolisp:
(let ((y 1)) (eval '(+ y 1)))# 2
Это вообще ни о чем. И ты не путай теплое с мягким, ты не понимаешь, что такое first-class, учи матчасть.

anonymous
()
Ответ на: комментарий от anonymous

На хера делать в рантайме то, что надо делать во время компиляции?

Ты неправильно ворос ставишь. Все что можно сделать во время компиляции, можно сделать и в рантайме, но не наоборот. Это и есть основное ограничение.

phill
() автор топика
Ответ на: комментарий от phill

Все что можно сделать во время компиляции, можно сделать и в рантайме, но не наоборот.

Повторяю вопрос: на хера делать в рантайме то, что надо делать во время компиляции?

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

anonymous
()
Ответ на: комментарий от Bad_ptr

разница в том что в Common Lisp макросы могут быть раскрыты вовремя компиляции. Вот как вычисления на шаблонах С++.

Плохое сравнение, ИМХО. В том и дело, что это просто механизм преобразования одного выражения в другое. Нормально вычисления в compile time так не сделать

anonymous
()
Ответ на: комментарий от Bad_ptr

разница в том что в Common Lisp макросы могут быть раскрыты вовремя компиляции

Только лишь и исключительно во время компиляции. Это не преимущество, а недостаток. Достоинство (сомнительное) здесь не в самих макросах, а в том, что код с макросами легко компилируется, а с fexprs — нет.

anonymous
()
Ответ на: комментарий от elyadow

Ума большого не нужно, это да, только у вас, похоже, ум меньше даже среднего.

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

phill
() автор топика
Ответ на: комментарий от phill

большинстве случаев, быстрей CL.

Похоже, подонок, ты так ничему и не научился. Мы же разбирали с тобой, что в твоих «тастах» писолисп был обвязкой для C кода. И сравнивался он с самой медленной - хотя в очень даже отличненькой - реализацией common lisp'а - clisp'ом

anonymous
()
Ответ на: комментарий от anonymous

Вы перепутали, это был не я. И я не настаиваю, что picolisp быстрей CL'а, на спецефичных для компилятора задачах. Но лисп, это, вообще-то, не скорость, для этого есть асм и си, лисп - это обработка списков и символьные вычисления, а здесь CL отсасывает очень глубоко. Хочешь иметь еще один цифродрочер — вперед, никто не мешает. И повторяю, в том треде, о котором ты говоришь, где тебя поимели, твоим опонентом был не я, там пограмотней меня человек был, а я начинающий.

phill
() автор топика
Ответ на: комментарий от phill

Вы перепутали, это был не я.

А твой сосед что ли? :) Так или иначе я-то тебя запомнил. Видимо просто ФГМ автора пиколиспа по какой-то причине неизбежно распространяется на его пользователей.

лисп - это обработка списков и символьные вычисления

А пацаны и не знали

там пограмотней меня человек был

О, да ты в курсе да?

где тебя поимели

В твоих влажный фантазиях. И да CL тебе ничем не обязан. Не нравится - не используй

anonymous
()
Ответ на: комментарий от lovesan

А ну, блесни интелектом, напиши аналог функции DO на своем говне cl, чтоб пацаны могли его как аргумент функции использовать и возвращать, комбинировать в map/reduce, модифицировать в рантайме, парсить, вперед, епт, докажи, что ты не обосрался в очередной раз, не просто тяфкнул как шавка из-под забора, а тебе реально есть что сказать. Дерзай. Тебе, мля, с твоими мозгами не в лисп срачах участвовать, а в плюсовых. Ба, да ты ж и есть плюсовичек, как я мог забыть, плюсовое быдло, во всей красе, а за лисп, чиста, с большими дядьками потереть(ся) пришел, да?

anonymous
()
Ответ на: комментарий от anonymous

напиши аналог функции DO

нафейхоа?

x4DA ★★★★★
()

Можно ли сделать fexprы на макросах? Да.

Можно ли сделать макросы на fexprах? Нет.

x4DA ★★★★★
()
Ответ на: комментарий от x4DA

Можно ли сделать fexprы на макросах? Да.
Можно ли сделать макросы на fexprах? Нет.

Бред сивой кобылы.

anonymous
()

неоптимизируемое говно

($define! foldr
  ($lambda (c n xs)
    ($if (null? xs)
         n
($let ((ys (foldr c n (cdr xs)))) 
(c (car xs) ys))

sapienti sat

x4DA ★★★★★
()
Ответ на: комментарий от x4DA

Можно ли сделать fexprы на макросах? Да.

Как ты можешь сделать fexprs на макросах, умник, если fexprs — это функции, которые МОГУТ не вычислять свои аргументы в рантайме, тогда как макросы все го ли шь трансформируют код в компилтайме.

Можно ли сделать макросы на fexprах? Нет.

Сама постановка глупа до безобразия. Fexpr'ы могут сделать ровно то же самое, что и макры, и нет нужды делать никакие макросы на fexpr'ах, но какие ты, вообще говоря, собрался делать макросы? Которые раскрываются в компилтайме? Том самом, которого вообще нет в Picolisp? Ты идиот?

anonymous
()
Ответ на: комментарий от anonymous

Это пустые слова. Аргументы. Я подозреваю, что ты не понимаешь не только лисп, но и программирование вообще.

anonymous
()

сколько в том, что они не first-class

Конечно они не first-class, ведь это сущности из следующего метауровня. FEXPR просто схлопывает все метауровни в один. Как, к примеру, Lisp-1 схлопывает все пространства имён в одно. С аналогичными последствиями для применимости оптимизаций.

ilammy ★★★
()
Ответ на: комментарий от ilammy

FEXPR просто схлопывает все метауровни в один

Значит ли это, что fexpr'ы могут поднять нас на неограниченое число метауровней, а макросы, только на один?

phill
() автор топика
Ответ на: комментарий от phill

в чем же особое волшебство макросов, на котором Вы настаиваете

Тебе же два раза написали: на хера делать в рантайме то, что надо делать во время компиляции? Compile-time бесплатный в отличии от. Представь RegEx-либу, которая на лету во время компиляции генерит эффективный код для конкретного регэкспа. Представь, что ты можешь расширять компилятор как тебе заблагорассудится, наворачивать какие угодно DSL под конкретную задачу, при этом иметь нулевую просадку производительности от твоих абстракций.

mix_mix ★★★★★
()
Ответ на: комментарий от mix_mix

Он щас вам скажет одну из двух: или «лисп был создан не для этого!!!111», или «тем не менее гениальный супер-пупер picolisp обходит в производительности CL благодаря божьей искре в нём!»

AVC_Verehrer
()
Ответ на: комментарий от mix_mix

То, что Вы пишите, понятно идиоту. Вопрос был в том ЧТО могут, а не «за какое время». К тому же,

бесплатный

сыр только в мышеловке. За это приходится расплачиваться мощностью языка.

phill
() автор топика
Ответ на: комментарий от phill

Вопрос был в том ЧТО могут, а не «за какое время».

Всё могут.

За это приходится расплачиваться мощностью языка.

Что не так с мощностью языка?

mix_mix ★★★★★
()
Ответ на: комментарий от AVC_Verehrer

обходит в производительности CL

Все, что не касается быдлооптимизаций, это действительно так.

лисп был создан не для этого

Вы с этим не согласны?

phill
() автор топика
Ответ на: комментарий от phill

На CL пишут реальные программы, а быдлооптимизациями занимаются, видимо, адепты Бургера, подрачивая на мифическую «производительность выше CL без всяких быдлооптимизаций»

AVC_Verehrer
()
Ответ на: комментарий от mix_mix

Что не так с мощностью языка?

То, что макросы и специальные формы не являются органичной частью языка, это костыли, превращающие, порой, тривиальную задачу в тонны кода. Они - не first-class сущности. Кроме того, приходиться распрощаться с «эквивалентностью кода и данных». Хотя CL'овцы все еще верят, что в их ЯП код - это данные, это не так. В схеме дела с этим еще хуже.

phill
() автор топика
Ответ на: комментарий от phill

порой, тривиальную задачу в тонны кода.

Нет, они сделаны с точностью до наоборот.

Они - не first-class сущности.

Breaking news!

Хотя CL'овцы все еще верят

Эти же люди верят что лисп пишется как «LISP» и используется для создания ИИ безумным ученым полковником Сандерсом

AVC_Verehrer
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.