[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Destructuring, GLS's and RMS's suggestions, and &EVAL.



A little secret:
    Date: 2 October 1980 22:20-EDT
    From: Carl W. Hoffman <CWH at MIT-MC>
    Subject: Dave Touretzky's message on macros, destructuring, and functions
    I like your DESTRUCTURE function idea a lot.  Could such a thing be
    implemented for MacLisp?
The destructuring DEFUN has been in MacLISP for a long time -- since the
LISP RECENT note of
" Sunday December 9,1979 FM+5D.18H.52M.12S. LISP 1914/COMPLR 904 -JONL,RWK- "
(with ocasional lapses of proper interfaceing between DEFUN and DEFUN/&,
 cough, cough!)
For example, note this little example in the current MacLISP:
  (SETQ DEFUN&-CHECK-ARGS () )
  (DEFUN FOO ( ((B . C) (D E))  A  &OPTIONAL ((G . H) E /3RD?)  &REST W) 
	(mumble))
  (GRINDEF FOO)
==>
  (DEFUN FOO G0005 
    (COMMENT ARGLIST = (((B . C) (D E)) A &OPTIONAL ((G . H) E /3RD?) &REST W))
    (LET ((W (AND (> G0005 3) (LISTIFY (- 3 G0005))))
	  (A (ARG 2))
	  (((B . C) (D E)) (ARG 1))
	  G H /3RD?)
	 (DESETQ (G . H) (COND ((> G0005 2) (ARG 3)) (E)))
	 (AND (> G0005 2) (SETQ /3RD? 'T))
	 (mumble)))

I have one or two comments on the extension Proposed by GLS
    Date:  2 October 1980 1340-EDT (Thursday)
    From: Guy.Steele at CMU-10A
    .  .  .  We can ignore &AUX by fiat, and &REST is the same
    (in some sense) as ".", so that leaves &OPTIONAL.  I might suggest
    extending JONL's BNF slightly to allow non-top-level &OPTIONALs:
    .  .  .
    Adding &OPTIONAL into RMS's syntax is more difficult.  I'm working
    on that.  May not be worth it?
If I understand the BNF right, the extension would allow for forms like
  (LET ( ((A B &OPTIONAL (C '35)) <x>) )
	<do-something>)
which would differ from
  (LET ( ((A B C) <x>) )
	<do-something>)
only in that if <x> is a list of length less than 3, then C is bound to '35
instead of ().  This would restrict binding a variable with the name
&OPTIONAL, which is a minor loss since such a variable can't now be bound
in a DEFUN's variable list, leaving only an explicit LAMBDA as a way to
bind this variable (yea, verry minor loss!).  Presumably the former would
be preferable to doing it by hand
    (LET ( ((A B . Z) <x>) 
	   (C (IF Z (CAR Z) '35)) )
	<do-something>)

A more serious problem to be faced is working RMS's destructuring syntax 
into the alread-extensively used MacLISP destructuring scheme:
    Date:  1 OCT 1980 2132-EDT
    From: RMS at MIT-AI (Richard M. Stallman)
    I think that destructuring in DEFUN would be a reasonable idea.
    .  .  . 
    However, I don't think that the Maclisp style of destructuring should
    be adopted at all.  It closes out the entire syntactc space -- if you
    adopt it, you can't ever allow anything else, because there is no room
    for an escape.  .  .  .
    If destructuring is done as follows:
    (defun foo (x (list z (list w y))) ...)
    or, equivalently
    (defun foo (x `(,z (,w ,y))) ...)
    .  .  .
With all respect, I'd like to offer an "escape" for the data-formatted
destructuring which would allow intermixing of the program-formatted
destructuring:  &EVAL.   If something like GLS's &OPTIONAL were
to be adopted into the data-formatted scheme, then the precedent is
already set for "escapes" in general.  Thus two ways to write the "foo"
above would be
    (defun foo (x (&eval (list z (list w y)))) ...)
or, if "#@" could be another "quoter" producing (&eval ...), then
    (defun foo (x #@`(,z (,w ,y))) ...)
In the program-formatted destructuring syntax (which I've been attributing
to RMS), the "escape" to data-directed format could be, say, &QUOTE.
Consider a "mixed-mode" in both schemes:
  data-formatted style:
   (DEFUN FOO (X (Z (&eval (list W Y)) ) <do-something>)
  program-formatted style:
   (DEFUN FOO (X (list Z (&quote (w y)) ) <do-something>)
The duality of "escapes" cannot be escaped here, and was probably the
subject of some thesis or paper 15 (or so) years ago.  

However, there is very little at all to be gained by using the program-
formatted destructuring only to destructure over data -- the data-formatted
would always be more concise.  But as RMS points out, one would not like
to close the door to syntactic extensions which would allow binding
something other than a variable, and the program-formatted is the more
general choice here.

One more possibility for extension is to include a little "matching"
along with the destructuring -- for example, suppose one wants to
destructure a list which is supposed to be a LAMBDA list into two
parts, the Bound-Variable-List and the Body.  He could say
   (DESETQ ( ()  BVL . BODY) <list>)
or alternatively,
   (DESETQ (&eval `(LAMBDA ,BVL ,. BODY)) <list>)
only in the latter form, the explicit quote on LAMBDA would mean not
only that nothing is to be bound at this point (just as the () means
in the former), but also that a check should be performed to see
that the car of <list> is equal to LAMBDA.  But I digress -- I don't
want to resurrect arguments over how much of a pattern-matching
language should be built into LISP.