Scheme function that return composition of functions - function

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

Related

Squaring all the elements in a list by Scheme

I wanted to square all elements in a list by the Scheme programming language.
my code is:
(define (square n) (* n *n))
(define (fun items factor)
(if (null? items)
0
(cons (* (fun (car items)
factor))
(fun (cdr items)
factor) ) ) ) )
(display (fun '( 1 2 3 4) square))
I'm showing these errors:
ERROR: In procedure car:
ERROR: In procedure car:
Wrong type (expecting pair): 1
You have a couple of errors:
The square procedure has an extra * that shouldn't be there
If we're building a list as output, then the base case should return the empty list '(), not 0.
The part where you operate on the current element of the list is incorrect, you should simply call the factor procedure on the car of the list, and there's no need to multiply again, square will take care of that.
This should fix them:
(define (square n) (* n n))
(define (fun items factor)
(if (null? items)
'()
(cons (factor (car items))
(fun (cdr items) factor))))
In real life, you don't need to implement this procedure yourself, map is already built-in and it's as simple to use as this:
(map square '(1 2 3 4))
=> '(1 4 9 16)
Here is other method:
(define factor-list
(lambda (l factor return)
(if (null? l)
(return '())
(factor-list (cdr l)
factor
(lambda (rest)
(return (cons (factor (car l))
rest)))))))
(define input '(1 2 3 4))
(factor-list input (lambda (x) (* x x)) (lambda (x) x))
Tail recursive implementation of map (to not to overwrite built-in map I called it *map).
(define (square x) (* x x))
(define (*map func lst (acc '()))
"Apply func on each element of the list."
(cond ((null? lst) (reverse acc))
(else (*map func (cdr lst) (cons (func (car lst)) acc)))))
Run it by:
(*map square '(1 2 3)) ;; '(1 4 9)

Combining two functions in Scheme

I have the filter-function and the reverse-function done out in my own code
(define reverse_
(lambda (xs)
(if (null? xs)
xs
(append (reverse_ (cdr xs))
(list (car xs))))))
and
(define filter_
(lambda (p? xs)
(if (null? xs)
xs
(append (if (p? (car xs))
(list (car xs))
(list))
(filter_ p? (cdr xs))))))
I want to combine the two functions into the (reverse-filter) function i.e you could type (reverse-filter symbol? '(1 2 3 a b c)) and it would return -> c b a.
It works now by simply typing (reverse_ (filter_ symbol? '(1 2 3 a b c))) -> c b a but I just want to combine the two.
Any help on doing this in the general case and in this specific one would be much appreciated
For the general case, we can use the curry and compose procedures (which hopefully are available in your interpreter), they allow us to manipulate other procedures:
((compose (curry filter_ symbol?) reverse_)
'(1 2 3 a b c))
=> '(c b a)
For illustrative purposes, here's a naive implementation of both procedures, to understand what they're doing under the hood:
(define (curry f x)
(lambda (y) (f x y)))
(define (compose f g)
(lambda (x) (f (g x))))
compose is the right and lazy thing to do, however since lists are iterated from head to tail but created from tail to head creating the reverse result is actually more efficient when done in one go:
(define (reverse-filter p? xs)
(define (helper lst acc)
(if (null? lst)
acc
(helper (cdr lst)
(let ((a (car lst)))
(if (p? a)
(cons a acc)
acc)))))
(helper xs '()))
(reverse-filter symbol? '(1 2 3 a b c))
; ==> (c b a)

"Adding" two functions together in Scheme

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

Map Function practice in Scheme

I am having trouble using a map function to return a list of the square of the deviation of a given set of numbers. I wrote my square-of-deviation function as follows, but I don't know how to map this. Is there a way to right my square-of-deviation function so that it doesn't take "l" as a parameter? If I wrote function like this then I would know how to map it.
(define (square-of-deviation l)
(define (square-of-deviation-h n)
(if (null? n)
'()
(cons (expt (- (car n) (average l)) 2)
(square-of-deviation-h (cdr n)))))
(square-of-deviation-h l))
I wrote a function that I could use to map, but it requires that I pass the same list twice when I test my code:
(define (square-of-deviation-2 l)
(lambda (x) (expt (- x (average l)) 2)))
(map (square-of-deviation-2 '(1 2 3 4 5)) '(1 2 3 4 5))
Should I alter my map function here? I wrote it as follows:
(define (map f items)
(if (null? items)
'()
(cons (f (car items))
(map f (cdr items)))))
Try this:
(define lst '(1 2 3 4 5))
(define avg (average lst))
(define (square-of-deviation-2 x)
(expt (- x avg) 2))
(map square-of-deviation-2 lst)
Notice that you only need to calculate the average once, so you can do it before calling map, because map's function only expects a single value, which is each of the input list's elements in turn. An even nicer solution would be to pack everything in a single function:
(define (square-of-deviation lst)
(let ((avg (average lst)))
(map (lambda (x) (expt (- x avg) 2)) lst)))

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)