Can someone help explain this scheme procedure - lisp

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?

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.

Macros for generating functions

I'm trying to write some macros for constraint programming on integers and specifically I'm trying to expand
(int-constr (x y z)
(< 10
(+
(* x 4)
(* y 5)
(* z 6)))
(> 10
(+
(* x 1)
(* y 2)
(* z 3))))
into
(let ((x (in-between 0 1))
(y (in-between 0 1))
(z (in-between 0 1)))
(assert
(and (< 10
(+
(* x 4)
(* y 5)
(* z 6)))
(> 10
(+
(* x 1)
(* y 2)
(* z 3)))))
(list x y z))
When using syntax-rules recursively, I can create nested let at the beginning, but I think I lose the possibility of calling the list of arguments at the end. Is there any way to do it?
Even just sticking to syntax-rules, this macro is easy to write by using ellipses. Here’s an implementation of the behavior you describe:
(define-syntax int-constr
(syntax-rules ()
((_ (x ...) constr ...)
(let ((x (in-between 0 1)) ...)
(assert (and constr ...))
(list x ...)))))
Since ellipses can be used to repeat forms containing pattern variables, not just repeat plain pattern variables on their own, this macro is quite declarative, and it’s both simple to read and write.

Lisp Illegal argument in functor position

Hello can anyone help me out?
(defun f(x)
(LIST ((* 2 x) (* 3 x)))
)
(f 1)
I get this, Illegal argument in functor position: (* 2 X) in ((* 2 X) (* 3 X)).
It should be:
(defun f (x)
(list (* 2 x) (* 3 x)))
You have an extra set of parentheses around the arguments to list. When an expression is a list, the first thing is supposed to be the function to call, so
((* 2 x) (* 3 x))
is not a valid expression because (* 2 x) is not a function.

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