My Mailbag
February 7, 2020
Here is our version of russian multiplication:
(define (mult left right)
(let loop ((left left) (right right) (prod 0))
(cond ((= left 1) (+ prod right))
((odd? left)
(loop (quotient left 2) (* right 2) (+ prod right)))
(else (loop (quotient left 2) (* right 2) prod)))))
> (mult 7 13) 91 > (mult 13 7) 91
And here is the new compose function:
(define (compose . fns)
(let comp ((fns fns))
(cond ((null? fns) (lambda (x) x)) ; identity function
((null? (cdr fns)) (car fns))
(else (lambda args
(call-with-values
(lambda () (apply (comp (cdr fns)) args))
(car fns)))))))
> ((compose) (+ 1 4)) 5 > ((compose add1) 4) 5 > ((compose add1 double) 2) 5
You can run the program at https://ideone.com/5g33iW.
Should compose with no arguments return a function like (lambda args (apply values args))?
Here’s a solution in Python.
def multiply(a, b): assert a >= 0 and b >= 0 result = 0 while a: if a & 1: result += b a >>= 1 b += b return result for x in range(10): for y in range(10): assert x * y == multiply(x, y) assert x * y == multiply(y, x) print(multiply(9, 13)) print(multiply(7, 13)) def compose(*args): def fn(x): for arg in reversed(args): x = arg(x) return x return fn rev_sort = compose(list, reversed, sorted) identity = compose() l = [3, 4, 6, 1, 0, 7, 2, 8, 5, 9] print(rev_sort(l)) print(identity(l))Output: