Composition of Functions or Macros.
; The composition of the functions is one of the basic mathematical
; operations. In this post, I'll try to define composition of
; functions and macros (Newlisp macros=fexprs) in Newlisp.
;
; Such composition should satisfy the following:
;
; ((composition 'f1 ... 'fn) _ _ _) = (f1 (f2 ... (fn _ _ _)))
;
; for all functions and macros.
;
; It wasn't that easy as I thought. First, I limited myself on the
; case of the composition of two functions. After some experimentation
; I came to that:
(set 'compose2 (lambda(f g)
(expand (lambda-macro()(letex((L (cons 'g (args))))(f L)))
'f 'g)))
; I tested it on simple example:
(println (compose2 'sin 'cos))
; (lambda-macro ()
; (letex ((L (cons 'cos (args)))) (sin L)))
(println ((compose2 'sin 'cos) 3) (sin (cos 3))) ; OK, it works.
; Then I tested it on two special, well, entities, i.e. identity
; function and identity macro:
(set 'I (lambda(x)x))
(set 'IM (lambda-macro(x)x))
(println ((compose2 'I 'sin) 3)) ; 0.1411200081, as it should be, i.e. (I (sin 3))
(println ((compose2 'sin 'I) 3)) ; 0.1411200081, as it should be, i.e. (sin (I 3))
(println ((compose2 'IM 'sin) 3)) ; (sin 3), as it should be, i.e. (IM (sin 3))
(println ((compose2 'sin 'IM) 3)) ; 0.1411200081, as it should be (sin (IM 3))
; OK; it appears it worked. Now I'll have to solve multi-version,
; I.e. composition of many functions or macros
(set 'compose (lambda()
(case (length (args))
(0 I) ; because (I (S x)) <=> (S x),
; no matter if S is function or macro
; so I can be always added from the left.
(1 (first (args)))
(2 (apply compose2 (args)))
(true (compose2 (first (args)) (apply compose (rest (args))))))))
(println ((compose sqrt) 65536)) ; 256
(println ((compose sqrt sqrt) 65536)) ; 16
(println ((compose sqrt sqrt sqrt) 65536)) ; 4
; OK, it works as well. However, result of the composing is
; rather complicated because of recursive definition
(println (compose 'f1 'f2 'f3 'f4))
; (lambda-macro ()
; (letex ((L (cons '(lambda-macro ()(letex ((L (cons '(lambda-macro ()(letex ((L (cons 'f4 (args))))
; (f3 L)))
; (args))))
; (f2 L)))
; (args))))
; (f1 L)))
;
;
; If iteration is used for definition of compose, then composition
; can be both shorter and faster - but not more elegant.
---
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment