[Replying mainly for the sake of other "CL newbies" such as myself...]
Erik Naggum <erik@naggum.net> wrote:
+---------------
| * rpw3@rigden.engr.sgi.com (Rob Warnock)
| | Hunh? What's FLET all about then?
| | (flet ((car (n) (+ 1 n)))
| | (values #'car (car 17)))
|
| Please note that you were not allowed to do what you just did if you
| also want to have a conforming ANSI Common Lisp program.
+---------------
I initially didn't understand Erik's comment at *all*, since both CMUCL &
CLISP accepted the FLET with no problems, and the HyperSpec section on FLET
specifically says that "flet can locally shadow a global function name".
So I went digging a little further (well, a *lot* further, due to my
unfamiliarity with the topic), and found some pointers in the X3J13
cleanup issues (specifically, PACKAGE-CLUTTER, LISP-SYMBOL-REDEFINITION,
and LISP-SYMBOL-REDEFINITION-AGAIN:MORE-FIXES) which pointed back to
the standard proper:
11.1.2.1.2 Constraints on the COMMON-LISP Package for Conforming
Programs
Except where explicitly allowed, the consequences are undefined
if any of the following actions are performed on an external symbol
of the COMMON-LISP package:
1. Binding or altering its value (lexically or dynamically).
(Some exceptions are noted below.)
2. Defining, undefining, or binding it as a function. ...
3. Defining, undefining, or binding it as a macro or compiler macro.
[...#4-19 omitted...]
So symbols in the COMMON-LISP package are "different" from other packages,
and I stand properly corrected. Thanks for the lesson, Erik.
+---------------
| I think the proper question is "What's Scheme all about then?".
|
| With distinct function and variable namespaces, you don't need to
| create the kind of hellish environment where you never know what a
| function does that Scheme has invented for itself.
+---------------
I agree that the Scheme community has not gone into *nearly* the level of
thought/discussion/care/etc. that the above issues demonstrate about the
CL community. However, the Scheme standard (using R5RS for reference) *does*
at least promise you a (considerably weaker) guarantee on system-defined
procedures:
6 Standard procedures
...
The initial (or "top level") Scheme environment starts out with
a number of variables bound to locations containing useful values,
most of which are primitive procedures that manipulate data.
...
Built-in procedures that can easily be written in terms of
other built-in procedures are identified as "library procedures".
...
A program may use a top-level definition to bind any variable.
It may subsequently alter any such binding by an assignment
(see 4.1.6). These operations do not modify the behavior of
Scheme's built-in procedures.
That is, redefining "car" must *not* change the behavior of "map" or
"member" (say), even if they were defined using the original "car".
However, there is a "non-guarantee" as well:
Altering any top-level binding that has not been introduced by
a definition has an unspecified effect on the behavior of the
built-in procedures.
This might be thought of as another consequence of "4.1.6 Assignments",
where it says that the variable to be assigned to "must be bound either
in some region enclosing the set! expression or at top level", which
to me is a hint that the Scheme system is permitted (or indeed, required!)
to do something "magic" with standard procedures that are re-defined with
a top-level "define", and yet *not* required to guarantee the same magic
for variables that are assigned to without being top-level-(re)defined.
[I know, this is nowhere *near* CL's constraints, but I thought the
comparison might be interesting.]
-Rob
-----
Rob Warnock, 31-2-510 rpw3@sgi.com
Network Engineering http://reality.sgi.com/rpw3/
Silicon Graphics, Inc. Phone: 650-933-1673
1600 Amphitheatre Pkwy. PP-ASEL-IA
Mountain View, CA 94043