emacs-devel
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]