Confused with behavior of this procedure
up vote
1
down vote
favorite
(CONTEXT)
I've defined a procedure that applies another one-argument procedure object to it's parameter twice. Take for example the procedure inc that adds 1 to it's argument, (double inc) will add two. hence ((double inc) 5) returns 7.
(THE PROBLEM)
I expected for (((double (double double)) inc) 5) to return 13. Since double double will apply a procedure 4 times and thus the most-left double will result in a the application of the one-parameter procedure 8 times. A lineair growth.
I'm wrong. Look below for what the procedure actually returns.
Clearly i'm missing something and there's a flaw in my understanding.
(define (double proc)
(lambda (y) (proc (proc y))))
(define (inc x) (+ x 1))
> ((double inc) 5)
7
> (((double double) inc) 5)
9
> (((double (double double)) inc) 5)
21
> (((double (double (double double))) inc) 5)
261
>
lambda scheme racket prediction r5rs
add a comment |
up vote
1
down vote
favorite
(CONTEXT)
I've defined a procedure that applies another one-argument procedure object to it's parameter twice. Take for example the procedure inc that adds 1 to it's argument, (double inc) will add two. hence ((double inc) 5) returns 7.
(THE PROBLEM)
I expected for (((double (double double)) inc) 5) to return 13. Since double double will apply a procedure 4 times and thus the most-left double will result in a the application of the one-parameter procedure 8 times. A lineair growth.
I'm wrong. Look below for what the procedure actually returns.
Clearly i'm missing something and there's a flaw in my understanding.
(define (double proc)
(lambda (y) (proc (proc y))))
(define (inc x) (+ x 1))
> ((double inc) 5)
7
> (((double double) inc) 5)
9
> (((double (double double)) inc) 5)
21
> (((double (double (double double))) inc) 5)
261
>
lambda scheme racket prediction r5rs
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
(CONTEXT)
I've defined a procedure that applies another one-argument procedure object to it's parameter twice. Take for example the procedure inc that adds 1 to it's argument, (double inc) will add two. hence ((double inc) 5) returns 7.
(THE PROBLEM)
I expected for (((double (double double)) inc) 5) to return 13. Since double double will apply a procedure 4 times and thus the most-left double will result in a the application of the one-parameter procedure 8 times. A lineair growth.
I'm wrong. Look below for what the procedure actually returns.
Clearly i'm missing something and there's a flaw in my understanding.
(define (double proc)
(lambda (y) (proc (proc y))))
(define (inc x) (+ x 1))
> ((double inc) 5)
7
> (((double double) inc) 5)
9
> (((double (double double)) inc) 5)
21
> (((double (double (double double))) inc) 5)
261
>
lambda scheme racket prediction r5rs
(CONTEXT)
I've defined a procedure that applies another one-argument procedure object to it's parameter twice. Take for example the procedure inc that adds 1 to it's argument, (double inc) will add two. hence ((double inc) 5) returns 7.
(THE PROBLEM)
I expected for (((double (double double)) inc) 5) to return 13. Since double double will apply a procedure 4 times and thus the most-left double will result in a the application of the one-parameter procedure 8 times. A lineair growth.
I'm wrong. Look below for what the procedure actually returns.
Clearly i'm missing something and there's a flaw in my understanding.
(define (double proc)
(lambda (y) (proc (proc y))))
(define (inc x) (+ x 1))
> ((double inc) 5)
7
> (((double double) inc) 5)
9
> (((double (double double)) inc) 5)
21
> (((double (double (double double))) inc) 5)
261
>
lambda scheme racket prediction r5rs
lambda scheme racket prediction r5rs
asked Nov 11 at 11:51
Turgut Kursun
154
154
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
up vote
2
down vote
accepted
This should be fairly easy to deduct using both reason or substitution model.
Reason:
(double double)
This is like double but twice, quadrouple. When applied with a function it will apply that function 4 times.
(double (double double))
This is doubling quadrouple. The result of quadrouple will be quadroupled making it 4*4. When applied with a function it will apply that 16 times.
(double (double (double double)))
This is doubling the previous one. Then the same again. 16*16 makes it apply the result 256 times.
Thus (double double)
is 2^2
, (double (double double))
is (2^2)^2
and (double (double (double double)))
is ((2^2)^2)^2
or 2^8
for short.
This relates to lambda calculus where power is defined as λb.λe.e b
or (lambda (b) (lambda (e) (e b))
. Now double
is the church numeral for 2
. Do you see that you are doing ((2^2)^2)^2
?
Substitution
Here are the expressions reduced. I sometimes jump steps later since it's pretty much the same that happens several times.
((double inc) 5) ; ==>
((lambda (y) (inc (inc y))) 5) ; ==>
(inc (inc 5)) ; ==> 7
(((double double) inc) 5) ; ==>
(((lambda (y) (double (double y))) inc) 5) ; ==>
(((lambda (y) (double (double y))) inc) 5) ; ==>
((double (double inc)) 5) ; ==>
((double (lambda (y) (inc (inc y)))) 5) ; ==>
((lambda (y) ((lambda (y) (inc (inc y))) ((lambda (y) (inc (inc y))) y))) 5) ; ==>
((lambda (y) (inc (inc (inc (inc y))))) 5) ; ==>
(inc (inc (inc (inc 5)))) ; ==> 9
(((double (double double)) inc) 5) ; ==>
(((double (lambda (y) (double (double y)))) inc) 5) ; ==>
(((lambda (y) ((lambda (y) (double (double y))) ((lambda (y) (double (double y))) y))) inc) 5) ; ==>
(((lambda (y) (double (double (double (double y))))) inc) 5) ; ==>
((double (double (double (lambda (y) (inc (inc y)))))) 5) ; ==>
((double (double (lambda (y) (inc (inc (inc (inc y))))))) 5) ; ==>
(inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc 5)))))))))))))))) ; ==> 21
I'll leave the last one as an exercise.
add a comment |
up vote
2
down vote
The problem is in your interpretation of what double
expands to when nested.
Just apply substitution of y
with inc
, one level at a time, and you'll see what's happening:
(double inc)
expansion using let
to make things clearer:
(lambda (y)
(let ([proc inc])
((proc (proc y))))
So far, so good.
((double double) inc)
expansion:
(lambda (y)
(let ([proc (lambda (y_0) (double (double y_0)))])
(proc (proc y))))
The first application works as intended, but the second doubles not the application of the inc
function, but of the double
function itself, as you apply double
to the function double
in (double double)
.
If you do it again, i.e. ((double (double double) inc)
, you can see it gets messy...
What you're probably looking for is to apply the result of a single application of double
to the result of another single application...
As in:
> ((double (double (double inc))) 5)
13
> ((double (double (double (double inc)))) 5)
21
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
This should be fairly easy to deduct using both reason or substitution model.
Reason:
(double double)
This is like double but twice, quadrouple. When applied with a function it will apply that function 4 times.
(double (double double))
This is doubling quadrouple. The result of quadrouple will be quadroupled making it 4*4. When applied with a function it will apply that 16 times.
(double (double (double double)))
This is doubling the previous one. Then the same again. 16*16 makes it apply the result 256 times.
Thus (double double)
is 2^2
, (double (double double))
is (2^2)^2
and (double (double (double double)))
is ((2^2)^2)^2
or 2^8
for short.
This relates to lambda calculus where power is defined as λb.λe.e b
or (lambda (b) (lambda (e) (e b))
. Now double
is the church numeral for 2
. Do you see that you are doing ((2^2)^2)^2
?
Substitution
Here are the expressions reduced. I sometimes jump steps later since it's pretty much the same that happens several times.
((double inc) 5) ; ==>
((lambda (y) (inc (inc y))) 5) ; ==>
(inc (inc 5)) ; ==> 7
(((double double) inc) 5) ; ==>
(((lambda (y) (double (double y))) inc) 5) ; ==>
(((lambda (y) (double (double y))) inc) 5) ; ==>
((double (double inc)) 5) ; ==>
((double (lambda (y) (inc (inc y)))) 5) ; ==>
((lambda (y) ((lambda (y) (inc (inc y))) ((lambda (y) (inc (inc y))) y))) 5) ; ==>
((lambda (y) (inc (inc (inc (inc y))))) 5) ; ==>
(inc (inc (inc (inc 5)))) ; ==> 9
(((double (double double)) inc) 5) ; ==>
(((double (lambda (y) (double (double y)))) inc) 5) ; ==>
(((lambda (y) ((lambda (y) (double (double y))) ((lambda (y) (double (double y))) y))) inc) 5) ; ==>
(((lambda (y) (double (double (double (double y))))) inc) 5) ; ==>
((double (double (double (lambda (y) (inc (inc y)))))) 5) ; ==>
((double (double (lambda (y) (inc (inc (inc (inc y))))))) 5) ; ==>
(inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc 5)))))))))))))))) ; ==> 21
I'll leave the last one as an exercise.
add a comment |
up vote
2
down vote
accepted
This should be fairly easy to deduct using both reason or substitution model.
Reason:
(double double)
This is like double but twice, quadrouple. When applied with a function it will apply that function 4 times.
(double (double double))
This is doubling quadrouple. The result of quadrouple will be quadroupled making it 4*4. When applied with a function it will apply that 16 times.
(double (double (double double)))
This is doubling the previous one. Then the same again. 16*16 makes it apply the result 256 times.
Thus (double double)
is 2^2
, (double (double double))
is (2^2)^2
and (double (double (double double)))
is ((2^2)^2)^2
or 2^8
for short.
This relates to lambda calculus where power is defined as λb.λe.e b
or (lambda (b) (lambda (e) (e b))
. Now double
is the church numeral for 2
. Do you see that you are doing ((2^2)^2)^2
?
Substitution
Here are the expressions reduced. I sometimes jump steps later since it's pretty much the same that happens several times.
((double inc) 5) ; ==>
((lambda (y) (inc (inc y))) 5) ; ==>
(inc (inc 5)) ; ==> 7
(((double double) inc) 5) ; ==>
(((lambda (y) (double (double y))) inc) 5) ; ==>
(((lambda (y) (double (double y))) inc) 5) ; ==>
((double (double inc)) 5) ; ==>
((double (lambda (y) (inc (inc y)))) 5) ; ==>
((lambda (y) ((lambda (y) (inc (inc y))) ((lambda (y) (inc (inc y))) y))) 5) ; ==>
((lambda (y) (inc (inc (inc (inc y))))) 5) ; ==>
(inc (inc (inc (inc 5)))) ; ==> 9
(((double (double double)) inc) 5) ; ==>
(((double (lambda (y) (double (double y)))) inc) 5) ; ==>
(((lambda (y) ((lambda (y) (double (double y))) ((lambda (y) (double (double y))) y))) inc) 5) ; ==>
(((lambda (y) (double (double (double (double y))))) inc) 5) ; ==>
((double (double (double (lambda (y) (inc (inc y)))))) 5) ; ==>
((double (double (lambda (y) (inc (inc (inc (inc y))))))) 5) ; ==>
(inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc 5)))))))))))))))) ; ==> 21
I'll leave the last one as an exercise.
add a comment |
up vote
2
down vote
accepted
up vote
2
down vote
accepted
This should be fairly easy to deduct using both reason or substitution model.
Reason:
(double double)
This is like double but twice, quadrouple. When applied with a function it will apply that function 4 times.
(double (double double))
This is doubling quadrouple. The result of quadrouple will be quadroupled making it 4*4. When applied with a function it will apply that 16 times.
(double (double (double double)))
This is doubling the previous one. Then the same again. 16*16 makes it apply the result 256 times.
Thus (double double)
is 2^2
, (double (double double))
is (2^2)^2
and (double (double (double double)))
is ((2^2)^2)^2
or 2^8
for short.
This relates to lambda calculus where power is defined as λb.λe.e b
or (lambda (b) (lambda (e) (e b))
. Now double
is the church numeral for 2
. Do you see that you are doing ((2^2)^2)^2
?
Substitution
Here are the expressions reduced. I sometimes jump steps later since it's pretty much the same that happens several times.
((double inc) 5) ; ==>
((lambda (y) (inc (inc y))) 5) ; ==>
(inc (inc 5)) ; ==> 7
(((double double) inc) 5) ; ==>
(((lambda (y) (double (double y))) inc) 5) ; ==>
(((lambda (y) (double (double y))) inc) 5) ; ==>
((double (double inc)) 5) ; ==>
((double (lambda (y) (inc (inc y)))) 5) ; ==>
((lambda (y) ((lambda (y) (inc (inc y))) ((lambda (y) (inc (inc y))) y))) 5) ; ==>
((lambda (y) (inc (inc (inc (inc y))))) 5) ; ==>
(inc (inc (inc (inc 5)))) ; ==> 9
(((double (double double)) inc) 5) ; ==>
(((double (lambda (y) (double (double y)))) inc) 5) ; ==>
(((lambda (y) ((lambda (y) (double (double y))) ((lambda (y) (double (double y))) y))) inc) 5) ; ==>
(((lambda (y) (double (double (double (double y))))) inc) 5) ; ==>
((double (double (double (lambda (y) (inc (inc y)))))) 5) ; ==>
((double (double (lambda (y) (inc (inc (inc (inc y))))))) 5) ; ==>
(inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc 5)))))))))))))))) ; ==> 21
I'll leave the last one as an exercise.
This should be fairly easy to deduct using both reason or substitution model.
Reason:
(double double)
This is like double but twice, quadrouple. When applied with a function it will apply that function 4 times.
(double (double double))
This is doubling quadrouple. The result of quadrouple will be quadroupled making it 4*4. When applied with a function it will apply that 16 times.
(double (double (double double)))
This is doubling the previous one. Then the same again. 16*16 makes it apply the result 256 times.
Thus (double double)
is 2^2
, (double (double double))
is (2^2)^2
and (double (double (double double)))
is ((2^2)^2)^2
or 2^8
for short.
This relates to lambda calculus where power is defined as λb.λe.e b
or (lambda (b) (lambda (e) (e b))
. Now double
is the church numeral for 2
. Do you see that you are doing ((2^2)^2)^2
?
Substitution
Here are the expressions reduced. I sometimes jump steps later since it's pretty much the same that happens several times.
((double inc) 5) ; ==>
((lambda (y) (inc (inc y))) 5) ; ==>
(inc (inc 5)) ; ==> 7
(((double double) inc) 5) ; ==>
(((lambda (y) (double (double y))) inc) 5) ; ==>
(((lambda (y) (double (double y))) inc) 5) ; ==>
((double (double inc)) 5) ; ==>
((double (lambda (y) (inc (inc y)))) 5) ; ==>
((lambda (y) ((lambda (y) (inc (inc y))) ((lambda (y) (inc (inc y))) y))) 5) ; ==>
((lambda (y) (inc (inc (inc (inc y))))) 5) ; ==>
(inc (inc (inc (inc 5)))) ; ==> 9
(((double (double double)) inc) 5) ; ==>
(((double (lambda (y) (double (double y)))) inc) 5) ; ==>
(((lambda (y) ((lambda (y) (double (double y))) ((lambda (y) (double (double y))) y))) inc) 5) ; ==>
(((lambda (y) (double (double (double (double y))))) inc) 5) ; ==>
((double (double (double (lambda (y) (inc (inc y)))))) 5) ; ==>
((double (double (lambda (y) (inc (inc (inc (inc y))))))) 5) ; ==>
(inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc 5)))))))))))))))) ; ==> 21
I'll leave the last one as an exercise.
answered Nov 11 at 13:38
Sylwester
33.7k22854
33.7k22854
add a comment |
add a comment |
up vote
2
down vote
The problem is in your interpretation of what double
expands to when nested.
Just apply substitution of y
with inc
, one level at a time, and you'll see what's happening:
(double inc)
expansion using let
to make things clearer:
(lambda (y)
(let ([proc inc])
((proc (proc y))))
So far, so good.
((double double) inc)
expansion:
(lambda (y)
(let ([proc (lambda (y_0) (double (double y_0)))])
(proc (proc y))))
The first application works as intended, but the second doubles not the application of the inc
function, but of the double
function itself, as you apply double
to the function double
in (double double)
.
If you do it again, i.e. ((double (double double) inc)
, you can see it gets messy...
What you're probably looking for is to apply the result of a single application of double
to the result of another single application...
As in:
> ((double (double (double inc))) 5)
13
> ((double (double (double (double inc)))) 5)
21
add a comment |
up vote
2
down vote
The problem is in your interpretation of what double
expands to when nested.
Just apply substitution of y
with inc
, one level at a time, and you'll see what's happening:
(double inc)
expansion using let
to make things clearer:
(lambda (y)
(let ([proc inc])
((proc (proc y))))
So far, so good.
((double double) inc)
expansion:
(lambda (y)
(let ([proc (lambda (y_0) (double (double y_0)))])
(proc (proc y))))
The first application works as intended, but the second doubles not the application of the inc
function, but of the double
function itself, as you apply double
to the function double
in (double double)
.
If you do it again, i.e. ((double (double double) inc)
, you can see it gets messy...
What you're probably looking for is to apply the result of a single application of double
to the result of another single application...
As in:
> ((double (double (double inc))) 5)
13
> ((double (double (double (double inc)))) 5)
21
add a comment |
up vote
2
down vote
up vote
2
down vote
The problem is in your interpretation of what double
expands to when nested.
Just apply substitution of y
with inc
, one level at a time, and you'll see what's happening:
(double inc)
expansion using let
to make things clearer:
(lambda (y)
(let ([proc inc])
((proc (proc y))))
So far, so good.
((double double) inc)
expansion:
(lambda (y)
(let ([proc (lambda (y_0) (double (double y_0)))])
(proc (proc y))))
The first application works as intended, but the second doubles not the application of the inc
function, but of the double
function itself, as you apply double
to the function double
in (double double)
.
If you do it again, i.e. ((double (double double) inc)
, you can see it gets messy...
What you're probably looking for is to apply the result of a single application of double
to the result of another single application...
As in:
> ((double (double (double inc))) 5)
13
> ((double (double (double (double inc)))) 5)
21
The problem is in your interpretation of what double
expands to when nested.
Just apply substitution of y
with inc
, one level at a time, and you'll see what's happening:
(double inc)
expansion using let
to make things clearer:
(lambda (y)
(let ([proc inc])
((proc (proc y))))
So far, so good.
((double double) inc)
expansion:
(lambda (y)
(let ([proc (lambda (y_0) (double (double y_0)))])
(proc (proc y))))
The first application works as intended, but the second doubles not the application of the inc
function, but of the double
function itself, as you apply double
to the function double
in (double double)
.
If you do it again, i.e. ((double (double double) inc)
, you can see it gets messy...
What you're probably looking for is to apply the result of a single application of double
to the result of another single application...
As in:
> ((double (double (double inc))) 5)
13
> ((double (double (double (double inc)))) 5)
21
answered Nov 11 at 13:26
Renato
6,55513348
6,55513348
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53248457%2fconfused-with-behavior-of-this-procedure%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown