Task

Create a function, compose,   whose two arguments   f   and   g,   are both functions with one argument.



The result of compose is to be a function of one argument, (lets call the argument   x),   which works like applying function    f    to the result of applying function    g    to    x.



Example

 compose(f, g) (x) = f(g(x))



Reference: Function composition

Hint: In some languages, implementing compose correctly requires creating a closure.




use std, math
 
let my_asin = new Function (.:<any,real x>:. -> real {asin x})
let my__sin = new Function (.:<any,real x>:. -> real { sin x})
let sinasin = my__sin o my_asin
print sin asin 0.5
print *my__sin 0.0
print *sinasin 0.5
~my_asin
~my__sin
~sinasin
 
=: <Function f> o <Function g> := -> Function {compose f g}
 
.:compose <Function f, Function g>:. -> Function
  use array
  let d = (new array of 2 Function)
  (d[0]) = f ; (d[1]) = g
  let c = new Function (.:<array of Function fg, real x>:. -> real {
    *fg[0]( *fg[1](x) )
  }) (d)
  c.del = .:<any>:.{free any}
  c
 
class Function
  function(any)(real)->(real)	func
  any				data
  function(any)			del
 
=: * <Function f> <real x> := -> real
   Cgen "(*("(f.func)"))("(f.data)", "(x)")"
 
.: del Function <Function f> :.
   unless f.del is nil
     call f.del with f.data
   free f
=: ~ <Function f> := {del Function f}
 
.: new Function <function(any)(real)-\>real func> (<any data>):. -> Function
   let f = new Function
   f.func = func
   f.data = data
   f