I have just start to pick up scheme and figuring out its ins and outs. I was trying to work out some practice problems and I came across this one. With my-counter defined, I thought calling my-counter would return 1, but instead it's returning <#Closure>. I understand to some extent what closures are and thought that count belongs to let, so it would return 1, but I supposed I overlooked something.
(define my-counter
(let ((count 0))
(lambda ()
(set! count (+ count 1))
count)))
my-counter returns a procedure. You need to call that procedure to get the next value.
(define counter-1 (my-counter))
(define counter-2 (my-counter))
(write (counter-1))
(write (counter-1))
(write (counter-2))
Related
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)
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).
In my OO World, I have an instance of "weapon" class called "max-damage". I asked to create a random number for a variable called "damage".
It says: The amount of "damage" suffered should be a random integer no more than the "max-damage", and at least 1.
I need some help to create that random integer, thanks!
PS: I can't ask more questions, in order to ask this question, I have changed the previous one, sorry..
You got the syntax of filter wrong, it's necessary that you pass a procedure as the first argument. Concretely, the procedure is a predicate (meaning: it evaluates to a boolean value), and the output list will only keep the elements in the original list that evaluate to #t when passed to the procedure. This is what I mean:
(define (remove-divisible lst value)
(filter (lambda (x) (not (zero? (remainder x value))))
lst))
If using a lambda bothers you, it's always possible to define a helper procedure, like this:
(define (remove-divisible lst value)
(define (not-divisible? x)
(not (zero? (remainder x value))))
(filter not-divisible? lst))
I'm new to Scheme and trying to understand how certain values that appear within a function can persist across multiple uses. Take the following counter:
(define count
(let ((next 0))
(lambda ()
(let ((v next))
(set! next (+ next 1))
v))))
What I can't figure out (and haven't found explained anywhere), is why next doesn't get reset to 0 every time count is used.
This is called a closure. There's only one version of next in the whole program.
To make this clearer, consider the following program:
(define next 0)
(define count
(lambda ()
(let ((v next))
(set! next (+ next 1))
v))))
Now it's clear that there's only one next.
The version you wrote is different, because you've used let to make sure that only the lambda expression can see next. But there's still only one next. If you changed it to this, instead:
(define count
(lambda ()
(let ((next 0))
(let ((v next))
(set! next (+ next 1))
v))))
Then you would create a new version of next every time, because the declaration of next is inside the lambda, which means that it happens every time that lambda is called.
I have one thing to add to Sam's excellent answer: your question suggests that this behavior might have something to do with "let". It does not. Here's an example that does a similar thing without a "let" in it:
#lang racket
(define (make-counter-from counter)
(lambda ()
(set! counter (+ counter 1))
counter))
(define count (make-counter-from 9))
(count)
(count)
The moral (if there is one): Yes! Mutation is confusing!
EDIT: Based on your comment below, it sounds like you really are looking for some insight into what kind of mental model you can use for a language with mutation.
In a language with mutation of local variables, you can't use the simple "substitution" model that replaces arguments with values. Instead, each call to a function creates a new "binding" that can later be updated (a.k.a. "mutated").
So, in my code above, calling "make-counter-from" with 9 creates a new binding that associates the "counter" variable with the value 9. This binding is then attached/substituted-for all uses of the "counter" variable in the body of the function, including those inside of the lambda. The result of the function is then a lambda (a function) that is "closed over" two references to this newly created binding. You can think of these as two references to a heap-allocated object, if you like. This means that every call to the resulting function results in two accesses to this object/heap-thing.
I don't totally agree with your explanation. You're right in that the function's definition is evaluated only once, but the function itself is evaluated every time it is called.
The point I don't agree with is the "...rewrites the definition...", because the function is defined only once (and not explicitly overwritten).
I imagine it the following way: Due to the so-called lexical binding of variables in scheme, the scheme interpreter notices during the evaluation of the function definition that there's a variable defined in the environment of the function definition - the variable "next". Therefore it remembers not only the function definition, but the value of the variable "next", too (this means that it stores two things - the function definition and the enclosing environment). When the function in called for the first time, its definition is evaluated by the scheme interpreter within the stored environment (in which the variable "next" has the value 0, and were the value is incremented). The second time the function is called, exactly the same things happen - the same function definition is evaluated in its enclosing environment. This time, however, the environment provides the value 1 for the variable "next" and the result of the function call is 1.
To phrase is concisely: The function (definition) stays the same, it's the evaluation environment that changes.
To directly answer your question, "next doesn't get reset to 0 every time count is used" because your code
(define count (let ((next 0))
(lambda ()
(let ((v next))
(set! next (+ next 1))
v))))
is equivalent to
(define count #f)
(set! count ( (lambda (next) ; close over `next`
(lambda () ; and then return lambda which _will_
(let ((v next)) ; read from `next`,
(set! next (+ v 1)) ; write new value to `next`,
v))) ; and then return the previous value;
0 )) ; `next` is initially 0
(this is "let-over-lambda" pattern; there's even a Lisp book by that name).
The value to assign count is "calculated" only once. This value is a closure referring to the binding for next, which (binding) is external to it (the closure). Then every time count is "used", i.e. a procedure that it refers to is called, it (the procedure) refers to that binding: first it reads from it, then it alters its contents. But it doesn't re-set it to its initial value; the binding is initiated only once, as part of its creation, which happens when the closure is created.
This binding is visible only from this procedure. The closure is a bundle of this procedure and the environment frame holding this binding. This closure is the result of evaluating the (lambda () ...) expression inside the lexical scope of next, the (lambda (next) ...) expression.
Ok, I've had something of an epiphany. I believe my confusion relates to the distinction between a definition and a procedure (lambda): Definitions occur once, while procedures evaluate each time they are run. In the original function, let defines a procedure with next set to zero. That definition happens one time, but using set! within the procedure rewrites the definition as if retroactively. Thus, each use of count produces a new version of the function in which next has been incremented.
Please correct me if this is totally off-base.
Here is a program that does precisely the same thing.
(define count
(local ((define next 0)
(define (inc)
(local ((define v next))
(begin
(set! next (+ next 1))
v))))
inc))
(count) 0
(count) 1
(count) 2 .........
Maybe your let/set sequence follows the same mechanism. The procedure that you are actually calling is inc, not count. The inc procedure increments next every time. An equivalent definition can be
(define next 0)
(define (inc)
(begin
(set! next (+ next 1))
(- next 1)))
(define count inc)
(count) 0
(count) 1
(count) 2......
So, I guess calling count in the first program is just like running the entire second program. I don't know. I too am new to scheme. Thanks, for the useful post.
I have tried to write a procedure that gets an integer as parameter and returns true if the number is a palindrome and false otherwise and it seems to be that there is a problem with changing a global parameter's value whithin an internal function block.
(define index 0)
(define (palindrome? x)
(if (= (lenght x) 1)
#t
(if (last_equal_first x)
(palindrome? (remove x))
#f)))
(define (lenght x)
(define index **(+ index 1))**
(if (= (modulo x (ten_power index)) x)
index
(lenght x)))
(define (last_equal_first x)
(if (= (modulo x 10) (modulo x (/ (ten_power (lenght x)) 10)))
#t
#f))
I would like to know what can I do about it
thanks!
Well, one problem is that you're redefining index after it's been used, in the length function. define doesn't really do what you want here - you want set!.
However, I think you'll find another bug when you try to call the length function more than once - you never set index to 0 after the first time, so I believe your length function will only work once.
However, this seems like it might be a homework assignment. Would you like clear instructions on fixing these problems, or would you like clues that lead you to understand the algorithm more?
What that (define ...) statement does in lenght is create a new variable called "index" that is more locally scoped than the "index" you defined at the top. That's only the superficial problem---more importantly, it looks like you're trying to write C code using Scheme. In a simple homework assignment like this, you should not need to use global variables, nor should you ever have to change a variable once it's created. Many programmers have trouble shifting how they think when first learning functional programming.
The way you've written lenght is not so much recursion as just a glorified while loop! There is no point to recursion if (lenght x) only calls (lenght x) again. For example, here's how I would write digits to count how many base-10 digits are in a number:
(define digits
(lambda (n)
(letrec ([digit-helper (lambda (n index)
(if (= (modulo n (expt 10 index)) n)
index
(digit-helper n (add1 index))))])
(digit-helper n 0))))
Notice how I never change a variable once it's been created, but only create new variables each time. Since I need to keep track of index, I created helper function digit-helper that takes two arguments to mask the fact that digit only takes one argument.