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