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

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

Related

Closure inside a Common Lisp Macro

In the following code how can i have the x and y variables to reflect the expressions given at macro call time?
(defmacro defrule (init-form &rest replication-patterns)
(let (rule-table)
`(destructuring-bind (p x y) ',init-form
#'(lambda (w h) (list x y)))))
When expanding a call like:
(defrule (70 (* 1/2 w) (+ h 3)))
it returns:
(DESTRUCTURING-BIND (P X Y) '(70 (* 1/2 W) (+ H 3))
#'(LAMBDA (W H) (LIST X Y)))
where the original expressions with W and H references are lost. I tried back-quoting the lambda function creation:
(defmacro defrule (init-form &rest replication-patterns)
(let (rule-table)
`(destructuring-bind (p x y) ',init-form
`#'(lambda (w h) (list ,x ,y)))))
But a same call:
(defrule (70 (* 1/2 w) (+ h 3)))
expands to:
(DESTRUCTURING-BIND
(P X Y)
'(70 (* 1/2 W) (+ H 3))
`#'(LAMBDA (W H) (LIST ,X ,Y)))
which returns a CONS:
#'(LAMBDA (W H) (LIST (* 1/2 W) (+ H 3)))
which can not be used by funcall and passed around like a function object easily. How can i return a function object with expressions i pass in as arguments for the x y part of the init-form with possible W H references being visible by the closure function?
You're getting a cons because you have the backquotes nested.
You don't need backquote around destructuring-bind, because you're destructuring at macro expansion time, and you can do the destructuring directly in the macro lambda list.
(defmacro defrule ((p x y) &rest replication-patterns)
(let (rule-table)
`#'(lambda (w h) (list ,x ,y))))
Looking at your code:
(defmacro defrule (init-form &rest replication-patterns)
(let (rule-table)
`(destructuring-bind (p x y) ',init-form
#'(lambda (w h) (list x y)))))
You want a macro, which expands into code, which then at runtime takes code and returns a closure?
That's probably not a good idea.
Keep in mind: it's the macro, which should manipulate code at macro-expansion time. At runtime, the code should be fixed. See Barmar's explanation how to improve your code.

Defining a let macro scope in emacs lisp

In emacs lisp (but answers relating to common lisp are also welcome) I have a library that uses a macro and I want to hijack one of the macro's arguments only when executed in a certain context. Essentially what I want is a macro:
; My macro. This is a sketch of what I want that doesn't work.
(defmacro hijack-f (body)
`(macrolet ((f (x) `(f (+ 1 ,x))))
,#body))
; Defined in the library, I don't want to deal with these
(defmacro f (x) x)
(defun g (x) (f x))
So that
(g 1) ; => 1
(hijack-f (g 1)) ; => 2
(hijack-f (hijack-f (g 1))) ; => 3
EDIT: #melpomene and #reiner-joswig correctly point out that f is expanded in g before hijack-f. As a followup is there a hijack-f such that:
(f 1) ; => 1
(hijack-f (f 1)) ; => 2
(hijack-f (hijack-f (f 1))) ; => 3
As far as I know, what you want is not possible because g does not contain an invocation of f. Instead f runs first and expands to (part of) the definition of g.
That is:
(defun g (x) (f x))
immediately turns into
(defun g (x) x)
Which then defines g as a function (whose value is (lambda (x) x)).
Messing with f at runtime doesn't affect anything because its invocation is long gone by the time you call g.
If you are happy for your f to be a function and not a macro, and to use CL not elisp, then you are after flet and a macro like this:
(defmacro hijack-f (&body body)
`(flet ((f (x)
(f (1+ x))))
,#body))
Given a global defintion of f:
(defun f (x)
x)
Then
> (hijack-f (f 1))
2
> (hijack-f (hijack-f (f 1)))
3
And so on.
(As others have pointed out, you can't hijack code that has already been compiled with a macro like this: you would need to do it by having f cooperate in the hijacking.)

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.

Can someone help explain this scheme procedure

Question:
((lambda (x y) (x y)) (lambda (x) (* x x)) (* 3 3))
This was #1 on the midterm, I put "81 9" he thought I forgot to cross one out lawl, so I cross out 81, and he goes aww. Anyways, I dont understand why it's 81.
I understand why (lambda (x) (* x x)) (* 3 3) = 81, but the first lambda I dont understand what the x and y values are there, and what the [body] (x y) does.
So I was hoping someone could explain to me why the first part doesn't seem like it does anything.
This needs some indentation to clarify
((lambda (x y) (x y))
(lambda (x) (* x x))
(* 3 3))
(lambda (x y) (x y)); call x with y as only parameter.
(lambda (x) (* x x)); evaluate to the square of its parameter.
(* 3 3); evaluate to 9
So the whole thing means: "call the square function with the 9 as parameter".
EDIT: The same thing could be written as
((lambda (x) (* x x))
(* 3 3))
I guess the intent of the exercise is to highlight how evaluating a scheme form involves an implicit function application.
Let's look at this again...
((lambda (x y) (x y)) (lambda (x) (* x x)) (* 3 3))
To evaluate a form we evaluate each part of it in turn. We have three elements in our form. This one is on the first (function) position:
(lambda (x y) (x y))
This is a second element of a form and a first argument to the function:
(lambda (x) (* x x))
Last element of the form, so a second argument to the function.
(* 3 3)
Order of evaluation doesn't matter in this case, so let's just start from the left.
(lambda (x y) (x y))
Lambda creates a function, so this evaluates to a function that takes two arguments, x and y, and then applies x to y (in other words, calls x with a single argument y). Let's call this call-1.
(lambda (x) (* x x))
This evaluates to a function that takes a single argument and returns a square of this argument. So we can just call this square.
(* 3 3)
This obviously evaluates to 9.
OK, so after this first run of evaluation we have:
(call-1 square 9)
To evaluate this, we call call-1 with two arguments, square and 9. Applying call-1 gives us:
(square 9)
Since that's what call-1 does - it calls its first argument with its second argument. Now, square of 9 is 81, which is the value of the whole expression.
Perhaps translating that code to Common Lisp helps clarify its behaviour:
((lambda (x y) (funcall x y)) (lambda (x) (* x x)) (* 3 3))
Or even more explicitly:
(funcall (lambda (x y) (funcall x y))
(lambda (x) (* x x))
(* 3 3))
Indeed, that first lambda doesn't do anything useful, since it boils down to:
(funcall (lambda (x) (* x x)) (* 3 3))
which equals
(let ((x (* 3 3)))
(* x x))
equals
(let ((x 9))
(* x x))
equals
(* 9 9)
equals 81.
The answers posted so far are good, so rather than duplicating what they already said, perhaps here is another way you could look at the program:
(define (square x) (* x x))
(define (call-with arg fun) (fun arg))
(call-with (* 3 3) square)
Does it still look strange?

How would I express this Scheme function more clearly?

(define (repeated f n)
if (= n 0)
f
((compose repeated f) (lambda (x) (- n 1))))
I wrote this function, but how would I express this more clearly, using simple recursion with repeated?
I'm sorry, I forgot to define my compose function.
(define (compose f g) (lambda (x) (f (g x))))
And the function takes as inputs a procedure that computes f and a positive integer n and returns the procedure that computes the nth repeated application of f.
I'm assuming that (repeated f 3) should return a function g(x)=f(f(f(x))). If that's not what you want, please clarify. Anyways, that definition of repeated can be written as follows:
(define (repeated f n)
(lambda (x)
(if (= n 0)
x
((repeated f (- n 1)) (f x)))))
(define (square x)
(* x x))
(define y (repeated square 3))
(y 2) ; returns 256, which is (square (square (square 2)))
(define (repeated f n)
(lambda (x)
(let recur ((x x) (n n))
(if (= n 0)
args
(recur (f x) (sub1 n))))))
Write the function the way you normally would, except that the arguments are passed in two stages. It might be even clearer to define repeated this way:
(define repeated (lambda (f n) (lambda (x)
(define (recur x n)
(if (= n 0)
x
(recur (f x) (sub1 n))))
(recur x n))))
You don't have to use a 'let-loop' this way, and the lambdas make it obvious that you expect your arguments in two stages.
(Note:recur is not built in to Scheme as it is in Clojure, I just like the name)
> (define foonly (repeat sub1 10))
> (foonly 11)
1
> (foonly 9)
-1
The cool functional feature you want here is currying, not composition. Here's the Haskell with implicit currying:
repeated _ 0 x = x
repeated f n x = repeated f (pred n) (f x)
I hope this isn't a homework problem.
What is your function trying to do, just out of curiosity? Is it to run f, n times? If so, you can do this.
(define (repeated f n)
(for-each (lambda (i) (f)) (iota n)))