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

Issue: FLET-IMPLICIT-BLOCK (Version 5)

Status:       Ready for release? [Use ballot]

Reference:    CLtL p. 113, 67
Edit history: Revision 2 by cleanup committee 15-Mar-87 15:13:33
              Revision 3 by Masinter (reformatting) 7-Apr-87 17:49:12 
              Revision 4 by SEF 11-Apr-87
              Revision 5 by SEF 11-Apr-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))))


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.

Category: Ommission. 

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.


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.

There are two coherent alternatives to the proposal above:

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 is to eliminate the implicit block from Defun
rather than adding such blocks to other forms.  There is 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.

On the other hand, 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.  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, but it would still
require more more work on existing user code than the proposal made

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 (perhaps even required) 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.