Understanding a macro - macros

As I understand the macro written below; The macro takes 3 arguments and produces a struct with a constructor which accepts 3 arguments. I can guess that the line immediately following the macro definition creates a struct which looks like:
(struct x (+ y x))
I am lost in understanding how the two lines which follow that work. It appears that y is bound to an x struct, but isn't it calling the constructor with one too many arguments?
(define-syntax binary-search
(syntax-rules ()
[(binary-search (node left right))
(struct left (node right x))]))
(binary-search (+ x y))
(define y (x 1 2 3))
(+ (x-+ y) (x-x y))
I won't be a bother and ask how the last line works, hopefully clarification on the y variable will lead me to the given answer of 4.

What's confusing here is that a field name can be the same as the struct name.
Consider this example:
#lang racket
(struct foo (foo) #:transparent)
(foo 42) ; => (foo 32)
(foo-foo (foo 42)) ; => 32
So (binary-search (+ x y)) results in:
(struct x (+ y x))
which defines an x struct that has a named also named x.
The line
(define y (x 1 2 3))
makes an x-struct where:
the + field stores 1,
the y field stores 2,
the x field stores 3.
Now (x-+ y) gets the + field of y, which is 1
and (x-x y) gets the x field of y which is 3.
This means that (+ (x-+ y) (x-x y)) evaluates to 4.

Related

Unused Lexical Variable

Just started learning lisp. I have no idea why I am getting these errors or even what they mean. I am simply trying to code an approximation of pi using the Gregory-Leibniz series, here is the code.
(defun gl (n)
(defparameter x 0) ;init variable to hold our runnning sum
(loop for y from 0 to n ;number of iterations, starting from 0 to desired n
(if (= y 0) ;if n is 0 then we just want 4
(defparameter w 4))
(if (> y 0) ;else, 4*(-1^y)/((2 * y)+1)
(defparameter w (* 4 (/ (exp -1 y) (+ (* 2 y) 1)))))
(+ x w)) ;add to our running sum
(write x)) ;once loop is over, print x.
I have tried using setq, defvar, let etc. instead of defparameter but I still get "Undeclared free variable X".
I also get the error "Unused lexical variable N" even though I am using it for my loop, which is weird also.
How can I fix this and why is it happening? Thanks!
Here is the code after Emacs auto-indented it:
(defun gl (n)
(defparameter x 0)
(loop for y from 0 to n
(if (= y 0)
(defparameter w 4))
(if (> y 0)
(defparameter w (* 4 (/ (exp -1 y) (+ (* 2 y) 1)))))
(+ x w))
(write x))
Compiling the following code with SBCL gives one error and two warnings.
One warning says that x is undefined.
You should not call defparameter from inside your function, since defvar and defparameter are used to declare dynamic variables and to set their value in the global scope. Prefer to have let bindings, or, since you already are using a loop, a with clause. When you want to modify a binding, use setf.
The errors comes from the macroexpansion of LOOP, which is malformed. For SBCL, that means that the code is treated as dead-code for the rest of the function compilation; that explains why n appears not to be used, which is what the second warning is about.
There are various fixes remaining to be done:
Use function EXPT, not EXP.
Calling (+ x w) only computes a value but does not modify x, the result is useless.
Prefer using if as expression, like a ternary operator in other languages, in your case the code can be simplified
Adding one can be done with function 1+ (that's the name of the function, not a special syntax for adding constants)
The write operation is rarely needed, especially if you are computing a mathematical formula; just return the value, and the REPL will print it automatically.
Small corrections that make your code works:
(defun gl (n)
(let ((x 0))
(loop
for y from 0 to n
for w = (if (= y 0)
4
(* 4 (/ (expt -1 y) (+ (* 2 y) 1))))
do (setf x (+ x w)))
(write x)))
I would personally get rid of x and w, and use a SUM loop clause.
(defun gl (n)
(loop
for y from 0 to n
sum (if (zerop y)
4
(* 4 (/ (expt -1 y)
(1+ (* 2 y)))))))

lisp - should be a lambda expression

I'm trying to return (values str ((+ x 3) y)) from the function it resides in.
code snippet:
(if (<my condition>)
(values str ((+ x 3) y))
(values str ((+ x 2) y)))
gives error:
(+ X 3) SHOULD BE A LAMBDA EXPRESSION
but (values str (y (+ x 3))) works fine.
why?
The S-expression ((+ x 3) y) cannot be evaluated because the first list element is not funcallable (it should name a function or be a lambda expression).
So, to avoid evaluation, you need to quote it:
(if (<my condition>)
(values str '((+ x 3) y))
(values str '((+ x 2) y)))
Then you will return a list of length 2 (containing a list of length 3 and a symbol y) as your second value. If, however, you want to return the values of (+ x 2) and y in the list, you will want to do something like
(values str (list (+ x (if <condition> 3 2)) y))
or maybe return 3 values instead of 2:
(values str
(+ x (if <condition> 3 2))
y)
On the other hand, y is a symbol, which, apparently, names a function in your image, so (y (+ x 3)) evaluates fine (it calls function y on the result of adding 3 to x).

Lisp function call syntax

I am trying to write a recursive code to do x^y but the problem no mater how I update the code it gives me an error.
The Code:
(defun power(x y) (if(> y 0) (* x (power(x (- y 1)))) (1)))
Error:
CL-USER 11 : 5 >Power 2 3
Error: Undefined operator X in form (X (- Y 1)).
Error:
CL-USER 11 : 5 >power(2 3)
Illegal argument in functor position: 2 in (2 3).
You're calling the function in the wrong way. In lisps function calls have the form:
(f a b c)
not
f(a b c)
You had (power (x (- y 1))) in your recursive definition, which in turn had (x (- y 1)) hence the error: x is not a function.
Use (power x (- y 1)) so your definition becomes:
(defun power (x y)
(if (> y 0)
(* x
(power x (- y 1)))
1))
and call it as (power 2 3)
To expand slightly on the previous (correct) answer, this version uses some idiomatic functions:
(defun power (x y)
(if (plusp y)
(* x (power x (1- y)))
1))
You cannot use parenthesis for grouping since CL thinks you want to call function x and function 1. Remove the excess like this:
(defun power(x y)
(if (> y 0)
(* x (power x (- y 1)))
1))
Parenthesis goes on the outside, just as in your function:
(power 2 3) ;==> 8
When you write (X ...) in a Lisp expression, you are asserting that X is a function to be called on the arguments ....
Your problem is you have too many parentheses in your expression. When you write (power (x ..
you've made this assertion. Write (power x ... instead.
You're calling, among others, this code:
(power (x (- y 1)))
So power is called with (x (- y 1)) as a parameter. Are you sure you want to call x as a function?

Deconstructing a recursive process - SICP

Consider the following definition:
(define foo
(lambda (x y)
(if (= x y)
0
(+ x (foo (+ x 1) y)))))
What is the test expression? (write the actual expression, not its value)
I would think it is just (if (= x y) but the MIT 6.001 On Line Tutor is not accepting that answer.
The test would be:
(= x y)
That's the expression that actually returns a boolean value, and the behaviour of the if conditional expression depends on it - if it's #t (or in general: any non-false value) the consequent part will be executed: 0. Only if it's #f the alternative part will be executed: (+ x (foo (+ x 1) y)).

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?