Calling lambda function directly - function

(define a1 (list 1 2 3 4))
(define a2 (list + - * /))
(define a3 (list 5 6 7 8))
(map (lambda (x y z) (y x z))
a1 a2 a3)
How do I call this lambda function directly without using map?
All it does is switching y and x, so that (1 + 5) becomes (+ 1 5)

You can write you map expression without switching the arguments:
(map (lambda (x y z) (x y z)) a2 a1 a3) ; ==> (6 -4 21 1/2)
Notice I have just switched the order of the arguments to map.
You can call a lambda by wrapping it in parenthesis and adding arguments.. eg.
((lambda (op1 proc op2) (proc op1 op2)) + 2 3) ; ==> 5
The map function is just a way of doing that with every element of the different lists. You can get the same result without using lambda if you know the length of the lists:
(list ((car a2) (car a1) (car a3))
((cadr a2) (cadr a1) (cadr a3))
((caddr a2) (caddr a1) (caddr a3))
((cadddr a2) (cadddr a1) (cadddr a3))) ; ==> (6 -4 21 1/2)
Since every element of a2 is a procedure wrapping it and arguments in parenthesis applies the procedure.
A lambda form (lambda (arg ...) body ...) gets evaluated and turns into a procedure object. When you define named procedure the same happens but the name gets bound to that procedure object. In fact. there is not difference between these 3 versions:
;; version 1 using syntactic sugar define for procedures
(define (test x) (* x x))
(test 10) ;==> 100
;; version 2 defineing a variable to a procedure
(define test (lambda (x) (* x x)))
(test 10) ;==> 100
;; version 3 using the procdure directly
((lambda (x) (* x x)) 10) ; ==> 100

As you probably know, to call a function in Scheme you write (f args), where f is the function and args is the list of arguments. This isn't any different whether f is a named function or a lambda. So to call your lambda function directly, you'd write:
;( -----------f------------ args- )
( (lambda (x y z) (y x z)) 1 + 2 )
Of course that's just a rather convoluted way of writing (+ 1 2), but there you go.

Related

A helpfunction as parameter?

I dont know how to fix one of my problems.
I have programmed two helpfunction for my main function but it wont work.
;;Main function
(define (FunctionA a b c)
(/(-(* -1 b) VariableD)aNotNull))
(check-expect (FunctionA 1 1 1)-1)
;;Helpfunction1:
(define (VariableD a b c)
(if (> 0(-(* b b)(* 4 (* a c)))) (error "No negative numbers allowed")
(sqrt(-(* b b)(* 4 (* a c))))))
(check-expect (VariableD 0 0 0) 0)
(check-error (VariableD 1 2 3) "No negative numbers allowed")
;helpfunction2:
(define (aNotNull a)
(if (= 0 (* 2 a)) (error "Zerodivisor not allowed")
(* 2 a)))
(check-error (aNotNull 0 ) "Zerodivisor not allowed")
(check-expect(aNotNull 2) 4)
I get the error: expects a number as 2nd argument, given (lambda (a1 a2 a3) ...)
But I dont know how to fix it.
Hope you can help me out :)
(define (FunctionA a b c)
(/ (- (* -1 b) VariableD) aNotNull))
VariableD here refers to the function you defined. You probably want to instead call the function with the a, b and c inputs from FunctionA, and use the result in FunctionA.
The same goes for your usage of aNotNull. I'm just inferring that these are the variables you'll want to pass to these functions in this revised FunctionA:
(define (FunctionA a b c)
(/ (- (* -1 b)
(VariableD a b c))
(aNotNull a)))

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

Scheme - Passing too much arguments into a function doesn't cause error?

Given the following code :
(define (g x y) (* x y))
(define (f x y z)
(define (h x y)(g (+ x y) x z))h)
Notice that I pass 3 arguments into g ,where g accepts only 2 .
However ,no error message is presented from the interpreter , why ?
Regards
You aren't actually calling h here, only returning it. Properly formatted your code should look like:
(define (f x y z)
(define (h x y)
(g (+ x y) x z))
h)
So when you call (f 1 2 3) you get back h. If you call
((f 1 2 3) 1 2)
then the interpreter will give an error.

Using abstract list functions to iterate over a list of functions in Scheme

How can I write a function max-list-function that consumes a list of functions, then produces a function f such that for every x, (f x) produces the maximum value of all the functions g in the list of functions?
For example (max-list-function (lambda (n) (+ n 4)) (lambda (n) (- 15 n))))
produces a function such that (f 2) returns 13 and (f 10) returns 14.
This is to be done with abstract list functions (filter, foldr, map, ...) without recursion.
Try this:
(define (max-list-function flist)
(lambda (n)
(foldr max -inf.0
(map (lambda (f) (f n))
flist))))
Use it like this:
(define f (max-list-function
(list (lambda (n) (+ n 4)) (lambda (n) (- 15 n)))))
(f 2)
> 13.0
(f 10)
> 14.0

Scheme - define variable as the result of a function?

The beginning of one of my programs results in an error. This is the problem area. I am trying to define a variable as the result of a recursive function.
(define (test n)
(define (a1func i)
(if (= i 1) 0
(+ (/ 1 i) (a1func (- i 1)))))
(define a1 (a1func (- n 1))))
if you were to give it say (test 10) the error would be:
procedure application: expected procedure, given: #<undefined>; arguments were: 9
I assumed this could be done in Scheme?? ideas?
In pure FP languages computations are done passing parameters to functions, which return some values as a result. You could bind the result of test in the function which called test:
(define (test n)
(define (a1func i)
(if (= i 1) 0
(+ (/ 1 i) (a1func (- i 1)))))
(a1func (- n 1)))
(define (calltest x)
(define (r (test (+ 2 x))))
(- r 4))
Variables usually bound once and cannot be changed. A function must return the value, a result of expression, but (define a1 (a1func(- n 1))) is rather a definition, not an expression, so the correct code would be:
(define (test n)
(define (a1func i)
(if (= i 1) 0
(+(/ 1 i) (a1func(- i 1)))))
(define a1 (a1func(- n 1)))
a1)
And since defining variable and immediate returning it is meaningless, a more correct code would be:
(define (test n)
(define (a1func i)
(if (= i 1) 0
(+(/ 1 i) (a1func(- i 1)))))
(a1func(- n 1)))
If your scheme implementation support lisp macros then you can write this:
(define-macro (test n)
(define (a1func i)
(if (= i 1) 0
(+ (/ 1 i) (a1func (- i 1)))))
`(define a1 ,(a1func (- n 1))))
or using named let
(define-macro (test n)
`(define a1 ,(let a1func ((i (- n 1)))
(if (= i 1)
0
(+ (/ 1 i) (a1func (- i 1)))))))