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

Issue: DESTRUCTURING-BIND (Version 1)



Issue:        DESTRUCTURING-BIND
Forum:	      Cleanup
References:   The LOOP Facility (X3J13/89-004)
Category:     ADDITION
Edit history: 24-Jan-89, Version 1 by Pitman
Status:	      For Internal Discussion

Problem Description:

  Programmers have frequently requested an interface to a destructuring
  bind facility similar to that available in DEFMACRO.

  To date, the excuse for not satisfying this request has been a religious
  war between factions who want to destructure lists by writing
    (DESTRUCTURING-BIND (var1 var2 var3) exp . body)
  and those who want to destructure lists by writing
    (DESTRUCTURING-BIND (LIST var1 var2 var3) exp . body)

  The advantage of the former approach is that it is notationally concise
  for the common case of destructuring a list. The disadvantage is that
  it is not extensible to accomodate abstract kinds of destructuring.

  The advantage of the latter approach is that it allows interesting
  extensions that accomodate data-hiding, such as:
    (DEFMACRO MAKE-FOO (&REST ELEMENTS) `(LIST ,@ELEMENTS))
    (DESTRUCTURING-BIND (MAKE-FOO var1 var2 var3) exp . body)
  and later the ability to change the representation of a FOO without
  updating the associated binding forms. The disadvantage is that it
  is more verbose in the common case of destructuring a list, and still
  even more verbose for nested lists.

  Destructuring always existed in DEFMACRO, but since forms seen by the
  evaluator are generally just lists, rather than arbitrary user-defined
  abstract data types, an argument for destructuring of the second kind
  in that circumstance seemed like overkill to most people.

Proposal (DESTRUCTURING-BIND:NEW-MACRO):

  Provide a macro called DESTRUCTURING-BIND which behaves like the
  destructuring bind in DEFMACRO.

  (DESTRUCTURING-BIND pattern datum . body)

  evaluates datum, binds the indicated pattern variables, and then
  executes the body.

  Clarify that LOOP does not permit the use of &keywords in its
  destructuring, and that proper lists are implicitly `&REST ignore'
  (where the variable is quietly ignored).

Test Case:

  (DEFUN IOTA (N) (LOOP FOR I FROM 1 TO N COLLECT I)) ;helper

  (DESTRUCTURING-BIND ((A &OPTIONAL (B 'BEE)) ONE TWO THREE)
		      `((ALPHA) ,@(IOTA 3))
    (LIST A B THREE TWO ONE))
  => (ALPHA BEE 3 2 1)

Rationale:

  Now that LOOP has been introduced into the language with destructuring
  of the first kind, rules of internal consistency could be used to 
  bypass religious arguments in order to satisfy user common needs.

  Prior to the introduction of LET into Maclisp, many people wrote their
  own LET macros. A popular expansion was in terms of a DO which did not
  iterate. eg,
    (LET ((A 3)) (+ A A)) ==> (DO ((A 3)) () (RETURN (+ A A)))
  While this practice worked, it was not perspicuous and contributed 
  substantially to non-readability: not only were the macros hard to
  understand, but the surface interface itself was not standardized
  and varied in subtle ways.

  There is now considerable danger that a lot of people will write
  DESTRUCTURING-BIND variants in terms of a LOOP expression that
  immediately returns.
    (DESTRUCTURING-BIND ((A B) C) (FOO) (LIST A B C))
    ==> (LOOP FOR ((A B) C) ON (FOO) DO (RETURN (LIST A B C)))
  We should help to head off the evolution of a number of uselessly
  different variants by simply institutionalizing the real support
  for this.

Current Practice:

  Symbolics Genera already offers this extension.

Cost to Implementors:

  Very small. In most cases, it's a matter of renaming and/or exporting an
  already existing symbol. In a few cases, a very small amount of 
  `program interface' code would have to be written.

Cost to Users:

  None. This is an upward compatible change.

Cost of Non-Adoption:

  Loss of the Benefits and Aesthetics cited below.

Benefits:

  Users will get a powerful feature they have asked for on many occassions.

  In implementations which `autoload' code, it would be better for this
  support to be separable so that people could do DESTRUCTURING-BIND
  without demand loading all other LOOP support.

Aesthetics:

  Defining this macro centrally will reduce subtle deviations, which will
  have positive aesthetic impact.

  Defining this facility allows other tools like DEFMACRO and LOOP to be
  defined in terms of it. That modularization of description is also a
  positive change.

Discussion:

  Pitman was on the side of the abstract destructuring and isn't the
  slightest bit happy about the kind of destructuring which snuck in
  on the `LOOP trojan horse.' However, he thinks something like this
  is the rational thing to do at this point. The details are not so
  important as coming up with a nice, unified story.