Dr. Scheme "local"? 
Author Message
 Dr. Scheme "local"?

I had been learning scheme using SICP and umb-scheme, and more recently
have been studying How To Design Programs at
http://www.*-*-*.com/

DrSchemes use of local is boggling me.  How does it relate to "let" and
"lambda".

e.g. (from HTDP)
;; add : number -> (number -> number)
;; to create a function that adds x to its input
(define (add-0 x)
  (local ((define (x-adder y) (+ x y)))
    x-adder))

I would before had thought in terms of
(define (add-1 x)
  (lambda (y)(+ x y)))

or
(define (add-2 x)
  (define (x-adder y)(+ x y))
  x-adder)

or even
(define (add-3 x)
  (let ((x-adder (lambda(y)(+ x y))))
    x-adder))

So, what is local for?  How is add-2 any different from add-0?

Thanks,
John



Sat, 30 Nov 2002 03:00:00 GMT  
 Dr. Scheme "local"?

Quote:

> I had been learning scheme using SICP and umb-scheme, and more recently
> have been studying How To Design Programs at
> http://www.cs.rice.edu/CS/PLT/Teaching/Lectures/Released/Book/.

> DrSchemes use of local is boggling me.  How does it relate to "let" and
> "lambda".

Don't think of local in terms of let and lambda.  Think of it in terms
of define.  Suppose you have a bunch of definitions:

  (define v1 ...)
  (define v2 ...)
  ...
  (define vn ...)

(whether or not they're bound to functions isn't relevant, ie, some
could be of the form (define (vk ...) ...); they can also be
structures created using define-struct).  Now you want to localize
their scope.  None of Scheme's existing constructs -- let, letrec,
internal defines -- preserves the semantics of the original.  local
does.  You can simply write

(local (
        (define v1 ...)
        (define v2 ...)
        ...
        (define vn ...)
                       )
  <expression> ...)

and its value would be the same as if you had written <expression>
after all the definitions sans the local.

Quote:
> ;; add : number -> (number -> number)
> ;; to create a function that adds x to its input
> (define (add-0 x)
>   (local ((define (x-adder y) (+ x y)))
>     x-adder))

> I would before had thought in terms of
> (define (add-1 x)
>   (lambda (y)(+ x y)))

> or
> (define (add-2 x)
>   (define (x-adder y)(+ x y))
>   x-adder)

> or even
> (define (add-3 x)
>   (let ((x-adder (lambda(y)(+ x y))))
>     x-adder))

> So, what is local for?  How is add-2 any different from add-0?

Those are all the same.  But those are the wrong examples to be
looking at.  The problem is

- lambda only captures the case where you have a single function that
  you are returning immediately,

- let does not capture recursion, and

- letrec and internal definitions turn sequential definitions into
  parallel ones, thereby altering the result.

(If you understand the preceding bullets, then you will see why local
is different and useful.  If you don't understand the preceding
bullets, then you don't understand the semantics of Scheme's many
binding constructs adequately, and you're just the sort of person for
whom local is most useful in that it minimizes surprises.)

'shriram



Sat, 30 Nov 2002 03:00:00 GMT  
 Dr. Scheme "local"?


Quote:

> > I had been learning scheme using SICP and umb-scheme, and more
recently
> > have been studying How To Design Programs at
> > http://www.cs.rice.edu/CS/PLT/Teaching/Lectures/Released/Book/.

> > DrSchemes use of local is boggling me.  How does it relate to "let"
and
> > "lambda".

> Don't think of local in terms of let and lambda.  Think of it in terms
> of define.  Suppose you have a bunch of definitions:

>   (define v1 ...)
>   (define v2 ...)
>   ...
>   (define vn ...)

> (whether or not they're bound to functions isn't relevant, ie, some
> could be of the form (define (vk ...) ...); they can also be
> structures created using define-struct).  Now you want to localize
> their scope.  None of Scheme's existing constructs -- let, letrec,
> internal defines -- preserves the semantics of the original.  local
> does.  You can simply write

> (local (
>    (define v1 ...)
>    (define v2 ...)
>    ...
>    (define vn ...)
>                        )
>   <expression> ...)

> and its value would be the same as if you had written <expression>
> after all the definitions sans the local.

Ok, what about BEGIN? Does it have the proper semantics?

(begin (
   (define a 7)
   (define b 9)
  (+ a b))

Oops, I just answered my own question-- this defines a and b in global
scope!  Surprise to me.

But then

(local (
   (define c 12)
   (define d 13)
                )
  (+ c d))

Didn't work for me, I got:
"define-values: illegal use (not at top-level) in: (#%define-values (c)
12)"

- Show quoted text -

Quote:

> > ;; add : number -> (number -> number)
> > ;; to create a function that adds x to its input
> > (define (add-0 x)
> >   (local ((define (x-adder y) (+ x y)))
> >     x-adder))

> > I would before had thought in terms of
> > (define (add-1 x)
> >   (lambda (y)(+ x y)))

> > or
> > (define (add-2 x)
> >   (define (x-adder y)(+ x y))
> >   x-adder)

> > or even
> > (define (add-3 x)
> >   (let ((x-adder (lambda(y)(+ x y))))
> >     x-adder))

> > So, what is local for?  How is add-2 any different from add-0?

> Those are all the same.  But those are the wrong examples to be
> looking at.  The problem is

> - lambda only captures the case where you have a single function that
>   you are returning immediately,

> - let does not capture recursion, and

> - letrec and internal definitions turn sequential definitions into
>   parallel ones, thereby altering the result.

> (If you understand the preceding bullets, then you will see why local
> is different and useful.  If you don't understand the preceding
> bullets, then you don't understand the semantics of Scheme's many
> binding constructs adequately, and you're just the sort of person for
> whom local is most useful in that it minimizes surprises.)

Yep, I guess you're mostly right about that.  But I'm wondering why
AFAICT R5RS, MIT-Scheme, UMB-scheme, nor Scheme-48 seem to recognize
LOCAL?  Is it because it's a dr-scheme enhancement to simplify?

Also, is there any particular discussion/chapter/etc you could point me
to to improve my "understanding of the semantics of Scheme's many
binding constructs"?  Or is this a topic that only comes through
experience of many k of code writing.

Thanks for your help,
John

Sent via Deja.com http://www.deja.com/
Before you buy.



Sat, 30 Nov 2002 03:00:00 GMT  
 Dr. Scheme "local"?

Quote:




> > > DrSchemes use of local is boggling me.  How does it relate to
> > > "let" and "lambda".

> > Don't think of local in terms of let and lambda.  Think of it in terms
> > of define.  

Uh-oh.

Quote:
> > Suppose you have a bunch of definitions:
> >   ...
> > (whether or not they're bound to functions isn't relevant, ie, some
> > could be of the form (define (vk ...) ...); they can also be
> > structures created using define-struct).  Now you want to localize
> > their scope.  None of Scheme's existing constructs -- let, letrec,
> > internal defines -- preserves the semantics of the original.  

Yes letrec...er no, you're right. I've actually found this to be
somewhat annoying at times. You can't use the letrec *values*[1] in
the letrec definitions. grrr....

I tend to think of this as a (standardized) bug in letrec, although I
am fairly sure that one of the mighty Matthiases would disagree.

Quote:
> Ok, what about BEGIN? Does it have the proper semantics?
> Oops, I just answered my own question-- this defines a and b in global
> scope!  Surprise to me.

I think that there's a hack possible here, though. How about something
like -
                      or
((lambda ()                (let ((junk #f))
   (define a 12)               (define a 12)
   (define b 13)               (define b 13)
   (+ a b)))                   (+ a b))

where you essentially use the implicit begin provided by the explicit
introduction of the new scope. You could even hack up a define-syntax
for local ;)

Quote:
> > - lambda
> > - let
> > - letrec

> > (If you understand the preceding bullets, then you will see why local
> > is different and useful.  If you don't understand the preceding
> > bullets, then you don't understand the semantics of Scheme's many
> > binding constructs adequately, and you're just the sort of person for
> > whom local is most useful in that it minimizes surprises.)

Or, possibly, you might learn to separate your specifications of
recursion and values, which define and the top-level tricks of R5RS
obscure somewhat (although in an arguably useful way). ISTM that if
you dropped define and the implicit begin at toplevel (you might need
to twiddle the defn of load, too), that a pretty complete categorical
module system just falls out. It's somewhat ugly syntactically, but...

Quote:
> AFAICT R5RS, MIT-Scheme, UMB-scheme, nor Scheme-48 seem to recognize
> LOCAL?  Is it because it's a dr-scheme enhancement to simplify?

Got it in one.

Quote:
> Also, is there any particular discussion/chapter/etc you could point me
> to to improve my "understanding of the semantics of Scheme's many
> binding constructs"?  Or is this a topic that only comes through
> experience of many k of code writing.

R5RS. The section on 'Derived expression types' under 'Binding
constructs'. I've only got the info version handy at the moment, so I
can't give you the paper section numbers, sorry.

david rush
--
[1] R5RS - "it must be possible to evaluate each <init> without
           assigning or referring to the value of any <variable>"

Quote:
> scope!  Surprise to me.

I think that there's a hack possible here, though. How about something
like -
                      or
((lambda ()                (let ((junk #f))
   (define a 12)               (define a 12)
   (define b 13)               (define b 13)
   (+ a b)))                   (+ a b))

where you essentially use the implicit begin provided by the explicit
introduction of the new scope. You could even hack up a define-syntax
for local ;)

Quote:
> > - lambda
> > - let
> > - letrec

> > (If you understand the preceding bullets, then you will see why local
> > is different and useful.  If you don't understand the preceding
> > bullets, then you don't understand the semantics of Scheme's many
> > binding constructs adequately, and you're just the sort of person for
> > whom local is most useful in that it minimizes surprises.)

Or, possibly, you might learn to separate your specifications of
recursion and values, which define and the top-level tricks of R5RS
obscure somewhat (although in an arguably useful way). ISTM that if
you dropped define and the implicit begin at toplevel (you might need
to twiddle the defn of load, too), that a pretty complete categorical
module system just falls out. It's somewhat ugly syntactically, but...

Quote:
> AFAICT R5RS, MIT-Scheme, UMB-scheme, nor Scheme-48 seem to recognize
> LOCAL?  Is it because it's a dr-scheme enhancement to simplify?

Got it in one.

Quote:
> Also, is there any particular discussion/chapter/etc you could point me
> to to improve my "understanding of the semantics of Scheme's many
> binding constructs"?  Or is this a topic that only comes through
> experience of many k of code writing.

R5RS. The section on 'Derived expression types' under 'Binding
constructs'. I've only got the info version handy at the moment, so I
can't give you the paper section numbers, sorry.

david rush
--
[1] R5RS - "it must be possible to evaluate each <init> without
           assigning or referring to the value of any <variable>"

Quote:
> binding constructs"?  Or is this a topic that only comes through
> experience of many k of code writing.

R5RS. The section on 'Derived expression types' under 'Binding
constructs'. I've only got the info version handy at the moment, so I
can't give you the paper section numbers, sorry.

david rush
--
[1] R5RS - "it must be possible to evaluate each <init> without
           assigning or referring to the value of any <variable>"

Posted via cut-and-paste through an xterm running telnet, since my
employer's NNTP server has disappeared from our subnet. grr....



Sat, 30 Nov 2002 03:00:00 GMT  
 Dr. Scheme "local"?

Quote:

> I had been learning scheme using SICP and umb-scheme, and more recently
> have been studying How To Design Programs at
> http://www.cs.rice.edu/CS/PLT/Teaching/Lectures/Released/Book/.

> DrSchemes use of local is boggling me.  How does it relate to "let" and
> "lambda".

Shriram has answered the question pretty much.

We decided that we wanted a small number of constructs in the
Scheme for our teaching world and that we wanted as much
semantic regularity as possible, including error semantics.

So, if you think of scope as just a way of turning a sequence of
definitions into something that has a textual beginning and end
(okay, that's very rough, but let it go), then you want a construct
that provides a beginning and an end to what otherwise looks
like a sequence of definitions. And we want the same semantics
locally and at top-level.   Following Scheme tradition, we
want this to be an expression, which means we must also add
a body to the construct. So that leaves us with

 (XXXX ( ..... a sequence of definitions .....)
    an-expression)

That's all, and you don't need anything else. Regular syntax, regular
semantics, no need for let, letrec, let*, let+, let-, let& or whatever.

Make life in a beginner course much much simpler.

-- Matthias



Sat, 30 Nov 2002 03:00:00 GMT  
 Dr. Scheme "local"?
P.S.   There is an intermezzo in the book that explains  LOCAL, its syntax, its
semantics,
its pragmatics:

  http://www.cs.rice.edu/CS/PLT/Teaching/Lectures/Released/Book/node98.htm

Later on, we explain LAMBDA at first  as an abbreviation of  LOCAL:

  (lambda <parameters> <expression>)
  ==
  (local ((define  variable:hygienic <parameters) <expression>))
      variable:hygienic)

No mystery here.



Sat, 30 Nov 2002 03:00:00 GMT  
 Dr. Scheme "local"?

Quote:

> > Ok, what about BEGIN? Does it have the proper semantics?
> > Oops, I just answered my own question-- this defines a and b in global
> > scope!  Surprise to me.

> I think that there's a hack possible here, though. How about something
> like -
>                       or
> ((lambda ()                (let ((junk #f))
>    (define a 12)               (define a 12)
>    (define b 13)               (define b 13)
>    (+ a b)))                   (+ a b))

> where you essentially use the implicit begin provided by the explicit
> introduction of the new scope. You could even hack up a define-syntax
> for local ;)

I already said in my post that implicit begin is not the same as
local.  Please read it more carefully and think about it.  Indeed,
since implicit begin is equivalent to letrec, and you yourself have
agreed that letrec is not the same as local, it follows that ...

'shriram

--

            Flectere si nequeo superos, Acheronta movebo.
                                                    --Virgil, /Aeneid/



Sat, 30 Nov 2002 03:00:00 GMT  
 Dr. Scheme "local"?

Quote:

> Ok, what about BEGIN? Does it have the proper semantics?

> (begin (
>    (define a 7)
>    (define b 9)
>   (+ a b))

> Oops, I just answered my own question-- this defines a and b in global
> scope!  Surprise to me.

Right.  But even an implicit internal begin -- as in

  (lambda ()
    (define a 7)
    (define b 9)
    ...)

does not preserve the top-level semantics.

Quote:
> But then

> (local (
>    (define c 12)
>    (define d 13)
>                 )
>   (+ c d))

> Didn't work for me, I got:
> "define-values: illegal use (not at top-level) in: (#%define-values (c)
> 12)"

Are you sure you're in the right language configuration?  In MzScheme,
you have to load

  (require-library "macro.ss")

And if you're in DrScheme or DrScheme Jr, which has LOCAL built in,
you need to be in the Intermediate or Advanced Student language
levels:

Welcome to DrScheme Jr version 102/17, Copyright (c) 1995-2000 PLT
Language: Intermediate Student

Quote:
> (local ((define c 12)

          (define d 13))
    (+ c d))
25

Quote:
> > (If you understand the preceding bullets, then you will see why local
> > is different and useful.  If you don't understand the preceding
> > bullets, then you don't understand the semantics of Scheme's many
> > binding constructs adequately, and you're just the sort of person for
> > whom local is most useful in that it minimizes surprises.)

> Yep, I guess you're mostly right about that.

Only "mostly"? (-:

                                                But I'm wondering why

Quote:
> AFAICT R5RS, MIT-Scheme, UMB-scheme, nor Scheme-48 seem to recognize
> LOCAL?  Is it because it's a dr-scheme enhancement to simplify?

It's a PLT Scheme enhancement.  So you can use it in our
implementations: DrScheme, DrScheme Jr, MzScheme.  You can't trivially
implement it in these other systems (to the best of my knowledge),
certainly not with a simple macro as someone else suggested.

Quote:
> Also, is there any particular discussion/chapter/etc you could point me
> to to improve my "understanding of the semantics of Scheme's many
> binding constructs"?  Or is this a topic that only comes through
> experience of many k of code writing.

As Samuel Johnson wrote, "one can supply arguments, but not
understanding" -- that's all manuals do.  To really understand why
such constructs are in the language, why they are necessary, and even
what their deeper semantic implications are, needs experience.  You
can look at the RnRS Scheme reports (see www.schemers.org), but they
are too terse to be of much help here.  You may get further by reading
Friedman, Wand and Haynes's "Essentials of Programming Languages", or
Matthias's and my notes (available for free on-line):

  http://www.cs.rice.edu/~shriram/311/
  Principles of Programming Languages

'shriram



Mon, 02 Dec 2002 03:00:00 GMT  
 Dr. Scheme "local"?

Quote:


> > Ok, what about BEGIN? Does it have the proper semantics?

> > (begin (
> >    (define a 7)
> >    (define b 9)
> >   (+ a b))

> > Oops, I just answered my own question-- this defines a and b in global
> > scope!  Surprise to me.

> Right.  But even an implicit internal begin -- as in

>   (lambda ()
>     (define a 7)
>     (define b 9)
>     ...)

> does not preserve the top-level semantics.

Ok, can I confirm my understanding by reading this back to you in my own
words?  So, you're saying that my example using (begin (define ...)
"preserves top-level semantics"?  Meaning that the defines occur the
top-level scope?  Then, in your example using (lambda ()(define ...)
they occur within the scope established by the define.  Ok.  And this is
the case with the PLT (local ...) construct as well, so (at least in
this respect) the (local ...) is like a ((lambda () ...))

- Show quoted text -

Quote:
> > But then

> > (local (
> >    (define c 12)
> >    (define d 13)
> >                 )
> >   (+ c d))

> > Didn't work for me, I got:
> > "define-values: illegal use (not at top-level) in: (#%define-values (c)
> > 12)"

> Are you sure you're in the right language configuration?  In MzScheme,
> you have to load

>   (require-library "macro.ss")

Yes, I found that after a wrote, sorry.

- Show quoted text -

Quote:

> And if you're in DrScheme or DrScheme Jr, which has LOCAL built in,
> you need to be in the Intermediate or Advanced Student language
> levels:

> Welcome to DrScheme Jr version 102/17, Copyright (c) 1995-2000 PLT
> Language: Intermediate Student
> > (local ((define c 12)
>           (define d 13))
>     (+ c d))
> 25

> > > (If you understand the preceding bullets, then you will see why local
> > > is different and useful.  If you don't understand the preceding
> > > bullets, then you don't understand the semantics of Scheme's many
> > > binding constructs adequately, and you're just the sort of person for
> > > whom local is most useful in that it minimizes surprises.)

> > Yep, I guess you're mostly right about that.

> Only "mostly"? (-:

Right.  For any value (0-100%) of "mostly".  Fine, rub it in.  Is that a
strange frowning emoticon, or an upside-down smiling emoticon?

- Show quoted text -

Quote:
>                                                 But I'm wondering why
> > AFAICT R5RS, MIT-Scheme, UMB-scheme, nor Scheme-48 seem to recognize
> > LOCAL?  Is it because it's a dr-scheme enhancement to simplify?

> It's a PLT Scheme enhancement.  So you can use it in our
> implementations: DrScheme, DrScheme Jr, MzScheme.  You can't trivially
> implement it in these other systems (to the best of my knowledge),
> certainly not with a simple macro as someone else suggested.

> > Also, is there any particular discussion/chapter/etc you could point me
> > to to improve my "understanding of the semantics of Scheme's many
> > binding constructs"?  Or is this a topic that only comes through
> > experience of many k of code writing.

> As Samuel Johnson wrote, "one can supply arguments, but not
> understanding" -- that's all manuals do.  To really understand why
> such constructs are in the language, why they are necessary, and even
> what their deeper semantic implications are, needs experience.  You
> can look at the RnRS Scheme reports (see www.schemers.org), but they
> are too terse to be of much help here.  You may get further by reading
> Friedman, Wand and Haynes's "Essentials of Programming Languages", or
> Matthias's and my notes (available for free on-line):

>   http://www.cs.rice.edu/~shriram/311/
>   Principles of Programming Languages

> 'shriram

Ok, I'll take a look!

Thanks for you patient and thorough explanations.

Cheers,
John



Wed, 04 Dec 2002 03:00:00 GMT  
 Dr. Scheme "local"?

Quote:

> Ok, can I confirm my understanding by reading this back to you in my own
> words?  So, you're saying that my example using (begin (define ...)
> "preserves top-level semantics"?  

Sorry to be perverse, but yes and no.  In this context, I am
implicitly using the phrase "preserves top-level semantics" to mean
both of these two things:

- does not change the meaning of the program                       [1]

AND

- encapsulates definitions in a more limited scope                 [2]

The (begin (define ...) ...) version certainly meets [1] (trivially,
since it splices the code into the top-level), but it doesn't
accomplish the original purpose, which is to encapsulate the
definitions in a restrictive scope [2], as you yourself observed in an
earlier post.

Quote:
>                                Meaning that the defines occur the
> top-level scope?  Then, in your example using (lambda ()(define ...)
> they occur within the scope established by the define.  

You mean "scope established by the lambda".  Actually the situation is
a little more tricky, since they translate into letrec's, but yes,
you're on the right track.

Quote:
>                                                      Ok.  And this is
> the case with the PLT (local ...) construct as well, so (at least in
> this respect) the (local ...) is like a ((lambda () ...))

Yes, correct.  In that one respect [2], they are similar.  But in the
equally if not more important criterion [1], they are different in an
important way: because

(define x 3)
(define y 2)
(define z (* x y))
z

evaluates to 6,

  (local ((define x 3)
          (define y 2)
          (define z (* x y)))
   z)

is guaranteed to always evaluate to 6, whereas the value of

  ((lambda ()
     (define x 3)
     (define y 2)
     (define z (* x y))
     z))

is NOT defined -- some implementations will sometimes print 6, while
the same implementation at other times, and other implementations,
will sometimes give an #<undefined> value and at other times give an
error.  In short, you cannot rely on the answer being any particular
thing.  These are all legal responses because this deceptively simple
code, though it looks reasonable enough, is nonsensical!  The reason
for this is subtle; Rob Warnock explained this in a parallel thread
(look for "Differences between SCM version ...").

This is why local is NOT the same as any of these other constructs.
We invented local (a) so we wouldn't have to explain the subtleties
that Warnock explained, and (b) so programmers, having understood the
subtlety, wouldn't have to rewrite their code entirely to work around
the problem.

Quote:
> > > Yep, I guess you're mostly right about that.

> > Only "mostly"? (-:

> Right.  For any value (0-100%) of "mostly".  Fine, rub it in.  Is that a
> strange frowning emoticon, or an upside-down smiling emoticon?

It's not upside down, it's mirrored left-to-right: I'm left-handed.

HTH.

'shriram



Wed, 04 Dec 2002 03:00:00 GMT  
 Dr. Scheme "local"?

| Yes, correct.  In that one respect [2], they are similar.  But in the
| equally if not more important criterion [1], they are different in an
| important way: because
|
| (define x 3)
| (define y 2)
| (define z (* x y))
| z
|
| evaluates to 6,
|
|   (local ((define x 3)
|           (define y 2)
|           (define z (* x y)))
|    z)
|
| is guaranteed to always evaluate to 6, whereas the value of
|
|   ((lambda ()
|      (define x 3)
|      (define y 2)
|      (define z (* x y))
|      z))
|
| is NOT defined -- some implementations will sometimes print 6, while
| the same implementation at other times, and other implementations,
| will sometimes give an #<undefined> value and at other times give an
| error.

What about:

  ((lambda ()
     (begin
       (define x 3)
       (define y 2)
       (define z (* x y))
       z)))

As R5RS says:

  The <expression>s are evaluated sequentially from left to right, and
  the value(s) of the last <expression> is(are) returned.  This
  expression type is used to sequence side effects such as input and
  output.

So, I would think the above is equivalent to (local ...), as the begin
guarantees that the internal defines are evaluated sequentially.  Or
am I still missing something?

--

The surest protection against temptation is cowardice.
                -- Mark Twain



Thu, 05 Dec 2002 03:00:00 GMT  
 Dr. Scheme "local"?

+---------------
| What about:
|   ((lambda ()
|      (begin
|        (define x 3)
|        (define y 2)
|        (define z (* x y))
|        z)))
|
| As R5RS says:
|   The <expression>s are evaluated sequentially from left to right, and
|   the value(s) of the last <expression> is(are) returned.  This
|   expression type is used to sequence side effects such as input and
|   output.
|
| So, I would think the above is equivalent to (local ...), as the begin
| guarantees that the internal defines are evaluated sequentially.  Or
| am I still missing something?
+---------------

Yes, you're still missing something, I'm afraid. Internal definitions
are not themselves "expressions", they're "internal definitions" --
and as such are *exactly* equivalent to a *single* "letrec" expression.
[See R5RS Section 5.2.2 "Internal definitions".] That is, your example
above is *defined* to mean this:

    ((lambda ()
       (begin                   ; now redundant
         (letrec ((x 3)
                  (y 2)
                  (z (* x y)))
           z)))

The "begin" contains only one expression (the "letrec"), and thus there
is no "left to right" sequentiality involved at all.

Oh, and the "letrec" bindings violate the rules [R5RS 4.2.2 & 5.2.2]
requiring that "it must be possible to evaluate each <init> without
assigning or referring to the value of any <variable>"...

-Rob

-----

Applied Networking              http://reality.sgi.com/rpw3/
Silicon Graphics, Inc.          Phone: 650-933-1673
1600 Amphitheatre Pkwy.         PP-ASEL-IA
Mountain View, CA  94043



Fri, 06 Dec 2002 03:00:00 GMT  
 Dr. Scheme "local"?

Quote:

> This is why local is NOT the same as any of these other constructs.
> We invented local (a) so we wouldn't have to explain the subtleties
> that Warnock explained, and (b) so programmers, having understood the
> subtlety, wouldn't have to rewrite their code entirely to work around
> the problem.

OK, I'm convinced. There's a bug in the spec, and letrec should be
replaced w/local.

So apparently 'local' would be a 'primitive expression type' in any
possible R6RS? Or do you have some clever hack for implementing it in
terms of lambda?

david rush
--
If you give someone fortran, he has Fortran.
If you give someone Lisp, he has any language he pleases.
        -- Guy L. Steele Jr.



Fri, 06 Dec 2002 03:00:00 GMT  
 Dr. Scheme "local"?

Quote:


> > So apparently 'local' would be a 'primitive expression type' in any
> > possible R6RS? Or do you have some clever hack for implementing it in
> > terms of lambda?

> I think this would work:

> (define-syntax local
>   (syntax-rules (define)
>     ((local ((define var init) ...)
>             expr ...)
>      (let ((var #f) ...)
>        (begin (set! var init) ...)
>        expr ...))))

Nice try.  But recall that we also want the top-levels error warnings.
A language should as regular as possible and necessary, including
ERROR messages. So, now try this one:

  > (local ((define y (+ x 20))
                   (define x 10))
       (* x y))

DrScheme report the following error (Intermediate):

   Variable x referenced before definition or initialization

And at top-level, it's pretty much the same error message.

-- Matthias



Fri, 06 Dec 2002 03:00:00 GMT  
 Dr. Scheme "local"?

Quote:

> I think this would work:

> (define-syntax local
>   (syntax-rules (define)
>     ((local ((define var init) ...)
>        expr ...)
>      (let ((var #f) ...)
>        (begin (set! var init) ...)
>        expr ...))))

This can't work.  Note that the macro artificially binds names that
are unbound, so any code that references something unbound now
inadvertently finds them bound to a specific value (#f) -- if they use
it in a non-boolean context, they get the wrong error message; if they
use it in a boolean context, they would never know that they actually
had an erroneous program and were computing with nonsense.  So this is
a particularly *insidious* macro.

'shriram



Fri, 06 Dec 2002 03:00:00 GMT  
 
 [ 42 post ]  Go to page: [1] [2] [3]

 Relevant Pages 

1. "Dr. O", "Dr. John", etc. etc.

2. "Dr. Know" career question

3. string.join(["Tk 4.2p2", "Python 1.4", "Win32", "free"], "for")

4. Witness Lee and the "Local Churches": A Personal Testimony

5. Clipper Debugger "loses" Local variables

6. "Local" Batch Files

7. "local l : like Result"

8. local uses of "vars"

9. Local directory search "server" script

10. Question about "exec in globals, locals"

11. Run a local script while "expecting"

12. Extraneous "eval" in ::itcl::local

 

 
Powered by phpBB® Forum Software