Today i am reading the book "A Gentle Introduction to Symbolic Computation", and i got to the exercise 4.29.
Here how it sounds like: "Write versions of LOGICAL-AND using IF and COND instead of AND."
Here how it was defined in the original text:
(defun logical-and (x y) (and x y t))
That is how i defined it with cond and if:
(defun logical-and (x y)
(cond ((and x y) t)
(t nil)))
(defun logical-and (x y)
(if (and x y) t nil))
And that is how they are defined in the answers to the exercises
(defun logical-and (x y)
(cond (x (cond (y t)))))
(defun logical-and (x y)
(if x (if y t)))
So the question is are all these definitions equal?
All three cases are identitical in behaviour. Specifically the function returns the symbol t if x and y are both non-nil, and nil otherwise.
In the definition in the text, it simply uses the and operator with t as it's last argument. This works because if either x or y are nil then, and short circuits and returns nil, however if both x and y are true, then and returns the result of the last expressions, which is t.
In your cond definition, if both x and y are true, the first clause matches, returning t, and in all other cases (i.e. either x or y is false) nil is returned.
Your if definition works similarly, returning t if and only if both x and y are true, and nil otherwise.
The answers to the exercise work because cond returns nil if no clause matches and if returns nil if the conditional is false and no else clause is specified. Therefore the cond definition returns t only if both conditions are satisfied (i.e. x is true and y is true), and the if defintion is t only if both if conditions are true, and if not nil is returned.
Related
CL-USER> (a-sum 0 3)
->> 6
I wrote this program :
(defun a-sum (x y)
(if (and (> x -1) (> y -1))
(do ((i 0 (1+ i))
(sum 0)
(num x))
((equal i (+ (- y x) 1)))
(setq sum (+ sum num))
(setq num (+ num 1))
sum)
(print " NOPE")))
put if I run it in the terminal it returns nil and not the answer stated above;
can someone help with the problem so it returns the value then Boolean.
DO,DO* Syntax
The entry for DO,DO* says that the syntax is as follows:
do ({var | (var [init-form [step-form]])}*)
(end-test-form result-form*)
declaration*
{tag | statement}*
The body is used as a list of statements and no intermediate value in this body is used as the result form of the do form. Instead, the do form evaluates as the last expression in result-form*, which defaults to nil.
(do ((i 0 (1+ i))
(sum 0)
(num x))
((equal i (+ (- y x) 1))
;;; RESULT FORMS HERE
)
(setq sum (+ sum num)) ;; (*)
(setq num (+ num 1)) ;; (*)
sum ;; (*)
)
All the expressions marked commented (*) above are used for side-effects only: the result of their evaluation is unused and discarded.
Problem statement
It is not clear to me what Σpi=ni means, and your code does not seem to compute something that could be expressed as that mathematical expression.
One red flag for example is that if (+ (- y x) 1) is negative (i.e. if y < x-1, for example y=1,x=3), then your loop never terminates because i, which is positive or null, will never be equal to the other term which is negative.
I would try to rewrite the problem statement more clearly, and maybe try first a recursive version of your algorithm (whichever is easier to express).
Remarks
Please indent/format your code.
Instead of adding setq statements in the body, try to see if you can define them in the iteration clauses of the loop (since I'm not sure what you are trying to achieve, the following example is only a rewrite of your code):
(do ((i 0 (1+ i))
(sum 0 (+ sum num)
(num x (1+ num))
(... sum))
Consider what value(s) a function returns. It's the value of the last form evaluated. In your case, that appears to be a do or maybe a setq or print (It's difficult to read as it's formatted now, and I don't have question edit privileges).
In short, the form that's returning the value for the function looks to be one evaluated for side-effects instead of returning a value.
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.
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)).
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).
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?