What is the purpose of Closures in Scheme/Racket? - scheme

I am learning Scheme and just came across Closures. The following example provided, demonstrating the use of Closures:
(define (create-closure x)
(lambda () x))
(define val (create-closure 10))
From what I understand, when the above code is evaluated, val will equal to 10. I realize this is just an example, but I don't understand just how a closure would be helpful. What are the advantages and what would a scenario where such a concept would be needed?

val is not 10 but a closure. If you call it like (val) it returns the value of x. x is a closure variable that still exists since it's still in use. A better example is this:
(define (larger-than-predicate n)
(lambda (v) (> v n )))
(filter (larger-than-predicate 5) '(1 2 3 4 5 6 7 8 9 10))
; ==> (6 7 8 9 10)
So the predicate compares the argument with v which is a variable that still holds 5. In a dynamic bound lisp this is not possible to do because n will not exist when the comparison happens.
Lecical scoping was introduces in Algol and Scheme. JavaScript, PHP amd C# are all algol dialects and have inherited it from there. Scheme was the first lisp to get it and Common Lisp followed. It's actually the most common scoping.

From this example you can see that the closure allows the functions local environment to remain accessible after being called.
(define count
(let ((next 0))
(lambda ()
(let ((v next))
(set! next (+ next 1))
v))))
(count)
(count)
(count)
0..1..2

I believe in the example you give, val will NOT equal to 10, instead, a lambda object (lambda () 10) will be assigned to val. So (val) equals to 10.
In the world of Scheme, there are two different concepts sharing the same term "closure". See this post for a brief introduction to both of these terms. In your case, I believe by "closure" you mean "lexical closure". In your code example, the parameter x is a free variable to the returned lambda and is referred to by that returned lambda, so a lexical closure is kept to store the value of x. I believe this post will give you a good explanation on what (lexical) closure is.

Totally agree with Lifu Huang's answer.
In addition, I'd like to highlight the most obvious use of closures, namely callbacks.
For instance, in JavaScript, I might write
function setup(){
var presses = 0;
function handleKeyPress(evt){
presses = presses + 1;
return mainHandler(evt);
}
installKeyHandler(handleKeyPress);
}
In this case, it's important to me that the function that I'm installing as the key handler "knows about" the binding for the presses variable. That binding is stored in the closure. Put differently, the function is "closed over" the binding for presses.
Similar things occur in nearly every http GET or POST call made in JS. It crops up in many many other places as well.

Btw, create-closure from your question is known by some as the Kestrel combinator, from the family of Combinator Birds. It is also known as True in Church encoding, which encodes booleans (and everything else) using lambdas (closures).
(define (kestrel a)
(lambda (b) a))
(define (create-list size proc)
(let loop ((x 0))
(if (= x size)
empty
(cons (proc x)
(loop (add1 x))))))
(create-list 5 identity)
; '(0 1 2 3 4)
(create-list 5 (kestrel 'a))
; '(a a a a a)
In Racket (I'm unsure about Scheme), this procedure is known as const -
(create-list 5 (const 'a))
; '(a a a a a)

Related

When does a program "intertwine definition and use"?

Footnote #28 of SICP says the following:
Embedded definitions must come first in a procedure body. The management is not responsible for the consequences of running programs that intertwine definition and use.
What exactly does this mean? I understand:
"definitions" to be referring to both procedure creations and value assignments.
"a procedure body" to be as defined in section 1.1.4. It's the code that comes after the list of parameters in a procedure's definition.
"Embedded definitions must come first in a procedure body" to mean 'any definitions that are made and used in a procedure's body must come before anything else'.
"intertwine definition and use" to mean 'calling a procedure or assigned value before it has been defined;'
However, this understanding seems to contradict the answers to this question, which has answers that I can summarise as 'the error that your quote is referring to is about using definitions at the start of a procedure's body that rely on definitions that are also at the start of that body'. This has me triply confused:
That interpretation clearly contradicts what I've said above, but seems to have strong evidence - compiler rules - behind it.
SICP seems happy to put definition in a body with other definitions that use them. Just look at the sqrt procedure just above the footnote!
At a glance, it looks to me that the linked question's author's real error was treating num-prod like a value in their definition of num rather than as a procedure. However, the author clearly got it working, so I'm probably wrong.
So what's really going on? Where is the misunderstanding?
In a given procedure's definition / code,
"internal definitions" are forms starting with define.
"a procedure body" is all the other forms after the forms which start with define.
"embedded definitions must come first in a procedure body" means all the internal define forms must go first, then all the other internal forms. Once a non-define internal form appears, there can not appear an internal define form after that.
"no intertwined use" means no use of any name before it's defined. Imagine all internal define forms are gathered into one equivalent letrec, and follow its rules.
Namely, we have,
(define (proc args ...)
;; internal, or "embedded", definitions
(define a1 ...init1...)
(define a2 ...init2...)
......
(define an ...initn...)
;; procedure body
exp1 exp2 .... )
Any ai can be used in any of the initj expressions, but only inside a lambda expression.(*) Otherwise it would refer to the value of ai while aj is being defined, and that is forbidden, because any ai names are considered not yet defined while any of the initj expressions are being evaluated.
(*) Remember that (define (foo x) ...x...) is the same as (define foo (lambda (x) ...x...)). That's why the definitions in that sqrt procedure in the book you mention are OK -- they are all lambda expressions, and any name's use inside a lambda expression will only actually refer to that name's value when the lambda expression's value -- a lambda function -- will be called, not when that lambda expression is being evaluated, producing that lambda function which is its value.
The book is a bit vague at first with the precise semantics of its language but in Scheme the above code is equivalent to
(define proc
(lambda (args ...)
;; internal, or "embedded", definitions
(letrec ( (a1 ...init1...)
(a2 ...init2...)
......
(an ...initn...) )
;; procedure body
exp1 exp2 ....
)))
as can be seen explained, for instance, here, here or here.
For example,
;; or, equivalently,
(define (my-proc x) (define my-proc
(lambda (x)
(define (foo) a) (letrec ( (foo (lambda () a))
(define a x) (a x) )
;; my-proc's body ;; letrec's body
(foo)) (foo))))
first evaluates the lambda expression, (lambda () a), and binds the name foo to the result, a function; that function will refer to the value of a when (foo) will be called, so it's OK that there's a reference to a inside that lambda expression -- because when that lambda expression is evaluated, no value of a is immediately needed, just the reference to its future value, under the name a, is present there; i.e. the value that a will have after all the names in that letrec are initialized, and the body of letrec is entered. Or in other words, when all the internal defines are completed and the body proper of the procedure my-proc is entered.
So we see that foo is defined, but is not used during the initializations; a is defined but is not used during the initializations; thus all is well. But if we had e.g.
(define (my-proc x)
(define (foo) x) ; `foo` is defined as a function
(define a (foo)) ; `foo` is used by being called as a function
a)
then here foo is both defined and used during the initializations of the internal, or "embedded", defines; this is forbidden in Scheme. This is what the book is warning about: the internal definitions are only allowed to define stuff, but its use should be delayed for later, when we're done with the internal defines and enter the full procedure's body.
This is subtle, and as the footnote and the question you reference imply, the subtlties can vary depending on a particular language's implementation.
These issues will be covered in far more detail later in the book (Chapters 3 and 4) and, generally, the text avoids using internal definitions so that these issues can be avoided until they are examined in detail.
A key difference between between the code above the footnote:
(define (sqrt x)
(define (good-enough? guess)
(< (abs (- (square guess) x)) 0.001))
(define (improve guess)
(average guess (/ x guess)))
(define (sqrt-iter guess)
(if (good-enough? guess)
guess
(sqrt-iter (improve guess))))
(sqrt-iter 1.0))
and the code in the other question:
(define (pi-approx n)
(define (square x) (* x x))
(define (num-prod ind) (* (* 2 ind) (* 2 (+ ind 1)))) ; calculates the product in the numerator for a certain term
(define (denom-prod ind) (square (+ (* ind 2 ) 1))) ;Denominator product at index ind
(define num (product num-prod 1 inc n))
(define denom (product denom-prod 1 inc n))
is that all the defintions in former are procedure definitions, whereas num and denom are value defintions. The body of a procedure is not evaluated until that procedures is called. But a value definition is evaluated when the value is assigned.
With a value definiton:
(define sum (add 2 2))
(add 2 2) will evaluated when the definition is evaluated, if so add must already be defined. But with a procedure definition:
(define (sum n m) (add n m))
a procedure object will be assigned to sum but the procedure body is not yet evaluated so add does not need be defined when sum is defined, but must be by the time sum is called:
(sum 2 2)
As I say there is a lot sublty and a lot of variation so I'm not sure if the following is always true for every variation of scheme, but within 'SICP scheme' you can say..
Valid (order of evaluation of defines not significant):
;procedure body
(define (sum m n) (add m n))
(define (add m n) (+ m n))
(sum 2 2)
Also valid:
;procedure body
(define (sum) (add 2 2))
(define (add m n) (+ m n))
(sum)
Usually invalid (order of evaluation of defines is significant):
;procedure body
(define sum (add 2 2))
(define (add m n) (+ m n))
Whether the following is valid depends on the implementation:
;procedure body
(define (add m n) (+ m n))
(define sum (add 2 2))
And finally an example of intertwining definition and use, whether this works also depends on the implementation. IIRC, this would work with Scheme described in Chapter 4 of the book if the scanning out has been implemented.
;procedure body
(sum)
(define (sum) (add 2 2))
(define (add m n) (+ m n))
It is complicated and subtle, but the key points are:
value definitions are evaluated differently from procedure definitions,
behaviour inside blocks may be different from outside blocks,
there is variation between scheme implementations,
the book is designed so you don't have to worry much about this until Chapter 3,
the book will cover this in detail in Chapter 4.
You discovered one of the difficulties of scheme. And of lisp. Due to this kind of chicken and egg issue there is no single lisp, but lots of lisps appeared.
If the binding forms are not present in code in a letrec-logic in R5RS and letrec*-logic in R6RS, the semantics is undefined. Which means, everything depend on the will of the implementor of scheme.
See the paper Fixing Letrec: A Faithful Yet Efficient Implementation of Scheme’s Recursive Binding Construct.
Also, you can read the discussions from the mailing list from 1986, when there was no general consensus among different implementors of scheme.
Also, at MIT there were developed 2 versions of scheme -- the student version and the researchers' development version, and they behaved differently concerning the order of define forms.

Name of this state representation idea without local variables

I know this is maybe an oddball idea, but I thought might as well give it a try to ask here.
I was experimenting in Racket about state representation without local variables.
The idea was defining a function that prints it's parameter value and if called again gives me another value. Since pure functions called with the same parameter always produce the same result, my workaround-idea got me the following.
(define (counter n)
(displayln n)
(λ () (counter (add1 n)))) ; unapplied lambda so it doesn't go in a loop
Then I devised a function to call counter and its resulting lambdas a certain number of times.
(define (call proc n)
(unless (zero? n)
(let ([x (proc)])
(call x (sub1 n)))))
Which results in this:
> (call (counter 0) 5)
0
1
2
3
4
5
What is the name for the concept applied here? Propably it's something trivial what you need in real applications all the time, but since I have no experience in that respect yet so I can't pinpoint a name for it. Or maybe I just complicated something very simple, but nonetheless I would appreciate an answer so I can look further into it.
Sorry if my question is not clear enough, but english is not my first language and to ask about things I have no name for makes me feel kinda uncertain.
You're using closures to save state: a lambda form stores the environment in which it was defined, and you keep redefining the procedure (called x in your code), so each time it "remembers" a new value for n.
Another way to do the same would be to let the procedure itself keep track of the value - in other words, counter should remember the current n value between invocations. This is what I mean:
(define (counter initial)
(let ((n (sub1 initial)))
(lambda ()
(set! n (add1 n))
n)))
In the above code, the first invocation of counter returns a new lambda that closes over n, and each invocation of that lambda modifies n and returns its new value. Equivalently, we could use Racket-specific syntax for currying and the begin0 special form to achieve the same effect:
(define ((counter n))
(begin0
n
(set! n (add1 n))))
Either way, notice how the procedure "remembers" its previous value:
(define proc (counter 0))
(proc)
=> 0
(proc)
=> 1
And we would call it like this:
(define (call proc n)
(unless (zero? n)
(displayln (proc))
(call proc (sub1 n))))
(call (counter 0) 5)
=> 0
1
2
3
4
Also notice that the above fixes an off-by-one error originally in your code - the procedure was being called six times (from 0 to 5) and not five times as intended, that happened because call invokes counter five times, but you called counter one more time outside, when evaluating (counter 0).

Getting elisp to return a function as return value

I'm trying to create a function in elisp that returns another function. I looked at this answer to a similar question (how to return function in elisp) but did not understand the answer (I'm literally just starting learning elisp today, so please excuse my ignorance). I thought a simpler example would help. First, consider a function that test whether a number is divisible by 5:
(defun divisible-by-5 (x)
;; tests whether a number is divsible by 5.
(setq remainder (% x 5))
(if (= remainder 0) 1 0)
)
This works fine:
(divisible-by-5 25)
1
Now suppose I want to create a function that can create more of these kinds of test functions---something like:
(defun divisible-by-z (z)
(lambda (z)
(setq remainder (% x z))
(if (= remainder 0) 1 0))
)
This does not work. E.g.,
(defun divisible-by-3 (divisible-by-z 3))
(divisible-by-3 4)
returns an error. I think even seeing an elisp-idiomatic example of how one would implement this pattern would be helpful.
First, make sure you have lexical-binding enabled. The simplest way to do so is to evaluate (setq lexical-binding t) in your current buffer. More information on the topic can be found here.
Your definition of divisible-by-z is basically correct except that you have a mistype (naming both parameters z; the lambda's parameter should be x). Also, it would be more idiomatic to introduce the binding for remainder with let - setq is generally reserved for mutating bindings that already exist. Here's the result:
(defun divisible-by-z (z)
(lambda (x)
(let ((remainder (% x z)))
(if (= remainder 0) 1 0))))
You can't use defun to create divisible-by-3 in quite the way you've tried - it's expecting the argument list for a new function to be where you have the call to divisible-by-z.
You could either create a global, dynamic binding with
(defvar divisible-by-3 (divisible-by-z 3))
Or a local, lexical binding with
(let ((divisible-by-3 (divisible-by-z 3)))
...)
Either way, you'll then need to use funcall to call the function
(funcall divisible-by-3 9) ; => 1
Of course, you could also skip giving it its own name entirely and simply
(funcall (divisible-by-z 3) 10) ; => 0
funcall is necessary because Emacs Lisp is (basically) a Lisp-2, meaning it can attach both a function and a value to a given symbol. So when you're treating functions as values (returning one from a function or passing one in to a function as a parameter) you essentially have to tell it to look in that value "cell" rather than the usual function cell. If you search for "Lisp-1 vs Lisp-2" you'll find more than you want to know about this.
A possible solution:
(defun divisible-by-3 (x)
(funcall (divisible-by-z 3) x))
Another (perhaps simpler) method is to include x as a variable to be passed to the function:
(defun divisible-by-z (x z) "
Check if x is divisible by z.
If so, return 0.
If not, return the remainder."
(if (% x z) (% x z) 0))
thus:
(divisible-by-z 5 2) --> 1
(divisible-by-z 4 2) --> 0

Why does Scheme allow mutation to closed environment in a closure?

The following Scheme code
(let ((x 1))
(define (f y) (+ x y))
(set! x 2)
(f 3) )
which evaluates to 5 instead of 4. It is surprising considering Scheme promotes static scoping. Allowing subsequent mutation to affect bindings in the closed environment in a closure seems to revert to kinda dynamic scoping. Any specific reason that it is allowed?
EDIT:
I realized the code above is less obvious to reveal the problem I am concerned. I put another code fragment below:
(define x 1)
(define (f y) (+ x y))
(set! x 2)
(f 3) ; evaluates to 5 instead of 4
There are two ideas you are confusing here: scoping and indirection through memory. Lexical scope guarantees you that the reference to x always points to the binding of x in the let binding.
This is not violated in your example. Conceptually, the let binding is actually creating a new location in memory (containing 1) and that location is the value bound to x. When the location is dereferenced, the program looks up the current value at that memory location. When you use set!, it sets the value in memory. Only parties that have access to the location bound to x (via lexical scope) can access or mutate the contents in memory.
In contrast, dynamic scope allows any code to change the value you're referring to in f, regardless of whether you gave access to the location bound to x. For example,
(define f
(let ([x 1])
(define (f y) (+ x y))
(set! x 2)
f))
(let ([x 3]) (f 3))
would return 6 in an imaginary Scheme with dynamic scope.
Allowing such mutation is excellent. It allows you to define objects with internal state, accessible only through pre-arranged means:
(define (adder n)
(let ((x n))
(lambda (y)
(cond ((pair? y) (set! x (car y)))
(else (+ x y))))))
(define f (adder 1))
(f 5) ; 6
(f (list 10))
(f 5) ; 15
There is no way to change that x except through the f function and its established protocols - precisely because of lexical scoping in Scheme.
The x variable refers to a memory cell in the internal environment frame belonging to that let in which the internal lambda is defined - thus returning the combination of lambda and its defining environment, otherwise known as "closure".
And if you do not provide the protocols for mutating this internal variable, nothing can change it, as it is internal and we've long left the defining scope:
(set! x 5) ; WRONG: "x", what "x"? it's inaccessible!
EDIT: your new code, which changes the meaning of your question completely, there's no problem there as well. It is like we are still inside that defining environment, so naturally the internal variable is still accessible.
More problematic is the following
(define x 1)
(define (f y) (+ x y))
(define x 4)
(f 5) ;?? it's 9.
I would expect the second define to not interfere with the first, but R5RS says define is like set! in the top-level.
Closures package their defining environments with them. Top-level environment is always accessible.
The variable x that f refers to, lives in the top-level environment, and hence is accessible from any code in the same scope. That is to say, any code.
No, it is not dynamic scoping. Note that your define here is an internal definition, accessible only to the code inside the let. In specific, f is not defined at the module level. So nothing has leaked out.
Internal definitions are internally implemented as letrec (R5RS) or letrec* (R6RS). So, it's treated the same (if using R6RS semantics) as:
(let ((x 1))
(letrec* ((f (lambda (y) (+ x y))))
(set! x 2)
(f 3)))
My answer is obvious, but I don't think that anyone else has touched upon it, so let me say it: yes, it's scary. What you're really observing here is that mutation makes it very hard to reason about what your program is going to do. Purely functional code--code with no mutation--always produces the same result when called with the same inputs. Code with state and mutation does not have this property. It may be that calling a function twice with the same inputs will produce separate results.

Beginner: Curried functions in Scheme

I'm using the SICP lectures and text to learn about Scheme on my own. I am looking at an exercise that says "An application of an expression E is an expression of the form (E E1,...En). This includes the case n=0, corresponding to an expression (E). A Curried application of E is either an application of E or an application of a Curried application of E."
(Edit: I corrected the above quote ... I'd originally misquoted the definition.)
The task is to define a Curried application of the procedure which evaluates to 3 for
(define foo1
(lambda (x)
(* x x)))
I really don't understand the idea here, and reading the Wikipedia entry on Curriying didn't really help.
Can anyone help with a more lucid explanation of what's being asked for here?
Actually even giving me the answer to this problem would be helpful, since there are five more to solve after this one. ... I just am not getting the basic idea.
Addition: Even after Brian Campbell's lengthy explanation, I'm still somewhat lost.
Is (foo1 (sqrt 3))) considered an application of foo, and therefore a curried application of foo?
Seems too simple, but maybe...
Typing (((foo1 2 )) 2) into DrScheme gives the following error (which I kind of expected)
procedure application: expected procedure, given: 4 (no arguments)
After re-reading What is Currying? I understand I can also re-define foo1 to be:
(define (foo1 a)
(lambda (b)
(* a b)))
So then I can type
((foo1 3 ) 4)
12
But this doesn't really get me any closer to producing 3 as an output, and it seems like this isn't really currying the original foo1, it's just re-defining it.
Damn, 20 years of C programming hasn't prepared me for this. :-) :-)
Hm, this problem is fairly confusingly phrased, compared to the usually much more clear style of the books. Actually, it looks like you might be misquoting the problem set, if you're getting the problem set from here; that could be contributing to your confusion.
I'll break the definition down for you, with some examples that might help you figure out what's going on.
An application of an expression E is an expression of the form (E E1 ... En).
Here's an example of an application:
(foo 1 2) ; This is an application of foo
(bar 1) ; This is an application of bar
This includes the case n=0, corresponding to an expression (E).
(baz) ; This is an application of baz
A Curried application of E is either an application of E or an application of a Curried application of E?...........
This is the one that you misquoted; above is the definition from the problem set that I found online.
There are two halves to this definition. Starting with the first:
A Curried application of E is either an application of E
(foo 1 2) ; (1) A Curried application of foo, since it is an application of foo
(bar 1) ; (2) A Curried application of bar, since it is an application of bar
(baz) ; (3) A Curried application of baz, since it is an application of baz
or an application of a Curried application of E
((foo 1 2) 3) ; (4) A Curried application of foo, since it is an application of (1)
((bar 1)) ; (5) A Curried application of bar, since it is an application of (2)
((baz) 1 2) ; (6) A Curried application of baz, since it is an application of (3)
(((foo 1 2) 3)) ; A Curried application of foo, since it is an application of (4)
(((bar 1)) 2) ; A Curried application of bar, since it is an application of (5)
; etc...
Does that give you the help you need to get started?
edit: Yes, (foo1 (sqrt 3)) is a Curried application of foo1; it is that simple. This is not a very good question, since in many implementations you'll actually get 2.9999999999999996 or something like that; it's not possible to have a value that will return exactly 3, unless your Scheme has some sort of representation of exact algebraic numbers.
Your second example is indeed an error. foo1 returns an integer, which is not valid to apply. It is only some of the later examples for which the recursive case, of an application of an application of the function, are valid. Take a look at foo3, for example.
edit 2: I just checked in SICP, and it looks like the concepts here aren't explained until section 1.3, while this assignment only mentions section 1.1. I would recommend trying to read through section 1.3 if you haven't yet.
See What is 'Currying'?
Currying takes a function and provides
a new function accepting a single
argument, and returning the specified
function with its first argument set
to that argument.
Most of the answers you've gotten are examples of 'partial evaluation'. To do true currying in Scheme you need syntactic help. Like such:
(define-syntax curry
(syntax-rules ()
((_ (a) body ...)
(lambda (a) body ...))
((_ (a b ...) body ...)
(lambda (a) (curry (b ...) body ...)))))
Which you then use as:
> (define adding-n3 (curry (a b c) (+ a b c)))
> (define adding-n2-to-100 (adding-n3 100))
> ((adding-n2-to-100) 1) 10)
111
> (adding-n3 1)
#<procedure>
> ((adding-n3 1) 10)
#<procedure>
I don't think James' curry function is correct - there's a syntax error when I try it in my scheme interpreter.
Here's an implementation of "curry" that I use all the time:
> (define curry (lambda (f . c) (lambda x (apply f (append c x)))))
> ((curry list 5 4) 3 2)
(5 4 3 2)
Notice, it also works for currying more than one argument to a function.
There's also a macro someone has written that let's you write functions that implicitly curry for you when you call them with insufficient arguments: http://www.engr.uconn.edu/~jeffm/Papers/curry.html
I think you are confusing yourself too much. Currying a function takes a function of type F(a1,a2,...aN) and turns it into F(a1) which returns a function that takes a2, (which returns a function that takes a3 ... etc.)
So if you have:
(define F (lambda (a b) (+ a b)))
(F 1 2) ;; ==> 3
you can curry it to make something that acts like the following:
(define F (lambda (a) (lambda (b) (+ a b))))
((F 1) 2) ;; ==> 3
in the case of your specific question, it seems very confusing.
(foo1 (sqrt 3))
seems to be suitable. I would recommend leaving it for now and reading more of the book.
you can actually make a function that does a simple curry for you:
(define (curry f x) (lambda (y) (apply f (cons x y))))
(curry = 0) ;; a function that returns true if input is zero
Depending on your Scheme implementation, there might be some utilities to be able to recover from errors/exceptions, for example, in Chicken Scheme, there is condition-case.
(condition-case (func)
((exn) (print "error")))
We can define a function which take a function of an arbitrary number of elements and return the curryed form :
(define curry
(lambda (func . args)
(condition-case (apply func args)
((exn)
(lambda plus
(apply curry func (append args plus)))))]))))
This is a bit ugly, because if you use too many argument one time, you'll never get the final result, but this turn any function into the curryed form.

Resources