Home > Archive > Scheme > March 2007 > Why does delay need to be special?
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Why does delay need to be special?
|
|
| dillogimp@gmail.com 2007-03-30, 4:14 am |
| hi
Why does delay need to be special?
Let's say my interpreter is simply the eager kind. (the simple MC-eval
in sicp 4.1)
(pp stream-enumerate-interval)
(named-lambda (stream-enumerate-interval low high)
(if (> low high)
the-empty-stream
(cons low (lambda () (stream-enumerate-interval (+ low 1)
high)))))
Let's say I'm not lazy and like to hand translate all my stream
related functions by hand into lambdas. Do I need delay at all?
Does the interpreter has to support it somehow?
I can't figured out what's the point of having a special syntax for
delay.
(I can understand some people want IF statement be special so that
only the predicate is evaluated first and not all the argument.) There
is efficiciency reason for it.
What's the justification for "delay" to be a special form?
please clarify. thanks.
| |
| Jens Axel Søgaard 2007-03-30, 4:14 am |
| > Why does delay need to be special?
> Let's say I'm not lazy and like to hand translate all my stream
> related functions by hand into lambdas. Do I need delay at all?
Yes. In (delay <expression> ) the <expression> is evaluated only once,
namely when it is forced the first time.
Consider the following example:
Welcome to DrScheme, version 301.
Language: Pretty Big (includes MrEd and Advanced Student).
> (define promise (delay (current-seconds)))
> (current-seconds)
1175232860
> (force promise)
1175232865
> (force promise)
1175232865
> (force promise)
1175232865
--
Jens Axel Søgaard
| |
| dillogimp@gmail.com 2007-03-30, 4:14 am |
| On Mar 30, 1:35 pm, Jens Axel S=F8gaard <use...@soegaard.net> wrote:
>
> Yes. In (delay <expression> ) the <expression> is evaluated only once,
> namely when it is forced the first time.
Are you talking about memorizing. Let's say we don't care about
efficiency, so "(delay <exp> ) <=3D> (lambda () exp)" like the simple
version in SICP. Does your example still hold?
>
> Consider the following example:
>
> Welcome to DrScheme, version 301.
> Language: Pretty Big (includes MrEd and Advanced Student).
>
>
> 1175232860
>
> 1175232865
>
> 1175232865
>
> 1175232865
>
> --
> Jens Axel S=F8gaard
| |
| dillogimp@gmail.com 2007-03-30, 4:14 am |
| On Mar 30, 1:58 pm, dillog...@gmail.com wrote:
> On Mar 30, 1:35 pm, Jens Axel S=F8gaard <use...@soegaard.net> wrote:
>
>
>
> Are you talking about memorizing. Let's say we don't care about
> efficiency, so "(delay <exp> ) <=3D> (lambda () exp)" like the simple
> version in SICP. Does your example still hold?
>
>
>
>
>
>
>
>
>
>
Strange, the special form did work as intended. The "defined" form
gets called only once...
Welcome to MzScheme version 360, Copyright (c) 2004-2006 PLT Scheme
Inc.[color=darkred]
> (define-syntax delay
(syntax-rules ()
((delay exp)
(lambda () exp))))
(define (force delayed-object) (delayed-object))
(define promise (delay (current-seconds)))
1175205698[color=darkred]
> (force promise)
1175205699
> (force promise)
1175205700
Welcome to MzScheme version 360, Copyright (c) 2004-2006 PLT Scheme
Inc.
> (define (delay e) (lambda () e))
(define (force delayed-object) (delayed-object))
(define promise (delay (current-seconds)))
1175205811[color=darkred]
> (force promise)
1175205811
> (force promise)
1175205811
> (force promise)
1175205811
> (force promise)
1175205811
> (force promise)
1175205811
| |
| dillogimp@gmail.com 2007-03-30, 4:14 am |
| On Mar 30, 2:09 pm, dillog...@gmail.com wrote:
> On Mar 30, 1:58 pm, dillog...@gmail.com wrote:
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> Strange, the special form did work as intended. The "defined" form
> gets called only once...
>
> Welcome to MzScheme version 360, Copyright (c) 2004-2006 PLT Scheme
> Inc.> (define-syntax delay
>
> (syntax-rules ()
> ((delay exp)
> (lambda () exp))))
> (define (force delayed-object) (delayed-object))
> (define promise (delay (current-seconds)))> > > (force promise)
> 1175205698
> 1175205699
>
> 1175205700
>
> Welcome to MzScheme version 360, Copyright (c) 2004-2006 PLT Scheme
> Inc.> (define (delay e) (lambda () e))
>
> (define (force delayed-object) (delayed-object))
> (define promise (delay (current-seconds)))> > > (force promise)
> 1175205811
> 1175205811
> 1175205811
> 1175205811
> 1175205811
>
> 1175205811
I've tried another example, and it works this time for all three
cases, so I still don't get it what's the point of delay?
Welcome to MzScheme version 360, Copyright (c) 2004-2006 PLT Scheme
Inc.
>
(define-syntax delay
(syntax-rules ()
((delay exp)
(lambda () exp))))
(define x 1)
(define (force delayed-object) (delayed-object))
(define promise (delay (set! x (+ x 1))))
(force promise)
(force promise)
(force promise)
4[color=darkred]
>
Welcome to MzScheme version 360, Copyright (c) 2004-2006 PLT Scheme
Inc.
> (define x 1)
(define (force delayed-object) (delayed-object))
(define promise (lambda () (set! x (+ x 1))))
(force promise)
(force promise)
(force promise)[color=darkred]
4
This MC-eval:
(define (force delayed-object) (delayed-object))
(define promise (lambda () (set! x (+ x 1))))
(force promise)
(force promise)
(force promise)
x
4
| |
| Nils M Holm 2007-03-30, 4:14 am |
| dillogimp@gmail.com wrote:
> (define (force delayed-object) (delayed-object))
An expression passed to your version of DELAY is called only
once, but it is called at the wrong time, namely when the
expression is passed to DELAY and not when the promise is
forced.
Using R5RS DELAY:
(define x 0)
x => 0
(define p (delay (set! x 1)))
x => 0
(force p)
x => 1
Using your DELAY:
(define x 0)
x => 0
(define p (delay (set! x 1)))
x => 1
(force p)
x => 1
--
Nils M Holm <n m h @ t 3 x . o r g> -- http://t3x.org/nmh/
| |
| Jussi Piitulainen 2007-03-30, 4:14 am |
| dillogimp@gmail.com writes:
....
It "gets called once" even if you never force it. Make sure you
understand why and when.
....[color=darkred]
You think the "promise" has any dependence on current-seconds? Or just
to the value that current-seconds happened to return when the
"promise" was made? It's the latter.
[color=darkred]
> I've tried another example, and it works this time for all three
> cases, so I still don't get it what's the point of delay?
....
> (define promise (delay (set! x (+ x 1))))
> (force promise)
> (force promise)
> (force promise)
> x
> 4
....
You compare several incorrect implementations of delay, you find them
to behave the same in your tests, and you wonder what is the point.
Why not compare them with a correct implementation?
Here's the expected value, in Scsh:
(define x 1)
(define promise (delay (set! x (+ x 1))))
(force promise)
(force promise)
(force promise)
(force promise)
x
2
Here's a more informative test sequence:
(define x 1)
x
1
(define promise (delay (set! x (+ x 1))))
x
1
(force promise)
x
2
(force promise)
x
2
| |
| dillogimp@gmail.com 2007-03-30, 4:14 am |
| On Mar 30, 3:23 pm, Nils M Holm <before-2007-04...@online.de> wrote:
> dillog...@gmail.com wrote:
>
> An expression passed to your version of DELAY is called only
> once, but it is called at the wrong time, namely when the
> expression is passed to DELAY and not when the promise is
> forced.
>
> Using R5RS DELAY:
>
> (define x 0)
> x => 0
> (define p (delay (set! x 1)))
> x => 0
> (force p)
> x => 1
>
> Using your DELAY:
>
> (define x 0)
> x => 0
> (define p (delay (set! x 1)))
I don't get it.
(define p (delay (set! x 1))) <=>
(define p (lambda () (set! x 1)))
If the interpreter is too eager, then the problem is with how the
interpreter (or compiler) handles define-- not with the sematics.
In english, when you define something you don't actually run it to
begin with. How can you possbilly say when delay is equivalent to
lambda with no argument then it automatically gets delayed -- one
time?, one clock? Does all lambda with no argument gets delayed
equally? I don't get it.
> x => 1
> (force p)
> x => 1
>
> --
> Nils M Holm <n m h @ t 3 x . o r g> --http://t3x.org/nmh/
| |
| Jussi Piitulainen 2007-03-30, 4:14 am |
| dillogimp@gmail.com writes:
> If the interpreter is too eager, then the problem is with how the
> interpreter (or compiler) handles define-- not with the sematics.
That _is_ semantics.
> How can you possbilly say when delay is equivalent to lambda with
> no argument then it automatically gets delayed -- one time?, one
Delay is _not_ equivalent to a lambda with no argument. You have
just seen that the two behave differently, twice.
> Does all lambda with no argument gets delayed equally? I don't
> get it.
A lambda expression evaluates to a procedure. Its body is _not_
evaluated at that time but _is_ evaluated _every_ time the
procedure is called. This has nothing to do with the number of
arguments.
A procedure call is evaluated by evaluating the procedure
expression (usually just a variable) and the argument expressions
in some order, and _then_ passing the _values_ of the argument
expressions to the procedure, like the value of (current-seconds)
in your experiments.
This _is_ semantics, of Scheme. It is possible to have a different
semantics. Then delay may indeed not be needed. You think Scheme
got it wrong? Have you any idea how many other languages get it
wrong the same way? Applicative order is normal. (Sorry.)
| |
| dillogimp@gmail.com 2007-03-30, 4:14 am |
| On Mar 30, 4:25 pm, Jussi Piitulainen <jpiit...@ling.helsinki.fi>
wrote:
> dillog...@gmail.com writes:
>
> That _is_ semantics.
>
>
> Delay is _not_ equivalent to a lambda with no argument. You have
> just seen that the two behave differently, twice.
>
>
> A lambda expression evaluates to a procedure. Its body is _not_
> evaluated at that time but _is_ evaluated _every_ time the
> procedure is called. This has nothing to do with the number of
> arguments.
>
> A procedure call is evaluated by evaluating the procedure
> expression (usually just a variable) and the argument expressions
> in some order, and _then_ passing the _values_ of the argument
> expressions to the procedure, like the value of (current-seconds)
> in your experiments.
>
> This _is_ semantics, of Scheme. It is possible to have a different
> semantics. Then delay may indeed not be needed. You think Scheme
> got it wrong? Have you any idea how many other languages get it
> wrong the same way? Applicative order is normal. (Sorry.)
I don't know who got it wrong to begin with, but quote from the
textbook:
"
Although delay and force may seem like mysterious operations, their
implementation is really quite straightforward. Delay must package an
expression so that it can be evaluated later on demand, and we can
accomplish this simply by treating the expression as the body of a
procedure. Delay can be a special form such that
(delay <exp> )
is syntactic sugar for
(lambda () <exp> ) "
When I try in Mit-scheme:
1 ]=> (define p (lambda () (set! x 1)))
1 ]=> (pp p)
(named-lambda (p)
(set! x 1))
1 ]=> (define p (delay (set! x 1)))
1 ]=> (pp p)
#[promise 2]
Obviously the two statements produce two different things.
So maybe the textbook is wrong?
| |
| Jussi Piitulainen 2007-03-30, 4:14 am |
| dillogimp@gmail.com writes:
> I don't know who got it wrong to begin with, but quote from the
> textbook:
>
> "
> Although delay and force may seem like mysterious operations, their
> implementation is really quite straightforward. Delay must package
> an expression so that it can be evaluated later on demand, and we
> can accomplish this simply by treating the expression as the body of
> a procedure. Delay can be a special form such that
> (delay <exp> )
> is syntactic sugar for
> (lambda () <exp> ) "
....
> So maybe the textbook is wrong?
If the textbook claims to use R5RS, then yes, it got it wrong. It
still gets right the point that delay has to be special.
However, it may be describing a related but simpler construct. Is that
at a point where effects like mutation have not yet been introduced?
| |
| Jens Axel Søgaard 2007-03-30, 8:07 am |
| dillogimp@gmail.com skrev:
> On Mar 30, 1:35 pm, Jens Axel Søgaard <use...@soegaard.net> wrote:
>
> Are you talking about memorizing. Let's say we don't care about
> efficiency, so "(delay <exp> ) <=> (lambda () exp)" like the simple
> version in SICP. Does your example still hold?
Here is two versions of delay.
The first one is "your delay as a function":
(define (delay1 expr)
(lambda () expr))
The second is "your delay as a special form (macro)":
(define-syntax delay2
(syntax-rules ()
[(delay2 expr)
(lambda () expr)]))
Here is an example program:
(define promise1 (delay1 (current-milliseconds)))
(current-milliseconds)
(sleep 1)
(promise1)
(sleep 1)
(promise1)
(newline)
(newline)
(define promise2 (delay2 (current-milliseconds)))
(current-milliseconds)
(sleep 1)
(promise2)
(sleep 1)
(promise2)
and here is the result:
585687825
585687825
585687825
585689872
585690872
585691872
--
Jens Axel Søgaard
|
|
|
|
|