Cannot understand output in the second case - racket

(define c
(let ((d 10))
(set! d (- d 2))
d))
(define c1
(let ((d 10))
(lambda (p)
(set! d (- d p))
d)))
Now for c c the output is 8 8.
But for (c1 2) (c1 2) the output is 8 6. Why is that so?
I think I need an insight to how function calls are actually evaluated.
According to me, the evaluation should be as, (in the second case) for the first call, a local environment for function c1 is created where the value of d is 10 and then the procedure evaluation takes place normally. Then as soon as this call ends the whole environment is destroyed and for the second call the same whole process (as above) occurs. So the second output value should also be 8. But it is 6, why is that so?

Are you thinking this:
(define c1
(let ((d 10))
(lambda (p)
(set! d (- d p))
d)))
It is exactly the same as:
(define c1
(lambda (p)
(let ((d 10))
(set! d (- d p))
d)))
It is not. In the first the variable d is created before the lambda and thus it is the same free variable for each and every invocation of c1. Thus changing d alters next call.
The second one creates d at invocation and it gets destroyed when the call is finished.
In the first Scheme evaluates the let form. It creates d and then evaluates the lambda so d becomes a free variable in its closure that is returned. The define syntax then creates a global variable c1 with that resulting closure value. The let is out of scope, but d doesn't get garbage collected since it is still referenced by one value, the closure.

A let can be rewritten as an immediate application of a lambda abstraction
(mylet ([var rhs] ...) body ...) => ((lambda (var ...) body ...) rhs ...)
De-sugaring c's let yields
(define c ((lambda (d) (set! d (- d 2)) d) 10))
Which is just an application of 10 onto a function (which we call f)
(define f (lambda (d) (set! d (- d 2)) d))
(define c
(f 10))
c
c
As for c1, we have nested lambdas
(define f1 (lambda (d) (lambda (p) (set! d (- d p)) d)))
((f1 10) 2)
((f1 10) 2)
8 and 8. (Which is what you expected). But really, what's happening is
(define c1
(f1 10))
(c1 2)
(c1 2)
returns 8 and 6
The d gets memoized (here is an example of fibonacci using the same wrapping of a memoize procedure and set!).
Moreover, for set!, you can't have naive substitution. The racket's evaluation model explains how "a new location is created for each variable on each application":
Since the value associated with argument variable x can be changed,
the value cannot be substituted for x when the procedure is first
applied.
tl;dr evaluation of c1 yields a lambda that closes over pending substitution (environment). Which is then mutated by set! on each call.

Related

How do I append a list recursively in common lisp?

(defun foo (in i out)
(if (>= i 0)
(progn
(append (list (intern (string (elt in i)))) out)
(print output)
(foo in (- i 1) out )
)
(out)
)
)
(print (foo "abcd" (- (length "abcd") 1) (list)))
I am trying to return this string as (a b c d). But it does return nil as output. What do I do wrong here? Thanks
I don’t know what this has to do with appending. I think your desired output is also weird and you shouldn’t do what you’re doing. The right object for a character is a character not a symbol. Nevertheless, a good way to get the list (a b c d) is as follows:
CL-USER> '(a b c d)
Interning symbols at runtime is weird so maybe you would like this:
(defconstant +alphabet+ #(a b c d e f g h i j k l m n o p q r s t u v w x y z))
(defun foo (seq)
(map 'list
(lambda (char)
(let ((index (- (char-code char) (char-code #\a))))
(if (< -1 index (length +alphabet+))
(svref +alphabet+ index)
(error "not in alphabet: ~c" char))))
seq))
You have just some minor mistakes. First, we need to get rid of output and (output); these bear no relation to the code. It seems you were working with a variable called output and then renamed it to out without fixing all the code. Moreover, (output) is a function call; it expects a function called output to exist.
Secondly, the result of append must be captured somehow; in the progn you're just discarding it. Here is a working version:
(defun foo (in i out)
(if (>= i 0)
(foo in (1- i) (cons (intern (string (elt in i))) out))
out))
Note also that instead of your (append (list X) Y), I'm using the more efficient and idiomatic (cons X Y). The result of this cons operation has to be passed to foo. The out argument is our accumulator that is threaded through the tail recursion; it holds how much of the list we have so far.
I.e. we can't have (progn <make-new-list> (foo ... <old-list>)); that just creates the new list and throws it away, and then just passes the old list to the recursive call. Since the old list initially comes as nil, we just keep passing along this nil and when the index hits zero, that's what pops out. We need (foo .... <make-new-list>), which is what I've done.
Tests:
[1]> (foo "" -1 nil)
NIL
[2]> (foo "a" 0 nil)
(|a|)
[3]> (foo "ab" 1 nil)
(|a| |b|)
[4]> (foo "abcd" 3 nil)
(|a| |b| |c| |d|)
[5]> (foo "abcd" 3 '(x y z))
(|a| |b| |c| |d| X Y Z)
Lastly, if you want the (|a| |b| |c| |d|) symbols to appear as (a b c d), you have to fiddle withreadtable-case.
Of course:
[6]> (foo "ABCD" 3 nil)
(A B C D)

Lisp function to return a number double and then the same number doubled plus one

I am totally new to lisp and have no idea how I'll create this function.
This is the pseudo code I created to help me solve it
Binary tree children
; This function returns the children of binary tree node
; e.g., 3 -> (6,7)
; e.g., 11 -> (22,23)
(defun tree-node(x))
The function is intended to take in a number, double it, and then double it and add 1. Please help.
To double a number (which is stored in a variable named n here): (* 2 n).
To add one: (1+ n). Note that 1+ is the name of a function. It is the same as (+ n 1).
Now, let's say that you have some scope (e. g. a function body) where you have a variable named n. You now create a new variable d using let:
(let ((d (* n 2)))
…)
This new variable is in scope for the body of the let (indicated by … above).
Now we create another variable d1, which is one more. We need to use let* now, so that the scope of d is not just the body, but also the binding forms of the let*:
(let* ((d (* n 2))
(d1 (+ d 1)))
…)
The function should maybe be called child-indices:
(defun child-indices (n)
(let* ((d (* n 2))
(d1 (+ d 1)))
…))
The bodies of many forms like defun and let are so-called implicit progns, which means that these forms return the value of the last expression in their body. So, whatever forms we put into the place marked … above, the value (or values, but let's keep that aside for now) of the last is the return value of the function.
There are several ways to do a “return this and then that”, but we'll use a list for now:
(defun child-indices (n)
(let* ((d (* n 2))
(d1 (+ d 1)))
(list d d1)))

Count elements and return them

I want to count the elements in a list and return a list containing the elements paired with them respective quantity
Something like that:
Input:
(count-elements '(a b d d a b c c b d d))
Output:
((a 2) (b 3) (d 4) (c 2))
How can I do it? I'm not having any success trying to pair the element and its accounting
Your problem can be divided into three broad parts:
Duplicate recognition/ deletion : This can be done by either removing all the duplicates of every element, or by knowing that the current element is a duplicate(and thus not counting it as a new element.). This(the former strategy) can be done by using the function remove-duplicates
Counting: A way to actually count the elements. This can be done by the function count
Combination: A way to combine the results into a list. This can be done by the macro push.
The Code:
(defun count-elements (lst)
(loop for i in (remove-duplicates lst)
with ans = nil
do (push (list i (count i lst)) ans)
finally (return ans)))
CL-USER> (count-elements '(a a b c))
((C 1) (B 1) (A 2))
CL-USER> (count-elements '(a b c d d a b s a c d))
((D 3) (C 2) (A 3) (S 1) (B 2))
CL-USER>
NOTE: The result might not be arranged as you would expect, because of the value returned by remove-duplicates
EDIT: As pointed out by coredump, a better version of count-elements would be:
(defun count-elements (lst)
(map 'list
(lambda (e)
(list e (count e lst)))
(remove-duplicates lst)))
which, instead of using loop, uses map.

Understanding objects with local state -- Scheme

i'm studying for my scheme final and objects with local state has always been a tough subject.
Here is a question from my final exam that i need help on.
(define (make-incrementer n)
(let ((old 0)
(new 0))
(lambda ()
(cond ((< new n)
(set! old new)
(set! new (+ new 1))
old)
(else
(set! old 0)
(set! new 1)
old)))))
(define a (make-incrementer 3))
(define b (make-incrementer 3))
(define c a)
; 1) (a)
; 2) (a)
why when a is called the second time it returns 1? I'm looking at the code and the n we give it is always 3. So wouldn't it always do the else case?
Welcome to the wonderful world of closures! This is a textbook example of how closures in Scheme work.
So make-counter returns a function that has 3 variables that it captures from it's enclosing environment: n, old, new. In this case, the starting environment looks something like
_name_|_value_
n | 3
old | 0
new | 1
On each invocation, it increments old and new and wraps them around if they're greater than n. Because it's using set!, this incrementing is mutating the variables in the lambda's environment, but since these variables are captured from the surrounding environment, they are changed for all future calls as well.
That's why you get different returns even with the same input.
If this seems like witchcraft, you can think of it like objects in more common languages:
Eg Python:
class Foo():
def __init__(self, n, m):
self.n = n
self.m = m
def count(self):
self.n += 1
if self.n == self.m:
self.n = 1
return self.n-1
f = Foo(0, 2)
f.count() # 1
f.count() # 0
This is the same basic idea except here we're being a bit more explicit about where the environment is coming from, self. In Scheme, we mimic this with the lambda capturing the surrounding variables.
For more, check out SICP
Here are some examples, that might help with the concept of capturing state:
(define (always x)
(lambda rest x))
(define always-true (always #t))
(always-true #f)
-> #t
(define (add-n n)
(lambda (m)
(+ n m)))
(define add-1 (add-n 1))
(add-1 10)
-> 11
(define (complement predicate)
(lambda (x)
(not (predicate x)))
(define not-positive? (complement positive?))
(not-positive? -1)
-> #t
Next is an example where the captured state, in this case l, is mutated. This is similar to your case where new and old are captures and modified.
(define (nexting l)
(lambda ()
(if (null? l)
'()
(let ((answer (car l)))
(set! l (cdr l))
answer))))
(define next-user (nexting '(Alice Bob David)))
(next-user)
-> Alice
(next-user)
-> Bob
(next-user)
-> David
(next-user)
'()

LISP SICP Video Lecture 2a Average Damp Question

In the following code, I am trying to understand how the variable whatami gets its value. In following the logic, I see that the procedure (lambda (y) (/ x y)) is the parameter that I am passing to the method average-damp, and is represented within that method as the variable f. It seems as though (/ x y) and (average (f whatami) whatami) need to be executed, but I can't figure out the order of execution. Any help is appreciated.
(define (average x y)
(/ (+ x y) 2))
(define (fixed-point f start)
(define tolerance 0.00001)
(define (close-enuf? u v)
(< (abs (- u v)) tolerance))
(define (iter old new)
(if (close-enuf? old new)
new
(iter new (f new))))
(iter start (f start)))
(define average-damp
(lambda (f)
(lambda (whatami) (average (f whatami) whatami))))
; square root with average damping
(define (_sqrt x)
(fixed-point
(average-damp (lambda (y) (/ x y)))
1))
(_sqrt 4.0)
The average-damp procedure takes a procedure as its argument and returns a procedure as its value. When given a procedure that takes one argument, average-damp returns another procedure that computes the average of the values before and after applying the original function f to its argument. It's inside the fixed-point procedure where that returned function is applied (iteratively).
So the average-damp procedure doesn't execute either (/ x y) or (average(f whatami) whatami) at all, it just uses the function passed to it to create a new function that it returns.