[Lisp] Знаки препинания

pilot

(defmacro ab (a b)
(let bb (gensym
(macrolet c (d) `(list 'print '(1+ ,d
`(let bb ,b
(print ,a)
(print c bb

> (pprint (macroexpand-1 '(ab f g

(LET #:G177117 G (PRINT F) (PRINT (PRINT (1+ BB
; No value

А хочется получить
 (LET #:G177117 G (PRINT F) (PRINT (PRINT (1+ G

Как?

Ivan8209

Не знаю, что ты хочешь, но

[1]> (defmacro ab (a b)
(let bb (gensym
`(let bb ,b (print ,a) (print (print (1+ ,b

AB
[2]> (pprint (macroexpand-1 '(ab f g

(LET #:G2910 G (PRINT F) (PRINT (PRINT (1+ G

---
...Я работаю антинаучным аферистом...

pilot

Не знаю, что ты хочешь
Угу. Хочу локальный макрос использовать при определении глобального.
Что-то типа того, только letted встречается раз 5 и в нем в or 10 условий. Я привожу тестовое-минимизированное.
(macrolet letted (first)
`(or
(= ,first 32)
(= ,first 73
(defmacro abc (runes-arg)
(let runes (gensym
(rune (gensym
`(let runes ,runes-arg
(some #'(lambda rune) letted rune ,runes

Ivan8209

Ладно, я подумаю, но это потребует времени.
Вообще же, вы маньяки, такой головоломный код использовать,
наверняка там можно как-то всё упростить.
---
...Я работаю антинаучным аферистом...

Ivan8209

Появилось рабочее предположение.
Есть подозрение, что макроподстановка не работает внутри quote и
quasiquote. Сможешь пропинать quote/quasiquote вглубь S-выражений?
Или проверить по стандарту, как отрабатывается макроподстановка.
---
...Я работаю антинаучным аферистом...

Ivan8209

> (LET #:G177117 G (PRINT F) (PRINT (PRINT (1+ G
Мне почему-то думается, что ты имеешь в виду
(LET #:G177117 G (PRINT F) (PRINT (PRINT (1+ #:G177117
потому что
(c bb) -> (c (gensym -> (print (1+ (gensym

[91]> (defmacro ab (a b)
(let bb (gensym
(flet c (d) `(print (1+ ,d
`(let bb ,b
(print ,a)
(print c bb

AB
[92]> (macroexpand '(ab f g
(LET #:G3083 G (PRINT F) (PRINT (PRINT (1+ #:G3083 ;

Оно?
---
...Я работаю антинаучным аферистом...

Papazyan

Есть подозрение, что макроподстановка не работает внутри quote и
quasiquote.
Аргументы макроса не эвалуэйтятся (что логично поэтому macrolet и не работает. Надо код менять на вменяемый.

Ivan8209

Я думаю, что там надо чётко понимать порядок чтения и применения
макроподстановок, последнее надо найти в документации и
внимательно прочитать. Лично я ещё не понял, почему

[6]> (macrolet this (x) (print x (macroexpand '(this x
(THIS X) ;
NIL
[9]> (macrolet this (x) (print x (this 'x

'X
X

Надо придумать, как сделать (или где взять) macroexpand на схеме.
---
...Я работаю антинаучным аферистом...

Ivan8209

> (let bb (gensym
У меня есть предложение, которому ты не последуешь.
Чтобы не мучаться с gensym и всеми этими quasiquote,
использовал бы ты гигиеничные (hygienic) макросы.
Нет у тебя такого кода, где ими нельзя обойтись.
Location: http://www.ccs.neu.edu/home/dorai/mbe/mbe-lsp.html
---
...Я работаю антинаучным аферистом...

Papazyan

Во втором примере все логично. eval (this 'x) -> eval (print 'x) -> 'x is undefined.
Первый мне не понятен, может это macroexpand так и должен работать. Может там ' не нужна.

Ivan8209

> Первый мне не понятен, может это macroexpand так и должен работать.
Мне очень не хочется читать стандарт.
> Может там ' не нужна.

[12]> (macrolet this (x) (print x (macroexpand (this 'x

'X
X ;
NIL

Верно.
---
...Я работаю...

pilot

Вот еще вопрос:
Как красиво писать такое:

if f1(a):
f2(f1(a
else:
a

Что на Лиспе:

(let tmp f1(a
(if tmp f2(tmp) a

У меня встречается сплошь и рядом.

Ivan8209

http://srfi.schemers.org/srfi-2/srfi-2.html
---
...Я работаю антинаучным аферистом...

vook

Это не эквивалентные куски кода: в первом случае f1(a) запускается два раза и за счет сайд-эффектов результат может быть разным.
А вообще если что то встречается сплошь и рядом, то имеет смысл написать макрос, как завещал Пол Грэхэм
http://www.bookshelf.jp/texi/onlisp/onlisp_15.html#Anaphoric...

pilot

Это не эквивалентные куски кода: в первом случае f1(a) запускается два раза и за счет сайд-эффектов результат может быть разным.
Мне это казалось очевидным.
А за ссылку спасибо.
Хотя и не нравится variable capture.
Насколько затратный по производительности let? По идее минимально должен быть.
Сам макрос в голову сразу приходит, другое дело насколько он оптимизируется, и как такое решается в других языках.

Ivan8209

> А вообще если что то встречается сплошь и рядом,
> то имеет смысл написать макрос, как завещал Пол Грэхэм
Ты сможешь грамотно написать этот макрос?
Из разговора выше видно, что процедурные макросы писать очень
даже не просто. Особенно, когда сам не понимаешь, что хочешь.
Да, тех макросов, о которых говорит Грахам, может и не хватить.
---
...Я работаю антинаучным аферистом...

Ivan8209

> Насколько затратный по производительности let?
Тебе это проще замерить или спросить самому в c.l.l или где ещё.
> другое дело насколько он оптимизируется
Ты когда-нибудь видел, как пишут библиотеки на той же схеме, где
оптимизация хвостовой рекурсии является требованием стандарта?
Если обеспокоен производительностью, посмотри.
Попробуй порыться в библиотеках, наверняка там уже есть and-let*
или его аналог. Хотя чёрт их всех разберёт.
---
...Я работаю антинаучным аферистом...

vook

Ты сможешь грамотно написать этот макрос?
Я писал такие макросы, что тебе и не снилось

kruzer25

и за счет сайд-эффектов результат может быть разным
А контра тут в соседнем треде сказал, что, если есть неоднозначности, то это - не Язык Программирования

tokuchu

А контра тут в соседнем треде сказал, что, если есть неоднозначности, то это - не Язык Программирования
Это не однозначности - там 2 разных выражения. Если есть побочные эффекты от вызова функции - то эти выражения нельзя приравнивать. А если нет - то можно.

kruzer25

Если есть побочные эффекты от вызова функции - то эти выражения нельзя приравнивать
И чем это лучше C?

tokuchu

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

Ivan8209

> И чем это лучше C?
Тем, что такой стиль программирования не поощряется удобством записи.
---
...Я работаю антинаучным аферистом...

kruzer25

и там совсем другой случай
Чем другой?

tokuchu

Чем другой?
Ты придуриваешься что ли?
Видишь разницу:
1) ОДНО выражение: "++i + ++i" может давать разные значения в разных компиляторах.
2) ДВА РАЗНЫХ выражения: { b = f(a); if (b) g(b); else a; } и { if (f(a g(f(a; else a; }. Во 2-м функция f(a) может быть вызвана ДВА раза, хоть и с одним аргументом. И поэтому ЕСТЕСТВЕННО, что если функция f(a) имеет побочные эффекты, то значения выражений могут отличаться.

kruzer25

Блин.... не заметил про разные куски
Оставить комментарий
Имя или ник:
Комментарий: