Subject: Re: BCPL curiosities.
From: (Rob Warnock)
Date: Thu, 05 Feb 2009 20:54:02 -0600
Newsgroups: comp.lang.lisp
Message-ID: <>
Kaz Kylheku  <> wrote:
| - setjmp/longjmp analog was called ``jump closures'', and was arguably
|   more sanely designed:
|   - the LEVEL() function neatly returns a ``closure'' for the current scoipe.
|   - LONGJMP (closure, label) jumps to the given labelled statement in the
|     closure; the label is a normal one that can be used with GOTO.

You can come quite close to that in CL, but I think the LEVEL would need
to enumerate the labels the LONGJMP can invoke (and therefore LEVEL would
have to be a macro). Just for fun, let's call it SAVEJMPS instead:  ;-}

	(foo (savejmps here there elswehere) otherargs...)

Then you could use it like this in FOO:

    (defun foo (jumper otherargs...)
      (when (some-condition)
	(funcall jumper 'there))

Possible definition of SAVEJMPS:

    (defmacro savejmps (&rest tags)
      (let ((where (gensym))
	    (cases (mapcar (lambda (tag) `((,tag) (go ,tag))) tags)))
        `(lambda (,where) (ecase ,where ,@cases))))

Note that the above doesn't require a LONGJMP macro, but does require
the target tag to be quoted when calling the saved jumper. But if you
insist on using the tags unquoted, then define LONGJMP as follows:

    (defmacro longjmp (saved-jumper tag)
      `(funcall ,saved-jumper ',tag))

and then use it in FOO this way:

    (defun foo (jmpbuf otherargs...)
      (when {some-condition}
	(longjmp jmpbuf there))

Eeeww, that's gross!  ...but part of why I *love* Lisp!  ;-}


p.s. Note that you can have several different "jumpers" active
at once, each one with a different set of enabled tags (though
possibly overlapping!).

p.p.s. The above will be instantly obvious to anyone who has read
Henry Baker's paper on "Metacircular Semantics for Common Lisp
Special Forms" <>.

Rob Warnock			<>
627 26th Avenue			<URL:>
San Mateo, CA 94403		(650)572-2607