о let, sbcl и dynamic scope

Jun 17, 2009 14:44

В результате отладки своего проекта наткнулся на вот такое "нихрена себе!":

CL-USER> (defmacro broken ()
(let ((x (gensym)))
`(format nil "x = ~a" ',x)))
BROKEN
CL-USER> (values
(broken)

(let (not-used)
(broken))

(let (not-used)
(broken))

(let ()
(broken)))

"x = G10330"
"x = G0"
"x = G0"
"x = G10331"

SBCL собран из trunk. Проверялось так же на 1.0.29/win32 (последний релиз на 17.06.2009), 1.0.13/win32, 1.0.18/linux. Везде результат один.

Для сравнения (как должно быть):

ECL (Embeddable Common-Lisp) 9.5.1
Copyright (C) 1984 Taiichi Yuasa and Masami Hagiya
Copyright (C) 1993 Giuseppe Attardi
Copyright (C) 2000 Juan J. Garcia-Ripoll
ECL is free software, and you are welcome to redistribute it
under certain conditions; see file 'Copyright' for details.
Type :h for Help. Top level.
> (defmacro broken ()
(let ((x (gensym)))
`(format nil "x = ~a" ',x)))

BROKEN
> (values
(progn
(broken))

(let (not-used)
(broken))

(let (not-used)
(broken))

(let ()
(broken)) )

"x = G111"
"x = G112"
"x = G113"
"x = G114"
>

Т.е. что мы видим? Наличие формы let с какой-либо переменной (не обязательно динамической), срывает нафиг dynamic scope в macro expansion time. Это пиздец, господа!
UPD: Отрепортил
UPD2: Это не бага, это я йолоп. (gensym) не гарантирует уникальность имени. Он гарантирует уникальность объектов. А подробности такого поведения SBCL в комментах к баге. Такие дела.

lisp, ненависть, профзаметки

Previous post Next post
Up