[LISPWORKS][Common Lisp HyperSpec (TM)] [Previous][Up][Next]


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.


[Starting Points][Contents][Index][Symbols][Glossary][Issues]
Copyright 1996-2005, LispWorks Ltd. All rights reserved.