The predecessor language to Dennis Ritchie's work on B and C, namely BCPL, uses
some Lisp like concepts in its definition, and had some features that were
actually done better than their C counterparts. It could be argued that C is
not strictly a better BCPL in every regard:
- ``Storage duration'' is called, guess what, ``extent''!
- ``Automatic storage'' (objects with lifetimes tied to a scope, which are
destroyed when dynamic instance of the scope terminates) are called, guess
what, ``dynamic''. The predecessor to C had dynamic extent.
- Blocks with return are supported: VALOF, RESULTIS.
- Parallel bindings in LET construct (by means AND keyword).
- 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.
- No bizarre restrictions.
- No passing of a value, but returning an int value via longjmp has limited
utility anyway.
- Contrast with C longjmp:
- values of local variables that are modified after setjmp buf before
longjmp are indeterminate, unless the variables are volatile.
- longjmp can only return to setjmp point, not to any label.
- restrictions on the kind of expression in which setjmp can appear,
and how its return value may be used.
Sources:
Clive Feather's ``Briefish Description'' of BCPL:
http://www.lysator.liu.se/c/clive-on-bcpl.html
Martin Richards's BCPL Reference Manual:
http://www.cs.bell-labs.com/who/dmr/bcpl.pdf
C99 Draft (regarding setjmp and longjmp restrictions)
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf
Kaz Kylheku <········@gmail.com> 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: ;-}
(tagbody
here
...
(foo (savejmps here there elswehere) otherargs...)
...
there
...
elswehere
...)
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! ;-}
-Rob
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" <http://home.pipeline.com/~hbaker1/MetaCircular.html>.
-----
Rob Warnock <····@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607
budden wrote:
> I never worked with Common Lisp predecessors, but I guess they were
> better than Common Lisp itself. World degrades.
You guess.
hth,kth
+ Kenneth Tilton <·········@gmail.com>:
> budden wrote:
>> I never worked with Common Lisp predecessors, but I guess they were
>> better than Common Lisp itself. World degrades.
>
> You guess.
His guess is as good as ...
... his guess.
--
* Harald Hanche-Olsen <URL:http://www.math.ntnu.no/~hanche/>
- It is undesirable to believe a proposition
when there is no ground whatsoever for supposing it is true.
-- Bertrand Russell
budden <···········@mail.ru> writes:
> I never worked with Common Lisp predecessors, but I guess they were
> better than Common Lisp itself. World degrades.
There certainly were some features in those Lisps that would still
need a port to CL. If only the OS (Lisp Machine OS I mean ;-)). On
the other hand, it's quite possible that Common Lisp saved lisp,
during the AI winter. Like a time capsule. Perhaps that without it,
the others would have been forgotten all the same.
--
__Pascal Bourguignon__
On 2009-02-06, budden <···········@mail.ru> wrote:
> I never worked with Common Lisp predecessors, but I guess they were
> better than Common Lisp itself. World degrades.
If your point is that I have never worked with BCPL, but am guessing, you are
wrong. I can read a specification. And, by the way, I didn't say BCPL is better
than its successors. Only that not everything in its successors is strictly an
improvement over its BCPL counterpart.
> If your point is that I have never worked with BCPL, but am guessing, you are
> wrong.
No, this was no irony. This is just my opinion about Common Lisp (and
the world). I do not say either that Common Lisp predecessors are
strictly better than Common Lisp in all directions, but losses are
essential too.