[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
cl-block less lexical than expected
From: |
Robin Tarsiger |
Subject: |
cl-block less lexical than expected |
Date: |
Thu, 30 Dec 2021 12:12:52 -0600 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.4.1 |
Greetings.
Today I was poking around with elisp and decided to look at the
definitions of cl-block and cl-return-from. These are predictably
described in the elisp manual as using lexical tags along the lines
of how actual-CL block and return-from work. However, the way the
macros are implemented doesn't line up with this; they do a static
transformation on the tag name and then intern the result for use
with catch/throw, and that yields dynamic semantics:
(defun tmp/cl-block-test-1 ()
(cl-block foo
(cl-return-from foo 'ok)
'not-reached))
(defun tmp/cl-block-test-2 ()
(cl-return-from foo 'bad))
(defun tmp/cl-block-test-3 ()
(cl-block foo
(tmp/cl-block-test-2)
;; Necessary to avoid the catch being discarded.
(cl-return-from foo 'correct)))
(tmp/cl-block-test-1)
==> ok ; This is fine.
(tmp/cl-block-test-2)
==> <signals error> ; Also okay.
(tmp/cl-block-test-3)
==> bad ; But the foo block isn't actually lexical!
I have to think that since catch and throw both take evaluated
expressions for their tags, a more suitable implementation might
do a static transformation to choose an out-of-the-way lexical
_variable_ name which would then be let-bound to a gensym during
the body. cl-return-from could then try to evaluate the variable
to get the tag; the warnings/errors for bad tags would be awkward
to read, but at least the semantics would be correct. An unbound
tag variable would also be warned about during byte-compilation.
Thoughts?
-RTT
- cl-block less lexical than expected,
Robin Tarsiger <=