"Adding" two functions together in Scheme - function

I am going through a practice exam for my programming languages course. One of the problems states:
Define a function named function+ that “adds” two functions together and returns this composition. For example:
((function+ cube double) 3)
should evaluate to 216, assuming reasonable implementations of the functions cube and double.
I am not sure how to approach this problem. I believe you are supposed to use the functionality of lambdas, but I am not entirely sure.

If you need a procedure which allows you two compose to unary procedures (procedure with only 1 parameter), you'll smack yourself in the head after seeing how simple the implementation is
(define (function+ f g)
(λ (x) (f (g x))))
(define (cube x)
(* x x x))
(define (double x)
(+ x x))
((function+ cube double) 3)
;=> 216

Basically if you need to do that you just do (x (y args ...)) so if you need to have a procedure that takes two arguments proc1 and proc2 returns a lambda that takes any number of arguments. You just use apply to give proc1 arguments as a list and pass the result to proc2. It would look something like this:
(define (compose-two proc2 proc1)
(lambda args
...))
The general compose is slightly more complicated as it takes any number of arguments:
#!r6rs
(import (rnrs))
(define my-compose
(let* ((apply-1
(lambda (proc value)
(proc value)))
(gen
(lambda (procs)
(let ((initial (car procs))
(additional (cdr procs)))
(lambda args
(fold-left apply-1
(apply initial args)
additional))))))
(lambda procs
(cond ((null? procs) values)
((null? (cdr procs)) (car procs))
(else (gen (reverse procs)))))))
(define (add1 x) (+ x 1))
((my-compose) 1) ;==> 1
((my-compose +) 1 2 3) ; ==> 6
((my-compose sqrt add1 +) 9 15) ; ==> 5

Related

How to recreate apply in scheme

how would i create the function apply in scheme?
A my-apply function that does the same thing as it.
(define (my-apply fn lst)
(if (null? lst)
I'm not sure where to go from here or how to start.
I think apply is "more fundamental" than eval, so the following is cheating:
(define (my-apply func args)
(eval `(,func ,#args)))
I don't think you can do it without eval.
I created a lisp interpreter a while back and it has eval and macros, but it didn't have apply. I wondered if there was a way I could make my interpreter support apply so made an effort to try this. Here is my first attempt:
(define (my-apply proc args)
(eval (cons proc args)))
This clearly doesn't work since the function and the list of arguments gets evaluated twice. eg. (my-apply cons '(a b)) will give you (cons a b) and not (cons 'a 'b). I then thought that this might be a job for a macro but threw the idea away since the list of arguments are not known at macro expansion time. Procedure it needs to be so I though I could quote the list before I pass it to eval.
(define (my-apply proc args)
(define (q v)
(list 'quote v))
(eval (cons proc (map q args))))
This actually works, but this does a lot more work than a native apply would do to undo the job eval does.
If you are not allowed to use eval you are truely out of luck. It cannot be done. The same goes for implementing eval without using apply since then you have no way of doing primitives.
(define (my-two-arg-apply f a)
(let ((l (length a)))
(cond ((= l 0) (f))
((= l 1) (f (car a)))
((= l 2) (f (car a) (cadr a))
...
((= l 5) (f (car a) (cadr a) ... (caddddr a)))
...
((= l 7) (f (car a) (cadr a) ... (caddddr a)
(list-ref a 5) (list-ref a 6)))
... ;; lots more cases
(else (error "argument passing limit exceeded")))))
A macro could be used to generate the large quantity of code needed.
error was introduced in R6RS. Amazingly, Scheme programs had no reasonable way to report errors before that.
Don't even think about making a pop macro and using the pattern (f (pop a) (pop a) ... (pop a)); Scheme doesn't have a defined evaluation order for function arguments unlike some other Lisp dialects like ANSI CL.

Scheme function that return composition of functions

How to realize a function that takes as input an any number of procedures with one argument and returns another function is the composition of these procedures in Scheme.
For example:
(define (f x) (* x 2))
(define (g x) (* x 3))
(define (h x) (- x))
((comp-func f g h) 1) => -6
((comp-func f g) 1) => 6
((comp-func h) 1) => -1
((comp-func) 1) => 1
As written, the question is ambiguous, because we can't tell in which order you're composing the functions. That is, we can't tell whether
((comp-func f g h) 1) computes (f (g (h 1))) or (h (g (f 1))), since both would work out to -6 in this case.
That said, this problem can be solved by a (left to right) fold a.k.a. reduction; once you know how to compose two functions, you can reduce that binary composition over a list of functions.
First, composing two functions is easy:
(define (compose2 f g)
;; Returns a function that computes (g (f x)).
(lambda (x)
(g (f x))))
Now, to reduce (a.k.a. fold left to right) a function f over a list (x1 x2 ... xn) with an initial value i means computing
(f ... (f (f (f i x1) x2) x3 ...) xn)
(by definition). Composing a list of functions (f1 f2 f3 f4) is then just folding the compose2 function with an initial value that is the identity function.
(define (identity x)
x)
(define (compose . functions)
(reduce compose2 identity functions))
reduce is a built-in function that does the (left to right) folding.
I'll use some functions where the order matters, so that we can see the difference in results:
(define (f x) (* x x))
(define (g x) (+ x 3))
(display ((compose f g) 3))
;=> 12 == (g (f 3)) == (3^2)+3
(display ((compose g f) 3))
;=> 36 == (f (g 3)) == (3+3)^2
A clean solution would be
(define (comp-func . procs)
(define (comp-rec arg procs)
(if (null? procs)
arg
((car procs) (comp-rec arg (cdr procs)))))
comp-rec)
However with this solution you need to call it like this ((comp-func f g h) 1 (list f g h)).
Here is a solution that will work if you call it like in your examples, however it is a bit uglier because we need to use set! to change procs argument.
(define (comp-func . procs)
(define (comp-rec arg)
(if (null? procs)
arg
(let ((proc (car procs))
(rest (cdr procs)))
(set! procs rest)
(proc (comp-rec arg)))))
comp-rec)
In addition to #Kevin's nice recursive solution, I would like to add that there's no need to use set!. Inside comp-func you can simply return a lambda function that calls comp-rec with the list of procedures as the extra argument.
(define (comp-func . procs)
(define (comp-rec arg procs)
(if (null? procs)
arg
((car procs) (comp-rec arg (cdr procs)))))
(lambda (arg) (comp-rec arg procs )))
No need for any intermediate define or let or set or what ever.
We stay pure functional and need no variables.
(define (comp-func . procs)
(lambda (arg)
(if (null? procs)
arg
((car procs) ((apply comp-func (cdr procs)) arg)))))

Lisp Anonymous Function Local Variable

How do I assign anonymous functions to local variables in either cl, emacs lisp or clojure?
I've tried the following with no success.
(let ((y (lambda (x) (* x x)) )) (y 2))
and
((lambda (x) 10) (lambda (y) (* y y)))
In CL, you could use flet or labels.
(defun do-stuff (n)
(flet ((double (x) (* 2 x)))
(double n)))
(do-stuff 123) ;; = 246
As Chris points out, since double is not recursive, we should use flet, as the difference between the two is that labels can handle recursive functions.
Check out docs for info on labels, or this question for the difference between labels and flet.

Creating a Function that produces a Function Scheme/DrRacket

I'm working on a function that takes in a list of structures and then using that list of structures produces a function that processes a list of symbols into a number. Each structure is made up of a symbol, that will be in the second list consumed, and a number. This function produced has to turn the list of symbols into a number by assigning each symbol a value based on the previous structures. Using abstract list functions btw.
Example: ((function (list (make-value 'value1 10) (make-value 'value2 20)))
(list 'value1 'value2 'nothing 'value1)) would produced 40.
Heres my code but it only works for specific cases.
(define (function lst)
(lambda (x) (foldr + 0 (map (lambda (x)
(cond
[(equal? x (value-name(first lst)))(value-value (first lst))]
[else (value-value (second lst))]))
(filter (lambda (x) (member? x (map value-name lst)))x)))))
Looks like a homework. Basic shape of your solution is ok. I think the reason you have a problem here is that there is no decomposition in your code so it's easy to get lost in parentheses.
Let's start with your idea of fold-ing with + over list of integers as a last step of computation.
For this subtask you have:
1) a list of (name, value) pairs
2) a list of names
and you need to get a list of values. Write a separate function which does exactly that and use it. Like this
(define (function lst)
(lambda (x) (foldr +
0
(to-values x lst)))
(define (to-values names names-to-values)
(map (lambda (name)
(to-value name names-to-values))))
(define (to-value n ns-to-vs)
...)
Here we map over the names with another little function. It will lookup the n value in ns-to-vs and return it or 0 if there is no one.
There are two approaches for solving the problem with foldr, it'd be interesting to study and understand both of them. The first one, attempted in the question, is to first produce a list with all the values and let foldr take care of adding them. It can be implemented in a simpler way like this:
(define (function lst)
(lambda (x)
(foldr +
0
(map (lambda (e)
(cond ((assoc e lst) => value-value)
(else 0)))
x))))
Alternatively: maybe using foldr is overkill, applying + is simpler:
(define (function lst)
(lambda (x)
(apply +
(map (lambda (e)
(cond ((assoc e lst) => value-value)
(else 0)))
x))))
In the second approach we take the input list "as is" and let foldr's lambda perform the addition logic. This is more efficient than the first approach using foldr, because there's no need to create an intermediate list - the one generated by map in the first version:
(define (function lst)
(lambda (x)
(foldr (lambda (e a)
(cond ((assoc e lst) => (lambda (p) (+ a (value-value p))))
(else a)))
0
x)))
In both approaches I'm using assoc for finding the element in the list; it's easy to implement as a helper function if you're not allowed to use it or if it doesn't work for the values created with make-value: assoc takes a list of name-value pairs and returns the first pair with the given name. The => syntax of cond passes the pair returned by assoc to a lambda's parameter and executes it.
And because you're using Racket, there's a bit of syntactic sugar that can be used for returning a function from another function, try this equivalent code, for simplicity's sake:
(define ((function lst) x)
(foldr +
0
(map (lambda (e)
(cond ((assoc e lst) => value-value)
(else 0)))
x)))
Or this:
(define ((function lst) x)
(foldr (lambda (e a)
(cond ((assoc e lst) => (lambda (p) (+ a (value-value p))))
(else a)))
0
x))
Anyway, the result is as expected:
((function (list (make-value 'value1 10) (make-value 'value2 20)))
(list 'value1 'value2 'nothing 'value1))
=> 40

Calling a Scheme function using its name from a list

Is it possible to call a Scheme function using only the function name that is available say as a string in a list?
Example
(define (somefunc x y)
(+ (* 2 (expt x 2)) (* 3 y) 1))
(define func-names (list "somefunc"))
And then call the somefunc with (car func-names).
In many Scheme implementations, you can use the eval function:
((eval (string->symbol (car func-names))) arg1 arg2 ...)
You generally don't really want to do that, however. If possible, put the functions themselves into the list and call them:
(define funcs (list somefunc ...))
;; Then:
((car funcs) arg1 arg2 ...)
Addendum
As the commenters have pointed out, if you actually want to map strings to functions, you need to do that manually. Since a function is an object like any other, you can simply build a dictionary for this purpose, such as an association list or a hash table. For example:
(define (f1 x y)
(+ (* 2 (expt x 2)) (* 3 y) 1))
(define (f2 x y)
(+ (* x y) 1))
(define named-functions
(list (cons "one" f1)
(cons "two" f2)
(cons "three" (lambda (x y) (/ (f1 x y) (f2 x y))))
(cons "plus" +)))
(define (name->function name)
(let ((p (assoc name named-functions)))
(if p
(cdr p)
(error "Function not found"))))
;; Use it like this:
((name->function "three") 4 5)