|
|
 |
 |
 |
 |
Scheme Programming Language
|
 |
 |
 |
 |
 |
 |
 |
 |
Why does delay need to be special?
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.
> 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 Sgaard
On Mar 30, 1:35 pm, Jens Axel Sgaard <use@soegaard.net> wrote: > > 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.
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?
> 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 Sgaard
On Mar 30, 1:58 pm, dillog@gmail.com wrote:
> On Mar 30, 1:35 pm, Jens Axel Sgaard <use @soegaard.net> wrote: > > > 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. > 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? > > 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 Sgaard
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 > (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))) > > > (force promise) 1175205811 > (force promise) 1175205811 > (force promise) 1175205811 > (force promise) 1175205811 > (force promise) 1175205811 > (force promise)
1175205811
On Mar 30, 2:09 pm, dillog@gmail.com wrote:
> On Mar 30, 1:58 pm, dillog @gmail.com wrote: > > On Mar 30, 1:35 pm, Jens Axel Sgaard <use@soegaard.net> wrote: > > > > 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. > > 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? > > > 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 Sgaard > 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 > > (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)))> > > (force promise) > 1175205811 > > (force promise) > 1175205811 > > (force promise) > 1175205811 > > (force promise) > 1175205811 > > (force promise) > 1175205811 > > (force promise) > 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) > > > > > > > x 4
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) > > > > > > x
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
dillog @gmail.com wrote: > > (define (delay e) (lambda () e)) > (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/
... >> Strange, the special form did work as intended. The "defined" form >> gets called only once...
It "gets called once" even if you never force it. Make sure you understand why and when. ... >> (define (delay e) (lambda () e)) >> (define (force delayed-object) (delayed-object)) >> (define promise (delay (current-seconds)))
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. > 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
On Mar 30, 3:23 pm, Nils M Holm <before-2007-04@online.de> wrote:
> dillog @gmail.com wrote: > > > (define (delay e) (lambda () e)) > > (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)))
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.
dillog @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.)
On Mar 30, 4:25 pm, Jussi Piitulainen <jpiit@ling.helsinki.fi> wrote:
> dillog @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.)
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?
dillog @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?
dillog@gmail.com skrev: > On Mar 30, 1:35 pm, Jens Axel Sgaard <use @soegaard.net> wrote: >>> 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. > 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 Sgaard
|
 |
 |
 |
 |
|