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

Issue: LAMBDA-FORM (Version 4)



I added to the cost, benefits and discussion section in an attempt to
reflect the subsequent discussion. NACKs only, please.

!
Forum: CLeanup
Issue:        LAMBDA-FORM
References:   LAMBDA (p59)
Related Issues: LISP-SYMBOL-REDEFINITION, PACKAGE-CLUTTER
Category:     ADDITION
Edit history: 22-Jun-88, Version 1 by Pitman
	      16-Sep-88, Version 2 by Pitman
	      02-Oct-88, Version 3 by Pitman
	      22-Nov-88, Version 4 by Masinter

Problem Description:

  In Scheme, one writes not #'(LAMBDA ...) but just (LAMBDA ...).

  Many Common Lisp programmers have asked for this feature.
  It can be written by the user, but since it's a commonly asked
  for feature, it would make sense for it to be in the standard.

  Also, even though the definition is trivial,

    (DEFMACRO LAMBDA (BVL &REST BODY) `#'(LAMBDA ,BVL ,@BODY))

  it is difficult to offer this as an extension because then "portable
  code" tries to define it, it will get a redefinition warning because
  it will be clobbering the system's predefined definition.
  [An implementation could shadow LAMBDA, but that, too, has associated
  problems.]

Proposal (LAMBDA-FORM:NEW-MACRO):

  Add a LAMBDA macro, which has equivalent effect to:

    (DEFMACRO LAMBDA (BVL &REST BODY) `#'(LAMBDA ,BVL ,@BODY))

Rationale:

 This is an upward-compatible extension which ``codifies current
 practice'' in that it makes a commonly defined macro available
 as a standard part of the language.

Test Case:

  #1: (DEFUN ADDER (N) (LAMBDA (X) (+ X N)))
      (FUNCALL (ADDER 5) 3) => 8
  
  #2: (MAPCAR (LAMBDA (X) (+ X 3)) '(1 2 3)) => (4 5 6)

  #3: (MACROEXPAND '(LAMBDA (X) (+ X Y)))
      => (FUNCTION (LAMBDA (X) (+ X Y)))

Current Practice:

  Symbolics Genera implements NEW-MACRO.

  Symbolics Cloe does not offer a LAMBDA macro because users who defined
  their own in portable code complained that they were getting redefinition
  warnings that CLtL had led them to believe shouldn't happen. [Ironically,
  the redefinition warnings always came when they tried to define LAMBDA
  in the way it was already defined!]

  Many other Common Lisp implementations do not offer such a macro.

Cost to Implementors:

  The cost is trivial. A portable definition is shown in the
  problem description above.

Cost to Users:

  No conversion cost. This change is basically upward compatible.
  

Cost of Non-Adoption:

  There are no really major consequences of non-adoption.

Benefits:

  It's been suggested that some people write '(LAMBDA ...) rather than
  #'(LAMBDA ...) because it's less ugly, and then run into confusion
  later. If they could just write (LAMBDA ...), some that use overly
  superficial reasons for the choice of one notation over another might
  accidentally select the primitive they should probably really be using.

Aesthetics:

  In Scheme, the operator of a function invocation form has the same
  evaluation semantics as the operands.  In CL, however, the operator is
  not evaluated in the same way that the operands are.  This definition
  of LAMBDA as a macro would obscure this difference. A novice Lisp 
  programmer might have a hard time understanding why the #' is 
  optional in

  (MAP [#'](LAMBDA (POINT) (+ (POINT-X POINT) (POINT-Y POINT))) 
          POINT-LIST)
  
 but is required in
     (MAP #'SUM-OF-COORDS POINT-LIST)

  This proposal "clutters" the language because it makes the syntax
  more complex.  LAMBDA is then used not only as a "flag" for
  introducing lambda-expressions, but also is a macro which generates
  functions. There is at least one precedent for having two
  operations that do the identical thing -- NOT and NULL. Both have
  been retained because they express different intents. In this case,
  the intent of #'xxx might be to ``access'' a function by name (the
  name of an anoymous function being its lambda expression), and the
  intent of (LAMBDA ...) is to ``create'' a function. This distinction
  is subtle but may be expressionally interesting to some programmers
  in some situations.

  Notationally, some people believe strongly that (LAMBDA ...) looks
  a lot better than #'(LAMBDA ...). Certainly it takes up fewer
  characters, and (LAMBDA ...) is a notable offender in code needing
  to be split onto multiple lines, so every little bit probably helps.

Discussion:

  Numerous people have suggested this from time to time in the past,
  but it's often been amidst a bunch of other more controversial issues.
  Pitman wrote up this proposal and supports LAMBDA-FORM:NEW-MACRO.

  Technically, CLtL does already permit implementations to predefine a
  LAMBDA macro, but most argue that this leeway was accidental. CLtL
  says that "all" functions, etc in CLtL must be in the LISP package,
  but it does not say "all and only". This oversight leaves enough room
  for implementors to add all manner of extra junk in the LISP package.
  A separate cleanup item (LISP-SYMBOL-REDEFINITION) addresses
 this issue.

  An earlier revision of this proposal considered the alternative of
  making this a new special form. Many people prefered that alternative.
  However, there were also strong objections to requiring a new special form;
  since the FUNCTION special form is still necessary (for #'symbol), 
  it was deemed better  to have LAMBDA a macro which is defined
  in terms of FUNCTION than to have both LAMBDA and FUNCTION
  as special forms.