What does the expression (define (f x) (length (range 3000))) evaluate to? - racket

For the expression
(define x (length (range 3000)))
I think it is evaluated to
(define x 3000)
For the expression
(define (f x) (length (range 3000)))
Does it evaluate to the following as well?
(define (f x) 3000)

No, they evaluate to two different procedures, with different bodies. A completely different matter is that when executed, they both will return the same value, namely 3000, ignoring the parameter in both cases. To be clear, the first expression binds f to a lambda (this is how define expands a procedure definition under the hood):
(define f
(lambda (x) (length (range 3000))))
The second expression also binds f to a lambda, but it's a different one:
(define f
(lambda (x) 3000))
Either one will return 3000 when invoked:
(f 42)
=> 3000
But the first one will do more work, it has to create a range and calculate its length, whereas the second one simply returns 3000. Regarding your first example - in the end x will have the same value, and it won't matter how you calculated it. But for the second example, the two fs are different objects, even though the values they calculate are the same.

Related

The Little Typer. I don't understand the meaning of The Initial Second Commandment of λ

I have tried following examples, but no matter y occurred or not,
The function f returns the same value as (λ(y)(f y)) after application.
I would like to do is to define a function that is not the same (-> Y X) as (λ (y)(f y)) when y occurred in y as a counter example, but I don't know how.
Do I misunderstand the meaning of The Initial Second Commandment of λ?
;;y does not occurs
(claim f (-> Nat Nat))
(define f
(λ(y)
0))
;; both return (the Nat 0)
(f 5)
((the (-> Nat Nat)
(λ(y)
(f y)))
5)
;; y occurs
(claim g (-> Nat Nat))
(define g
(λ(y)
y))
;;both return (the Nat 5)
(g 5)
((the (-> Nat Nat)
(λ(y)
(g y)))
5)
In order to create an example illustrating the importance of the caveat "...as long as y does not occur in f", we need to create a function f in which a name y occurs free. The provision that y is free in f is critical. This is also why it is difficult to create such an example: (top-level) functions cannot contain free variables. However, functions that are interior to other functions can. This is the key.
Here is function g that contains another function inside of it:
(claim g (-> Nat
(-> Nat
Nat)))
(define g
(lambda (y)
(lambda (x) ;; Call this inner
y))) ;; function "f"
(I've chosen to write the claim in this way to emphasize that we are thinking about a function inside of a function.)
To get our bearings, this simple function g expects two Nat arguments, and returns the first.
Let's call the inner function f. Note that f contains a free variable y (for this reason, f is meaningless outside of g). Let's substitute (lambda (y) (f y)) for f:
(claim g1 (-> Nat
(-> Nat
Nat)))
(define g1
(lambda (y)
(lambda (y) ;; Here we've replaced "f"
((lambda (x) ;; with an eta-expanded
y) ;; version, introducing
y)))) ;; the name "y"
We can eliminate the application to produce the following expression:
g1
---------------- SAME AS
(lambda (y)
(lambda (y)
((lambda (x)
y)
y)))
---------------- SAME AS
(lambda (y)
(lambda (y)
y))
---------------- SAME AS
(lambda (y)
(lambda (y1)
y1))
In the last step, I've renamed the second y to y1 to illustrate that the variable in the body of the inner function refers to the closer binding site, and not the farther one.
To recap, we started with a function g that "takes two (curried) arguments and returns the first". We then introduced a faulty eta-expansion around the inner function. As a result, we ended up with a function g1 that "takes two (curried) arguments and returns the second". Clearly not equivalent to the original function g.
So this commandment is about variable capture, which is the price we pay for working with names. I hope that helps!
IMPORTANT NOTE:
Due to the way that Pie checks types, you will need to introduce an annotation in the body of g if you want to try this example out:
(claim g1 (-> Nat
(-> Nat
Nat)))
(define g1
(lambda (y)
(lambda (y)
((the (-> Nat Nat)
(lambda (x)
y))
y))))

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)))

Lisp Sum of power

Define a function "power" that takes two input arguments m and n, and returns m^n. Then, by using the function "power", define a function sum_power that takes two input arguments m and n and returns the sum: (1^n + 2^n + 3^n +.... + m^n).
int first function i calculate power from given arguments in second function a sum powers. But program gives error: Program stack overflow. RESET...
I cant find my error. Function power is correct I checked.
(defun power(m n)
(let ((result 1))
(dotimes (count n result)
(setf result (* m result)))))
(defun sum_power (m n)
(if (= 0 m)
0
(+ (powern m)
(sum_power (1- m) n))))
Ok the problem is your function sum_power when you pass the variable m
the expression (- 1 m) is an infinite loop first time because is for example
for m = 5 first time (- 1 m) => -4 (new m = -4) second time (- 1 m)
=> 5 (new m = 5)
begin again so is a recusive infinite loop, you never arrive to 1 so this is teh case of the overflow
Use instead the build function (1- m) which decreases the value of m, or (- m 1) if you want
So the new funtion will be like this, also this is no tail recursion so for big m and n it will take a lot of time, but for your needs it should work, and this function is better formated, please take of fromatting when writing lisp functions for easy reading
(defun sum_power (m n)
(if (= 1 m)
1
(+ (power n m) (sum_power (1- m) n))
You have a argument order mistake in your sum_power function. The stand lisp function - when given two arguments subtracts the second argument from the first argument that is (- 1 m) will subtract m from one and NOT 1 from m as you probably expected thus your result will be a negative integer and your base case (= 1 m) will never be reached. For you code to work correctly you have to swap the arguments to - thus (- m 1) or you can user the lisp function 1- (1- m) which subtracts one from its only argument thus a corrected version of your code is as follows:
(defun sum_power (m n)
(if (= 1 m)
1
(+ (power m n) (sum_power (1- m) n))))
On a non-related side-note lisp allows a lot more characters in function, variable and macro names than most other languages thus you can use sum-power instead of sum_power, in-fact it is arguably better lisp style to use hyphens to join multiple-word identifier names rather than underscores (as used in C) or camel-back casing (sumPower as used in Java). Secondly closing parenthesis usually are not written on a separate line but are on the same line as the last expression before the closing parentheses, as I have done above in the corrected version. These are merely conventions you may follow them if you wish but you're not obliged to.
Why you don't use higher-order functions and loop macro? I think is more readable that way:
(defun power (n m)
(reduce #'* (loop for x below n collect m))
(defun sum-power (n m)
(reduce #'+ (loop for x from 1 to m collect (power x n)))

explanation of lambda expression in scheme

I was wondering if anyone could explain this lambda expression and how the output is derived. I put it into the interpreter and am getting ((2) 2). I'm just not sure why it's giving me that instead of just (2 2).
((lambda x (cons x x)) 2)
The expression (lambda x (cons x x)) produces a function; the function puts all arguments into a list x; the function returns (cons x x).
Your expression calls the above function with an argument of 2. In the function x is (2) (a list of all the arguments). The function (cons '(2) '(2)) returns ((2) 2)
(cons x x)
is not the same as
(list x x)
since it produces dotted pairs, e.g. (cons 2 2) returns (2 . 2).
But when the right side of a dotted pair is a list, the whole thing is a list. (lambda x expr) takes an arbitrary number of arguments, puts them in a list x, so that's (2) here. The dotted pair ((2) . (2)) is printed as ((2) 2) per Lisp conventions.
Yep, you've ran off the deep end of scheme.
You've stublled across the notation that allows you to write a function that accepts zero or more arguments. (any number really)
(define add-nums
(lambda x
(if (null? x)
0
(+ (car x) (apply add-nums (cdr x))))))
(add-nums 1 87 203 87 2 4 5)
;Value: 389
If you just want one argument you need to enclose x in a set of parenthesis.
And you want to use
(list x x)
or
(cons x (cons x '())
as the function body, as a properly formed list will have an empty list in the tail position.
You probably wanted to write:
((lambda (x) (cons x x)) 2)
(note the brackets around x).

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.