CLHS: Issue FLET-IMPLICIT-BLOCK Writeup

#

## Issue FLET-IMPLICIT-BLOCK Writeup

    Issue:        FLET-IMPLICIT-BLOCK
    Reference:    CLtL p. 113, 67
    Category:     OMISSION
    Edit history: Version 2 by cleanup committee 15-Mar-87 15:13:33
                  Version 3 by Masinter (reformatting) 7-Apr-87 17:49:12
                  Versions 4,5 by Fahlman 11-Apr-87
                  Version 6 by Masinter  5-Jun-87

    Problem Description:

    Do FLET, LABELS, DEFMACRO, MACROLET, DEFSETF, DEFINE-SETF-METHOD, and
    DEFTYPE have an implicit block around their bodies like the body of a
    DEFUN?  CLtL is silent on this point.  Many users and some implementors
    assume that such blocks should be established, since they view these
    forms as analogous with DEFUN.

    Test case:

    (defun test ()
      (flet ((test (x) (if x (return-from test 4) 3)))
    	(list (test nil) (test t))))

    (test)

    will return (3 4) if FLET-IMPLICIT-BLOCK:YES is adopted, and would
    return 4 in an implementation that did not add an implicit block around
    FLET.

    Proposal: FLET-IMPLICIT-BLOCK:YES

    Each function created by FLET and LABELS and each macro created by
    DEFMACRO and MACROLET has an implicit block around the body.  The name
    of this block is that same as the (lexical) name of the function or
    macro.  Similarly, the body code in DEFSETF, DEFINE-SETF-METHOD, and
    DEFTYPE is surrounded by a block with the same name as the accessor or
    type.

    Current Practice:

    Current practice is mixed.  Several implementations do not add the
    implicit block, others do, some add some of these blocks and not others.

    Cost of adopting this change:

    Some implementations will have to be modified.  This should be a
    relatively easy modification.

    Cost of not adopting the change:

    If the issue is not clarified one way or another, continuing confusion
    will result in portability problems.  Clarifying the issue in any other
    way would also require modifications in some implementations.

    Cost of converting existing code:

    It is possible that some user code would break because it does a return
    from within a code body to an outer block that has the same as the
    newly-required block.  Such problems will be rare, and the code in
    question would not run on all current Common Lisp systems because of the
    diverse interpretations currently in effect.  It would be possible to
    detect all such instances automatically, though it seems unlikely that
    anyone will need to use this technique.

    Discussion:

    The goal is first to clean up an ambiguous situation and, second, to do
    this in a way that provides consistent behavior between local and global
    definitions.  The proposed change would allow a simple rule of thumb:
    any named entity that takes a code body establishes an implicit block
    with the obvious name.

    Two alternatives to the proposal were considered and rejected:

    The first would be to keep the implicit block in DEFUN, and to clearly
    state that the other forms do not create implicit blocks.  This violates
    the goal of consistency between lexical and global definitions, and it
    seems to conflict with users' expectations.

    The second alternative was to eliminate the implicit block from DEFUN
    rather than adding such blocks to other forms.  There was some feeling
    that specifying the implicit block in DEFUN was a poor design decision
    in the first place, since it hides a reference to the name of a function
    within the code of the function itself.  If a user decides to rename
    some function, he must be careful to rename any return-from forms within
    the body of the function as well.

    However, eliminating the implicit block in DEFUN would be a significant
    incompatible change.  Some users find this implicit block to be a great
    convenience for popping out of convoluted code, and some existing code
    makes heavy use of this feature.  While such code could be repaired
    automatically by searching for situations in which the user returns from
    a function by name and by adding an appropriate explicit block to any
    function containing such a forms, it would still require more more work
    on existing user code than this proposal made above.

    There was considerable discussion in the cleanup committee about whether
    these implicit blocks would interfere with tail-recursion optimization,
    which we hope will become more common in future Common Lisp
    implementations.  The outcome of these discussions was general agreement
    that a compiler could easily eliminate the implicit block in any case
    where it is not actually used, and that the impact on tail-recursion
    optimization in compiled code is therefore minimal.

Copyright 1996-2005, LispWorks Ltd. All rights reserved.