Clojure first and rest - function

Why do I get 2 different values for
(apply (first '(+ 1 2)) (rest '(+ 1 2)))
> 2
and
(apply + '(1 2))
> 3
when
(first '(+ 1 2))
> +
and
(rest '(+ 1 2))
> (1 2)
I tried reduce and got the same value
(reduce (first '(+ 1 2)) (rest '(+ 1 2)))
> 2

Your trouble is that you're trying to call the symbol '+ rather than the function +. When you call a symbol, it tries to look up the symbol in the first argument (for example, if it had been {'a 1 '+ 5 'b 2} you would have gotten 5). If you pass a second argument, that value gets returned instead of nil if the symbol can't be found in the first argument. So when you call ('+ 1 2), it tries to look up '+ in 1 and fails, so it returns 2.
Incidentally, this is the difference between creating lists with '(+ 1 2) and (list + 1 2). The former creates a list of the symbols +, 1 and 2. Since '1 and 1 are the same, that's fine. But the symbol '+ is not the Var clojure.core/+, so the latter gets the value of the Var while the former just gets the symbol. So if you'd done (list + 1 2), your could would have worked as written.

(first '(+ 1 2)) is a symbol.
user=> (class (first '(+ 1 2)))
clojure.lang.Symbol
user=> (apply (symbol "+") [1 2])
2
user=> (apply (eval (symbol "+")) [1 2])
3
user=> (apply (eval (first '(+ 1 2))) (rest '(+ 1 2)))
3
user=> (class (first [+ 1 2]))
clojure.core$_PLUS_
user=> (apply (first [+ 1 2]) (rest '(+ 1 2)))
3

Related

&rest in common lisp

I am confused as to what &rest does in common lisp.
This could be an example to represent what I mean :
(defmacro switch (value &rest pairs)
....
)
What exactly does the &rest and pairs mean?
The last parameter in a function (or macro) definition can be preceded by &rest. In this case, when the function (or the macro) is called, all the arguments not bound to the previous parameters are collected into a list which is bound to that last parameter. This is a way of providing an unspecified number of arguments to a function or a macro.
For instance:
CL-USER> (defun f (a &rest b)
(list a (mapcar #'1+ b)))
F
CL-USER> (f 1 2 3 4 5)
(1 (3 4 5 6))
CL-USER> (f 1)
(1 NIL)
CL-USER> (f 1 2 3)
(1 (3 4))
CL-USER> (defmacro m (f g &rest pairs)
(let ((operations (mapcar (lambda (pair) (list g (first pair) (second pair))) pairs)))
`(,f (list ,#operations))))
M
CL-USER> (macroexpand-1 '(m print + (1 2) (3 4) (5 6)))
(PRINT (LIST (+ 1 2) (+ 3 4) (+ 5 6)))
T
CL-USER> (m print + (1 2) (3 4) (5 6))
(3 7 11)
Note that, if the are no remaining arguments, the list passed to the last parameter is empty.

Why is the parameter for my procedure getting a 'not a function' error?

I am going through the book Structure and Interpretation of Computer Programming, which uses Scheme, and I just got through a portion on recursion. I wrote a program for exercise 1.11:
A function f is defined by the rule that f(n) = n if n<3 and f(n) = f(n - 1) + 2f(n - 2) + 3f(n - 3) if n> 3. Write a procedure that computes f by means of a recursive process. Write a procedure that computes f by means of an iterative process.
I wrote the code at repl.it and when I run the procdure with the input 2, it gives me the error: Error: 2 is not a function [fRecurse, (anon)]. Can somebody explain to me what this means and how I can fix it? Why is it expecting my input to be a function?
Code:
(define (fRecurse n)(
(cond ((< n 3) n)
((>= n 3)
(+ (procRecurse (- n 1))
(* 2 (f (- fRecurse 2)))
(* 3 (f (- fRecurse 3))))))))
(fRecurse 2)
The error is due to an extra pair of parentheses before (cond...). To fix the issue, we simply remove the extra pair of parentheses:
(define (fRecurse n)
(cond ((< n 3) n)
((>= n 3)
(+ (fRecurse (- n 1))
(* 2 (fRecurse (- n 2)))
(* 3 (fRecurse (- n 3)))))))
(fRecurse 2)
And some additonal fixes I made to your example to make it work correctly:
Change f to fRecurse
Change procRecurse to fRecurse
Change (* 2 (f (- fRecurse 2))) to (* 2 (fRecurse (- n 2)))
Change (* 3 (f (- fRecurse 3))) to (* 3 (fRecurse (- n 3)))
See the updated repl.it

Recursive functions in clojure

How does this recursive function work step by step:
(fn foo [n]
(if (< n 10)
[n]
(conj (foo (quot n 10))
(mod n 10))))
I have problem with understanding: lets say i give it as n the number 123, and it will return a vector of its digits. At the last step when arrived to 1 and (< 1 10) it should go to the then-part [n], return [1] and come out of the recursion. So this doesn't happen, what am i missing in the play?
At the last step when arrived to 1 and (< 1 10) it does go to the then-part [n], return [1], but it does NOT come out of the recursion, only out of the innermost invocation.
The evaluation goes as follows:
(foo 123)
(conj (foo 12) 3)
(conj (conj (foo 1) 2) 3)
(conj (conj [1] 2) 3)
(conj [1 2] 3)
[1 2 3]

Scheme - have a function return a value from another function for each member of a list

I am trying to write a function that returns a value for each element of a list but algebraic operation will be implemented on another funtcion. This is my first step:
(define (base list another-fun)
;every member of the list will be
send to enother-fun and all return as a value )
(define (funk a) (lambda (c) (* a c)
))
(define (funkc a) (lambda (c) (- a c)
))
Here's my input:
(define base '(1 2 3 4 5) (funk 2)) => (1 2 3 4 5 6) not '(1 2 3 4 5 6)
(define base '(1 2 3 4 5) (funkc 1)) => (1 2 3 4 5 6) not '(0 1 2 3 4 5)
The function that you're trying to implement is called map, and it's a standard built-in procedure in Scheme. Try this:
(define (funk a)
(lambda (c) (* a c)))
(define (funkc a)
(lambda (c) (- a c)))
(map (funk 2) '(1 2 3 4 5))
=> '(2 4 6 8 10)
(map (funkc 1) '(1 2 3 4 5))
=> '(0 -1 -2 -3 -4)
Here's a link to the SICP book, explaining how to implement your own version of map in case you want to write it from scratch.

Multiplying 2 lists in Lisp

I have a function that takes 2 lists as input and I would like to make it so that everything in the first list, is multiplied with everything in the second list, and then the sum is calculated.
Here's my function so far:
(defun multiply(a b)
(if (eq a nil)
0
(progn
(* (car a) (car b))
(multiply (car a) (cdr b)))
))
Currently all I'm trying to get it to do is take the first number from the first list, and multiply one by with everything in the second list. However I get this error from when the function is re-called within the function:
(This is what I inputted, '(1 2 3) and '(4 5 6))
The value 1 is not of type list.
(MULTIPLY 1 '(5 6))
Any help would be much appreciated.
Is loop acceptable?
Case 1
If the result should be 90 as in
(+ (* 1 4) (* 1 5) (* 1 6) (* 2 4) (* 2 5) (* 2 6) (* 3 4) (* 3 5) (* 3 6))
then you could do
(defun multiply (a b)
(loop for i in a
sum (loop for j in b
sum (* i j))))
Case 2
If the result is supposed to be 32 as in
(+ (* 1 4) (* 2 5) (* 3 6))
then it would be
(defun multiply (a b)
(loop
for i in a
for j in b
sum (* i j)))
If you want to multiply two lists per element, you should just be able to use mapcar:
(mapcar #'* '(3 4 5) '(4 5 6))
As to the error in your existing function, this line should be:
...
(multiply (cdr a) (cdr b)))
...
What you describe sounds like the dot product:
(defun dot (l1 l2)
(reduce #'+ (mapcar #'* l1 l2)))
The above solution is nice because it is purely functional, but, alas, it creates an unnecessary intermediate list. Of course, a Sufficiently Smart Compiler should be able to eliminate that, but, practically speaking, you are better off using loop:
(defun dot (l1 l2)
(loop for x in l1 and y in l2 sum (* x y)))
Note also that using lists to represent mathematical vectors is not a very good idea, use vectors instead.
I would modify multiply as
(defun multiply(a b)
(if (eq a nil)
0
(+
(* (car a) (car b))
(multiply (cdr a) (cdr b)))))
When you call
(multiply '(1 2 3) '(4 5 6))
it will return the sum
32
(define (*2Ls L1 L2)
(apply map * (list L1 L2)))