This commit is contained in:
Ingy döt Net 2013-04-10 21:29:02 -07:00
parent 764da6cbbb
commit db842d013d
19005 changed files with 197040 additions and 7 deletions

View file

@ -0,0 +1,6 @@
Create a function, <span style="font-family:serif">compose</span>, whose two arguments <span style="font-family:serif">''f''</span> and <span style="font-family:serif">''g''</span>, are both functions with one argument. The result of <span style="font-family:serif">compose</span> is to be a function of one argument, (lets call the argument <span style="font-family:serif">''x''</span>), which works like applying function <span style="font-family:serif">''f''</span> to the result of applying function <span style="font-family:serif">''g''</span> to <span style="font-family:serif">''x''</span>, i.e,
: <span style="font-family:serif">compose(''f'', ''g'') (''x'') = ''f''(''g''(''x''))</span>
Reference: [[wp:Function composition (computer science)|Function composition]]
Hint: In some languages, implementing <span style="font-family:serif">compose</span> correctly requires creating a [[wp:Closure (computer science)|closure]].

View file

@ -0,0 +1,2 @@
---
note: Higher-order functions

View file

@ -0,0 +1,10 @@
MODE F = PROC(REAL)REAL; # ALGOL 68 is strong typed #
# As a procedure for real to real functions #
PROC compose = (F f, g)F: (REAL x)REAL: f(g(x));
OP (F,F)F O = compose; # or an OPerator that can be overloaded #
# Example use: #
F sin arc sin = compose(sin, arc sin);
print((sin arc sin(0.5), (sin O arc sin)(0.5), new line))

View file

@ -0,0 +1,11 @@
MODE F = PROC(REAL)REAL; # ALGOL 68 is strong typed #
# As a procedure for real to real functions #
PROC compose = (F f, g)F: ((F f2, g2, REAL x)REAL: f2(g2(x)))(f, g, ); # Curry #
PRIO O = 7;
OP (F,F)F O = compose; # or an OPerator that can be overloaded #
# Example use: #
F sin arc sin = compose(sin, arc sin);
print((sin arc sin(0.5), (sin O arc sin)(0.5), new line))

View file

@ -0,0 +1,6 @@
function compose(f:Function, g:Function):Function {
return function(x:Object) {return f(g(x));};
}
function test() {
trace(compose(Math.atan, Math.tan)(0.5));
}

View file

@ -0,0 +1,13 @@
generic
type Argument is private;
package Functions is
type Primitive_Operation is not null
access function (Value : Argument) return Argument;
type Func (<>) is private;
function "*" (Left : Func; Right : Argument) return Argument;
function "*" (Left : Func; Right : Primitive_Operation) return Func;
function "*" (Left, Right : Primitive_Operation) return Func;
function "*" (Left, Right : Func) return Func;
private
type Func is array (Positive range <>) of Primitive_Operation;
end Functions;

View file

@ -0,0 +1,25 @@
package body Functions is
function "*" (Left : Func; Right : Argument) return Argument is
Result : Argument := Right;
begin
for I in reverse Left'Range loop
Result := Left (I) (Result);
end loop;
return Result;
end "*";
function "*" (Left, Right : Func) return Func is
begin
return Left & Right;
end "*";
function "*" (Left : Func; Right : Primitive_Operation) return Func is
begin
return Left & (1 => Right);
end "*";
function "*" (Left, Right : Primitive_Operation) return Func is
begin
return (Left, Right);
end "*";
end Functions;

View file

@ -0,0 +1,12 @@
with Ada.Numerics.Elementary_Functions; use Ada.Numerics.Elementary_Functions;
with Ada.Text_IO; use Ada.Text_IO;
with Functions;
procedure Test_Compose is
package Float_Functions is new Functions (Float);
use Float_Functions;
Sin_Arcsin : Func := Sin'Access * Arcsin'Access;
begin
Put_Line (Float'Image (Sin_Arcsin * 0.5));
end Test_Compose;

View file

@ -0,0 +1,8 @@
import math
function compose (f, g) {
return function (x) { return f(g(x)) }
}
var func = compose(Math.sin, Math.asin)
println (func(0.5)) // 0.5

View file

@ -0,0 +1,43 @@
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

View file

@ -0,0 +1,5 @@
MsgBox % compose("sin","cos",1.5)
compose(f,g,x) { ; function composition
Return %f%(%g%(x))
}

View file

@ -0,0 +1,17 @@
REM Create some functions for testing:
DEF FNsqr(a) = SQR(a)
DEF FNabs(a) = ABS(a)
REM Create the function composition:
SqrAbs = FNcompose(FNsqr(), FNabs())
REM Test calling the composition:
x = -2 : PRINT ; x, FN(SqrAbs)(x)
END
DEF FNcompose(RETURN f%, RETURN g%)
LOCAL f$, p% : DIM p% 7 : p%!0 = f% : p%!4 = g%
f$ = "(x)=" + CHR$&A4 + "(&" + STR$~p% + ")(" + \
\ CHR$&A4 + "(&" + STR$~(p%+4) + ")(x))"
DIM p% LEN(f$) + 4 : $(p%+4) = f$ : !p% = p%+4
= p%

View file

@ -0,0 +1,9 @@
double sin (double v) { return Math.sin(v); }
double asin (double v) { return Math.asin(v); }
Var compose (Func f, Func g, double d) { return f(g(d)); }
void button1_onClick (Widget widget)
{
double d = compose(sin, asin, 0.5);
label1.setText(d.toString(9));
}

View file

@ -0,0 +1 @@
0.500000000

View file

@ -0,0 +1,7 @@
compose = { f, g | { x | f g x } }
#Test
add1 = { x | x + 1 }
double = { x | x * 2 }
b = compose(->double ->add1)
p b 1 #should print 4

View file

@ -0,0 +1,35 @@
#include <functional>
#include <cmath>
#include <iostream>
// functor class to be returned by compose function
template <class Fun1, class Fun2>
class compose_functor :
public std::unary_function<typename Fun2::argument_type,
typename Fun1::result_type>
{
protected:
Fun1 f;
Fun2 g;
public:
compose_functor(const Fun1& _f, const Fun2& _g)
: f(_f), g(_g) { }
typename Fun1::result_type
operator()(const typename Fun2::argument_type& x) const
{ return f(g(x)); }
};
// we wrap it in a function so the compiler infers the template arguments
// whereas if we used the class directly we would have to specify them explicitly
template <class Fun1, class Fun2>
inline compose_functor<Fun1, Fun2>
compose(const Fun1& f, const Fun2& g)
{ return compose_functor<Fun1,Fun2>(f, g); }
int main() {
std::cout << compose(std::ptr_fun(::sin), std::ptr_fun(::asin))(0.5) << std::endl;
return 0;
}

View file

@ -0,0 +1,16 @@
#include <iostream>
#include <functional>
#include <cmath>
template <typename A, typename B, typename C>
std::function<C(A)> compose(std::function<C(B)> f, std::function<B(A)> g) {
return [f,g](A x) { return f(g(x)); };
}
int main() {
std::function<double(double)> f = sin;
std::function<double(double)> g = asin;
std::cout << compose(f, g)(0.5) << std::endl;
return 0;
}

View file

@ -0,0 +1,9 @@
#include <iostream>
#include <cmath>
#include <ext/functional>
int main() {
std::cout << __gnu_cxx::compose1(std::ptr_fun(::sin), std::ptr_fun(::asin))(0.5) << std::endl;
return 0;
}

View file

@ -0,0 +1,64 @@
#include <stdlib.h>
/* generic interface for functors from double to double */
typedef struct double_to_double {
double (*fn)(struct double_to_double *, double);
} double_to_double;
#define CALL(f, x) f->fn(f, x)
/* functor returned by compose */
typedef struct compose_functor {
double (*fn)(struct compose_functor *, double);
double_to_double *f;
double_to_double *g;
} compose_functor;
/* function to be used in "fn" in preceding functor */
double compose_call(compose_functor *this, double x) {
return CALL(this->f, CALL(this->g, x));
}
/* returns functor that is the composition of functors
f & g. caller is responsible for deallocating memory */
double_to_double *compose(double_to_double *f,
double_to_double *g) {
compose_functor *result = malloc(sizeof(compose_functor));
result->fn = &compose_call;
result->f = f;
result->g = g;
return (double_to_double *)result;
}
#include <math.h>
/* we can make functors for sin and asin by using
the following as "fn" in a functor */
double sin_call(double_to_double *this, double x) {
return sin(x);
}
double asin_call(double_to_double *this, double x) {
return asin(x);
}
#include <stdio.h>
int main() {
double_to_double *my_sin = malloc(sizeof(double_to_double));
my_sin->fn = &sin_call;
double_to_double *my_asin = malloc(sizeof(double_to_double));
my_asin->fn = &asin_call;
double_to_double *sin_asin = compose(my_sin, my_asin);
printf("%f\n", CALL(sin_asin, 0.5)); /* prints "0.500000" */
free(sin_asin);
free(my_sin);
free(my_asin);
return 0;
}

View file

@ -0,0 +1,7 @@
(defn compose [f g]
(fn [x]
(f (g x))))
; Example
(def inc2 (compose inc inc))
(println (inc2 5)) ; prints 7

View file

@ -0,0 +1 @@
(defun compose (f g) (lambda (x) (funcall f (funcall g x))))

View file

@ -0,0 +1,5 @@
>(defun compose (f g) (lambda (x) (funcall f (funcall g x))))
COMPOSE
>(let ((sin-asin (compose #'sin #'asin))))
(funcall sin-asin 0.5))
0.5

View file

@ -0,0 +1,2 @@
(defun compose (f g)
(eval `(lambda (x) (funcall ',f (funcall ',g x))))

View file

@ -0,0 +1,6 @@
CL-USER> (defmacro compose (fn-name &rest args)
(labels ((rec1 (args)
(if (= (length args) 1)
`(funcall ,@args x)
`(funcall ,(first args) ,(rec1 (rest args))))))
`(defun ,fn-name (x) ,(rec1 args))))

View file

@ -0,0 +1,11 @@
import std.stdio;
T delegate(S) compose(T, U, S)(in T delegate(U) f,
in U delegate(S) g) {
return s => f(g(s));
}
void main() {
writeln(compose((int x) => x + 15, (int x) => x ^^ 2)(10));
writeln(compose((int x) => x ^^ 2, (int x) => x + 15)(10));
}

View file

@ -0,0 +1,36 @@
program AnonCompose;
{$APPTYPE CONSOLE}
type
TFunc = reference to function(Value: Integer): Integer;
function Compose(F, G: TFunc): TFunc;
begin
Result:= function(Value: Integer): Integer
begin
Result:= F(G(Value));
end
end;
var
Func1, Func2, Func3: TFunc;
begin
Func1:=
function(Value: Integer): Integer
begin
Result:= Value * 2;
end;
Func2:=
function(Value: Integer): Integer
begin
Result:= Value * 3;
end;
Func3:= Compose(Func1, Func2);
Writeln(Func3(6)); // 36 = 6 * 3 * 2
Readln;
end.

View file

@ -0,0 +1,3 @@
define method compose(f,g)
method(x) f(g(x)) end
end;

View file

@ -0,0 +1,3 @@
def compose(f, g) {
return fn x { return f(g(x)) }
}

View file

@ -0,0 +1 @@
compose f g x = f (g x)

View file

@ -0,0 +1,7 @@
-module(fn).
-export([compose/1, multicompose/2]).
compose(F,G) -> fun(X) -> F(G(X)) end.
multicompose(Fs) ->
lists:foldl(fun compose/2, fun(X) -> X end, Fs).

View file

@ -0,0 +1,6 @@
1> (fn:compose(fun math:sin/1, fun math:asin/1))(0.5).
0.5
2> Sin_asin_plus1 = fn:multicompose([fun math:sin/1, fun math:asin/1, fun(X) -> X + 1 end]).
#Fun<tests.0.59446746>
82> Sin_asin_plus1(0.5).
1.5

View file

@ -0,0 +1,4 @@
( scratchpad ) [ 2 * ] [ 1 + ] compose .
[ 2 * 1 + ]
( scratchpad ) 4 [ 2 * ] [ 1 + ] compose call .
9

View file

@ -0,0 +1,15 @@
class Compose
{
static |Obj -> Obj| compose (|Obj -> Obj| fn1, |Obj -> Obj| fn2)
{
return |Obj x -> Obj| { fn2 (fn1 (x)) }
}
public static Void main ()
{
double := |Int x -> Int| { 2 * x }
|Int -> Int| quad := compose(double, double)
echo ("Double 3 = ${double(3)}")
echo ("Quadruple 3 = ${quad (3)}")
}
}

View file

@ -0,0 +1,9 @@
: compose ( xt1 xt2 -- xt3 )
>r >r :noname
r> compile,
r> compile,
postpone ;
;
' 2* ' 1+ compose ( xt )
3 swap execute . \ 7

View file

@ -0,0 +1,7 @@
Composition := function(f, g)
return x -> f(g(x));
end;
h := Composition(x -> x+1, x -> x*x);
h(5);
# 26

View file

@ -0,0 +1,11 @@
// Go doesn't have generics, but sometimes a type definition helps
// readability and maintainability. This example is written to
// the following function type, which uses float64.
type ffType func(float64) float64
// compose function requested by task
func compose(f, g ffType) ffType {
return func(x float64) float64 {
return f(g(x))
}
}

View file

@ -0,0 +1,17 @@
package main
import "math"
import "fmt"
type ffType func(float64) float64
func compose(f, g ffType) ffType {
return func(x float64) float64 {
return f(g(x))
}
}
func main() {
sin_asin := compose(math.Sin, math.Asin)
fmt.Println(sin_asin(.5))
}

View file

@ -0,0 +1 @@
def compose = { f, g -> { x -> f(g(x)) } }

View file

@ -0,0 +1,15 @@
def sq = { it * it }
def plus1 = { it + 1 }
def minus1 = { it - 1 }
def plus1sqd = compose(sq,plus1)
def sqminus1 = compose(minus1,sq)
def identity = compose(plus1,minus1)
def plus1sqdminus1 = compose(minus1,compose(sq,plus1))
def identity2 = compose(Math.&sin,Math.&asin)
println "(x+1)**2 = (0+1)**2 = " + plus1sqd(0)
println "x**2-1 = 20**2-1 = " + sqminus1(20)
println "(x+1)-1 = (12+1)-1 = " + identity(12)
println "(x+1)**2-1 = (3+1)**2-1 = " + plus1sqdminus1(3)
println "sin(asin(x)) = sin(asin(1)) = " + identity2(1)

View file

@ -0,0 +1 @@
compose f g x = f (g x)

View file

@ -0,0 +1,4 @@
Prelude> let compose f g x = f (g x)
Prelude> let sin_asin = compose sin asin
Prelude> sin_asin 0.5
0.5

View file

@ -0,0 +1,2 @@
x @ f # use this syntax in Icon instead of the Unicon f(x) to call co-expressions
every push(fL := [],!rfL) # use this instead of reverse(fL) as the Icon reverse applies only to strings

View file

@ -0,0 +1,31 @@
procedure main(arglist)
h := compose(sqrt,abs)
k := compose(integer,"sqrt",ord)
m := compose("-",k)
every write(i := -2 to 2, " h=(sqrt,abs)-> ", h(i))
every write(c := !"1@Q", " k=(integer,\"sqrt\",ord)-> ", k(c))
write(c := "1"," m=(\"-\",k) -> ",m(c))
end
invocable all # permit string invocations
procedure compose(fL[]) #: compose(f1,f2,...) returns the functional composition of f1,f2,... as a co-expression
local x,f,saveSource
every case type(x := !fL) of {
"procedure"|"co-expression": &null # procedures and co-expressions are fine
"string" : if not proc(x,1) then runnerr(123,fL) # as are invocable strings (unary operators, and procedures)
default: runerr(123,fL)
}
fL := reverse(fL) # reverse and isolate from mutable side-effects
cf := create { saveSource := &source # don't forget where we came from
repeat {
x := (x@saveSource)[1] # return result and resume here
saveSource := &source # ...
every f := !fL do x := f(x) # apply the list of 'functions'
}
}
return (@cf, cf) # 'prime' the co-expr before returning it
end

View file

@ -0,0 +1 @@
compose =: @

View file

@ -0,0 +1 @@
f compose g

View file

@ -0,0 +1,3 @@
f=: >.@(1&o.)@%:
g=: 1&+@|@(2&o.)
h=: f@g

View file

@ -0,0 +1,2 @@
(f, g, h) 1p1
1 2 1

View file

@ -0,0 +1,33 @@
public class Compose {
// Java doesn't have function type so we define an interface
// of function objects instead
public interface Fun<A,B> {
B call(A x);
}
public static <A,B,C> Fun<A,C> compose(final Fun<B,C> f, final Fun<A,B> g) {
return new Fun<A,C>() {
public C call(A x) {
return f.call(g.call(x));
}
};
}
public static void main(String[] args) {
Fun<Double,Double> sin = new Fun<Double,Double>() {
public Double call(Double x) {
return Math.sin(x);
}
};
Fun<Double,Double> asin = new Fun<Double,Double>() {
public Double call(Double x) {
return Math.asin(x);
}
};
Fun<Double,Double> sin_asin = compose(sin, asin);
System.out.println(sin_asin.call(0.5)); // prints "0.5"
}
}

View file

@ -0,0 +1,13 @@
import java.util.function.Function;
public class Compose {
public static <A,B,C> Function<A,C> compose(Function<B,C> f, Function<A,B> g) {
return x -> f.apply(g.apply(x));
}
public static void main(String[] args) {
Function<Double,Double> sin_asin = compose(Math::sin, Math::asin);
System.out.println(sin_asin.apply(0.5)); // prints "0.5"
}
}

View file

@ -0,0 +1,5 @@
function compose(f, g) {
return function(x) {
return f(g(x));
};
}

View file

@ -0,0 +1,2 @@
var id = compose(Math.sin, Math.asin);
print(id(0.5)); // 0.5

View file

@ -0,0 +1 @@
g f

View file

@ -0,0 +1 @@
compose: {x@y@z}

View file

@ -0,0 +1,3 @@
sin_asin: compose[_sin;_asin]
sin_asin 0.5
0.5

View file

@ -0,0 +1,27 @@
HAI 1.3
I HAS A fx, I HAS A gx
HOW IZ I composin YR f AN YR g
fx R f, gx R g
HOW IZ I composed YR x
FOUND YR I IZ fx YR I IZ gx YR x MKAY MKAY
IF U SAY SO
FOUND YR composed
IF U SAY SO
HOW IZ I incin YR num
FOUND YR SUM OF num AN 1
IF U SAY SO
HOW IZ I sqrin YR num
FOUND YR PRODUKT OF num AN num
IF U SAY SO
I HAS A incsqrin ITZ I IZ composin YR incin AN YR sqrin MKAY
VISIBLE I IZ incsqrin YR 10 MKAY BTW, prints 101
I HAS A sqrincin ITZ I IZ composin YR sqrin AN YR incin MKAY
VISIBLE I IZ sqrincin YR 10 MKAY BTW, prints 121
KTHXBYE

View file

@ -0,0 +1 @@
function compose(f, g) return function(...) return f(g(...)) end end

View file

@ -0,0 +1,2 @@
Composition[f, g][x]
Composition[f, g, h, i][x]

View file

@ -0,0 +1,2 @@
f[g[x]]
f[g[h[i[x]]]]

View file

@ -0,0 +1,2 @@
compose[f_, g_][x_] := f[g[x]]
compose[Sin, Cos][r]

View file

@ -0,0 +1 @@
Sin[Cos[r]]

View file

@ -0,0 +1,3 @@
Composition[f,g,h][x]
f@g@h@x
x//h//g//f

View file

@ -0,0 +1 @@
f[g[h[x]]]

View file

@ -0,0 +1,2 @@
Composition[f, Identity, g]
Composition[f, InverseFunction[f], h][x]

View file

@ -0,0 +1,2 @@
f[g[x]]
h[x]

View file

@ -0,0 +1,8 @@
/* built-in */
load(to_poly_solver);
compose_functions([sin, cos]);
/* lambda([%g0],sin(cos(%g0)))*/
/* An implementation, to show a use of buildq */
compose(f, g) := buildq([f, g], lambda([x], f(g(x))));

View file

@ -0,0 +1,8 @@
<?php
function compose($f, $g) {
return function($x) use ($f, $g) { return $f($g($x)); };
}
$trim_strlen = compose('strlen', 'trim');
echo $result = $trim_strlen(' Test '), "\n"; // prints 4
?>

View file

@ -0,0 +1,8 @@
<?php
function compose($f, $g) {
return create_function('$x', 'return '.var_export($f,true).'('.var_export($g,true).'($x));');
}
$trim_strlen = compose('strlen', 'trim');
echo $result = $trim_strlen(' Test '), "\n"; // prints 4
?>

View file

@ -0,0 +1,10 @@
sub compose {
my ($f, $g) = @_;
sub {
$f -> ($g -> (@_))
};
}
use Math::Trig;
print compose(sub {sin $_[0]}, \&asin)->(0.5), "\n";

View file

@ -0,0 +1,3 @@
(de compose (F G)
(curry (F G) (X)
(F (G X)) ) )

View file

@ -0,0 +1,3 @@
(def 'a (compose inc dec))
(def 'b (compose 'inc 'dec))
(def 'c (compose '((A) (inc A)) '((B) (dec B))))

View file

@ -0,0 +1,8 @@
: (a 7)
-> 7
: (b 7)
-> 7
: (c 7)
-> 7

View file

@ -0,0 +1,4 @@
:- use_module(lambda).
compose(F,G, FG) :-
FG = \X^Z^(call(G,X,Y), call(F,Y,Z)).

View file

@ -0,0 +1 @@
compose = lambda f, g: lambda x: f( g(x) )

View file

@ -0,0 +1,6 @@
>>> compose = lambda f, g: lambda x: f( g(x) )
>>> from math import sin, asin
>>> sin_asin = compose(sin, asin)
>>> sin_asin(0.5)
0.5
>>>

View file

@ -0,0 +1,3 @@
compose <- function(f,g) function(x) { f(g(x)) }
r <- compose(sin, cos)
print(r(.5))

View file

@ -0,0 +1,2 @@
compose: procedure; parse arg f,g,x; interpret 'return' f"(" g'(' x "))"
exit /*control never gets here, but this was added just in case.*/

View file

@ -0,0 +1,2 @@
(define (compose f g)
(lambda (x) (f (g x))))

View file

@ -0,0 +1,8 @@
def compose(f,g)
lambda {|x| f[g[x]]}
end
s = compose(Math.method(:sin), Math.method(:cos))
p s[0.5] # => 0.769196354841008
# verify
p Math.sin(Math.cos(0.5)) # => 0.769196354841008

View file

@ -0,0 +1,4 @@
def compose[A](f: A => A, g: A => A) = { x: A => f(g(x)) }
def add1(x: Int) = x+1
val add2 = compose(add1, add1)

View file

@ -0,0 +1,7 @@
class Composable[A](f: A => A) {
def o (g: A => A) = compose(f, g)
}
implicit def toComposable[A](f: A => A) = new Composable(f)
val add3 = (add1 _) o add2

View file

@ -0,0 +1,5 @@
(define (compose f g) (lambda (x) (f (g x))))
;; or:
(define ((compose f g) x) (f (g x)))

View file

@ -0,0 +1,2 @@
(display ((compose sin asin) 0.5))
(newline)

View file

@ -0,0 +1 @@
0.5

View file

@ -0,0 +1,6 @@
| composer fg |
composer := [ :f :g | [ :x | f value: (g value: x) ] ].
fg := composer value: [ :x | x + 1 ]
value: [ :x | x * x ].
(fg value:3) displayNl.

View file

@ -0,0 +1,10 @@
package require Tcl 8.5
namespace path {::tcl::mathfunc}
proc compose {f g} {
list apply [list {f g x} {{*}$f [{*}$g $x]}] $f $g]
}
set sin_asin [compose sin asin]
{*}$sin_asin 0.5 ;# ==> 0.5
{*}[compose abs int] -3.14 ;# ==> 3