Version française
Home     About     Download     Resources     Contact us    
Browse thread
Re: Redefinition doesn't work
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Pierre Weis <Pierre.Weis@i...>
Subject: Re: Redefinition doesn't work
Mike Friede wrote:

> Pierre> Scheme has lexical scoping <EM>locally</EM>. It has dynamic binding
> Pierre> globally,
> 
> No.

I'm very surprised, since I find in the R5RS, a clear distinction
between top level definitions that are said to be equivalent to
assigments (i.e. top level definitions are treated dynamically):

``Top level definitions

  At the top level of a program, a definition 
  (define <variable> <expression>)

  has essentially the same effect as the assignment expression 
  (set! <variable> <expression>)

  if <variable> is bound. If <variable> is not bound, however, then the
  definition will bind <variable> to a new location before performing
  the assignment, whereas it would be an error to perform a `set!' on
  an unbound variable.''

In contrast, local definitions that are not treated as an assigment,
but as conventional static bindings:

``Internal definitions

  Definitions may occur at the beginning of a <body> (that is, the body
  of a lambda, let, let*, letrec, let-syntax, or letrec-syntax
  expression or that of a definition of an appropriate form). Such
  definitions are known as internal definitions as opposed to the top
  level definitions described above. The variable defined by an internal
  definition is local to the <body>. That is, <variable> is bound rather
  than assigned, and the region of the binding is the entire <body>.''

In my mind these two definitons can be summerized as this crude
statement: ``Scheme has lexical scoping <EM>locally</EM>. It has
dynamic binding globally''.

> Pierre> just to address this redefinition problem (as far as I can
> Pierre> imagine a clever justification to this extremely strange behaviour). I
[...]
> 
> What you're describing is not a binding issue, but an assignment
> issue.  (Look in R5RS, 5.2.1 for an explanation.)  Moreover, what
> you're describing is (at least not in spirit) not conformant with
> R5RS.

As quoted above, the R5RS essentially says : Top level definitions are
assignments. The dynamic behaviour of Scheme global definitions is
just a consequence of this design choice. So, you are right, it is an
assignment issue: once you decided that global definitions are
assignments, then you automatically get dynamic top level definitions.

May be, what I call ``dynamic global binding'', is what you call an
assignment issue ? Or is it the same old semantics discussion with
schemers that pretended that Scheme global binding was indeed static
since a global identifier was always bound to the same memory location
(obtained once and for all at the first definition of the global),
even if the contents of this memory location can be changed
dynamically and dereferencement was transparent in Scheme ?

>  Section 6 has this:
> 
>   [Global binding alterations] do not modify the behavior of Scheme's
>   built-in procedures.

Good! So for built-in procedures we also get static binding at toplevel!

However, this is clearly a hack for built-in procedures! Useful, but
it is difficult to understand why I cannot benefit from this feature
for my own programs.

Note also the direct consequences of this cautious statement: now you
have a lot of identifiers that you cannot use any more in your
programs, since, if you dedefine these names, you would probably
``modify the behavior of Scheme's built-in procedures''. Also, if the
Scheme implementors add a new built-in procedure then your programs
have to be changed if you ever used the new name !

> Pierre> That's an example of a user that does not want the functions to be
> Pierre> redefined everywhere, since he cannot understand the consequences of
> Pierre> the redefinition since he does not even know where the rebound
> Pierre> function was used!
> 
> Sounds like an implementation bug to me.
> 
> -- 
> Cheers =8-} Mike
> Friede, Völkerverständigung und überhaupt blabla

May be it is a bug of the Scheme I used, or may be your Section 6 is
new with respect to the Scheme I used (the report on Scheme was known
as R3 at the time).

However, this behaviour was a consequence of the choice of the
semantics of global definitions. In 2000, this definition is still
valid, as written in the R5RS. Hence, you will have the problem of
global dynamic binding for any big program for which global
definitions cannot be protected against ``Global binding
alterations''.

In Caml, we do not treat global definitions as assigments. Hence we
have not to add a Section 6 special case in the manual to prevent
users from breaking the compiler. Hence you can redefine any built-in
you want, since you can never ``alterate'' the bindings. Hence, you
cannot modify the semantics of already defined functions (this is also
true for basic operators such as +, *, ...), and this property is
universal, either locally or globally. This a strong property (and a
good one in my mind, since it allows the programmer to be sure that
nobody can alterate the code that will be executed at run time). A
#relet feature would geopardize this invaluable property.

Pierre Weis

INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://cristal.inria.fr/~weis/