[net.lang.lisp] Abusing "define" in Scheme...

hydar@ucla-cs.ARPA (Dan Hydar) (05/16/86)

     
        Does anyone know if Scheme is defined such that ANY binding can be
   changed or is there some set of functions/identifiers that can be (or
   MUST be) prevented from being re-defined?

        For instance --- are you able to do blatantly stupid things like:

                        (define car  5)

    or are such things verbotten?  If this sort of thing isn't allowable, is
    there some list of identifiers which can't be re-defined?

                                        |Dan|

willc@tekchips.UUCP (Will Clinger) (05/19/86)

In article <13508@ucla-cs.ARPA> hydar@ucla-cs.ARPA (Dan Hydar) writes:
>
>
>	Does anyone know if Scheme is defined such that ANY binding can be
>   changed or is there some set of functions/identifiers that can be (or
>   MUST be) prevented from being re-defined?
>
Certainly any identifier that is not the keyword of a special form can
be *bound* as in (LET ((CAR 5) (CDR LOG)) (CDR CAR)); the question is
whether all variables can be *assigned*.  By my reading of the idealized
semantics of Scheme, the answer is yes.  Some implementations of Scheme,
however, prevent you from assigning a new value to variables like CAR;
though deliberate, I consider this behavior to be a (tolerable) bug
introduced in exchange for simpler open-coding of important operations.

>	For instance --- are you able to do blatantly stupid things like:
>
>			(define car  5)
>
An implementation of Scheme that lets you do this should be civil enough
not to crash when you do it.  (The system code should have been compiled
in a different environment from the one in which you are wreaking your
havoc.  I confess, however, that MacScheme isn't entirely bulletproof
in this regard.)

Compare this to the status quo in other languages, where assignments such
as (SETF (SYMBOL-FUNCTION 'CDR) #'LOG) may be permitted but ineffective,
or have effect only when #'CAR appears in an argument position, or have
effect only in code that is interpreted or code that is compiled
following the assignment.

Peace, William Clinger
       Tektronix Computer Research Laboratory
       willc%tekchips@tektronix

psi@mit-eddie.MIT.EDU (Joseph J. Mankoski) (05/21/86)

In article <13508@ucla-cs.ARPA>, hydar@ucla-cs.ARPA (Dan Hydar) writes:
> 
>      
>         Does anyone know if Scheme is defined such that ANY binding can be
>    changed or is there some set of functions/identifiers that can be (or
>    MUST be) prevented from being re-defined?	

	I do  not  know off hand of  any prohibition on redefining any
identifiers  in Scheme.   Not having a manual on  hand,  I resorted to
testing the readily accessible Scheme implementaions here at MIT.
	On both the VAX and PDP-10 versions of Scheme, I was allowed
to do the following:

	==> (define car 8)
	CAR
	
	==> car
	8

	==> (car '(foo baz bar))
	ERROR: Inapplicable procedure object ...*mumble*...

(The last should be expected, due to the fact that identifiers only
have one value in Scheme.)
	I see  nothing inherently wrong  in letting the  user redefine
whatever he wants in the Scheme environment.  This is  in keeping with
the Lisp(hacker) philosophy that one should be able to frob the system
at will, just as long as  you are willing to  do it responsibly enough
that you don't hose yourself.
	I have seen Scheme programs written  by first-time programmers
which redefined T to be some random thing.  Having learned (true) Lisp
before Scheme,  I was first  horrified when I   saw them  doing  this.
There is no problem with redefining T, however, as the actual value of
Truth is  kept elsewhere(#!true),  and  final  cond-clauses  are often
written with Else in the place of T.
	Whether or not such redefinions should be  allowed is a matter
of personal taste, though  prohibiting some redefitions  detracts from
the uniformity of  the language.  Personally,  I prefer the freedom to
redefine anything, though  I still avoid redefining  T, Lambda, and of
course, Define.

				Lisp is True Beauty,
					Joseph J. Mankoski ***PSI***
					...!mit-eddie!psi(UUCP)
					psi@ai.ai.mit.edu(ARPA)

jbs@mit-eddie.MIT.EDU (Jeff Siegal) (05/21/86)

In article <2048@mit-eddie.MIT.EDU> psi@mit-eddie.MIT.EDU (Joseph J. Mankoski) writes:
>In article <13508@ucla-cs.ARPA>, hydar@ucla-cs.ARPA (Dan Hydar) writes:
>> 
>>      
>>         Does anyone know if Scheme is defined such that ANY binding can be
>>    changed or is there some set of functions/identifiers that can be (or
>>    MUST be) prevented from being re-defined?	
>

>[...].  Personally,  I prefer the freedom to
>redefine anything, though  I still avoid redefining  T, Lambda, and of
>course, Define.

Actually, redefining lambda or define would not change the meaning of
expressions like (define a b) or (lambda (x) (* x 2)).  These are are
"special forms" and (if I remember my 6.001 correctly) the evaulator
does not look for their definitions in the current context before
actually doing the work involved (binding or procedure creation).  So
actually the list of indentifiers which can not be redefined is the
list of special forms.

Note however, that you can do the following:

--> (DEFINE LAMBDA 1)
LAMBDA

--> LAMBDA
1

--> ((LAMBDA (X) (+ X 1)) 1)
2

LAMBDA has been defined as a symbol bound to 1, but this does not
affect the normal usage of LAMBDA, which still works as expected(?).

Jeff Siegal

willc@tekchips.UUCP (Will Clinger) (05/23/86)

In article <2049@mit-eddie.MIT.EDU> jbs@mit-eddie.UUCP (Jeff Siegal) writes:
>Actually, redefining lambda or define would not change the meaning of
>expressions like (define a b) or (lambda (x) (* x 2)).  These are are
>"special forms" and (if I remember my 6.001 correctly) the evaulator
>does not look for their definitions in the current context before
>actually doing the work involved (binding or procedure creation).  So
>actually the list of indentifiers which can not be redefined is the
>list of special forms.
>
>Note however, that you can do the following:
>
>--> (DEFINE LAMBDA 1)
>LAMBDA
>
>--> LAMBDA
>1
>
>--> ((LAMBDA (X) (+ X 1)) 1)
>2
>
>LAMBDA has been defined as a symbol bound to 1, but this does not
>affect the normal usage of LAMBDA, which still works as expected(?).
>
>Jeff Siegal

Whether you can do this or not is implementation-dependent.  The
Revised Revised Report on Scheme (MIT AI Memo 848) says "Some
implementations [reserve] the identifiers that serve as keywords
of special forms, while other implementations allow the keyword
meaning of an identifier to be shadowed by lexical bindings."
The code that Jeff wrote illustrates yet a third implementation,
in which the shadowing is context-dependent.

To write portable Scheme code, you have to assume that the keywords
of special forms are reserved.  That's one reason people are so
fanatic about having the number of special forms be as small as
possible.

I don't know how Common Lisp stands on this issue.  To judge by the
program-analyzing algorithm on page 57 of Steele's "Common Lisp: the
Language", the names of special forms are reserved when they appear
in the car of a form, but I don't know what happens when they appear
in other contexts.  Common Lisp distinguishes between special forms
and macros, however, and it is clear that macro names can be shadowed
because they live in the "function" environment, which is lexical
except for some special treatment of the global function environment.
On the other hand, implementations of Common Lisp are explicitly
allowed to implement certain macros as special forms, and I don't
know how their names can be simultaneously reserved (because they
are special forms) and shadowable (because they are macros).  I'd
appreciate any pointers to authoritative explanations of these two
matters.

Peace, William Clinger
Tektronix Computer Research Laboratory
willc%tekchips@tektronix

smc@mit-vax.UUCP (Stewart M. Clamen) (05/26/86)

In article <13508@ucla-cs.ARPA> hydar@ucla-cs.ARPA (Dan Hydar) writes:
>
>     
>        Does anyone know if Scheme is defined such that ANY binding can be
>   changed or is there some set of functions/identifiers that can be (or
>   MUST be) prevented from being re-defined?
>
>        For instance --- are you able to do blatantly stupid things like:
>
>                        (define car  5)


As a matter of fact, redefinition of the PAIR abstraction (mainly CAR,
CDR, and CONS) is the subject of a number of examples in Abelson and
Sussman's _Structure_and_Interpretation_of_Computer_Programs_.
Exercises 2.3 and 2.4 ask the student to define a new implementation
for the "primitives" which preserve their functionality.

-- 
----------------------------------------------------

ARPA: SMC%MIT-OZ@MIT-MC.ARPA
USENET: ...!decvax!genrad!mit-eddie!smc%mit-oz

barmar@mit-eddie.MIT.EDU (Barry Margolin) (05/28/86)

In article <328@tekchips.UUCP> willc@tekchips.UUCP (Will Clinger) writes:
>I don't know how Common Lisp stands on this issue.  To judge by the
>program-analyzing algorithm on page 57 of Steele's "Common Lisp: the
>Language", the names of special forms are reserved when they appear
>in the car of a form, but I don't know what happens when they appear
>in other contexts.

I think the Common Lisp definition describes the reserved status of
these symbols by saying that they cannot be given new function
definitions.  The user is perfectly free to change the value cell,
package cell, and property list.

>  Common Lisp distinguishes between special forms
>and macros, however, and it is clear that macro names can be shadowed
>because they live in the "function" environment, which is lexical
>except for some special treatment of the global function environment.
>On the other hand, implementations of Common Lisp are explicitly
>allowed to implement certain macros as special forms, and I don't
>know how their names can be simultaneously reserved (because they
>are special forms) and shadowable (because they are macros).  I'd
>appreciate any pointers to authoritative explanations of these two
>matters.

No problem, the compiler/interpreter merely has to check whether the
user has redefined the function binding before using the built-in
definition of the macro.  Only the special forms listed in the language
definition are required to be reserved.  When it says that
implementations may implement macros as special forms, it is actually
saying that they are allowed to skip the explicit macro-expansion step,
i.e. interpret the macro in whatever special way they interpret special
forms.
-- 
    Barry Margolin
    ARPA: barmar@MIT-Multics
    UUCP: ..!genrad!mit-eddie!barmar