[Richard Suchenwirth] - More [steps towards functional programming]... When reading about, and [playing Haskell], I met the concept of ''functional composition'' again, where you conglomerate some functions into one, so in pseudocode the application of the functional object (f . g) to a variable x (f . g)(x) is equivalent to f(g(x)) This, of course, can again be had in Tcl - we just have to compromise that the infix operator "." as used in Haskell must be moved to prefix position (before the arguments), as Polish notation requires - but this allows us to pass any number of arguments, not just two. Also, considering that this code should be runnable in a [wish], "." is a (maybe the only) taboo name for a proc: defining "proc ." destroys the primary toplevel window, often causing [wish] to exit. So I changed the name to the slightly bigger, but harmless comma: ",". The code below will create a new procedure, which needs a name. I have first found out in [Lambda in Tcl] that [[info level 0]] makes a nice self-referential name: it tells how the "," proc was called. As opposed to just counting up a lambda index, this has the added advantage that it avoids memory leaks - execute the same code as often as you wish, the name is always the same and thus overwrites the previous instance... For now I assume that the generated procedure takes a single argument (call it "x") - but that could be a list. However, the functions to be nested are not restricted to a single word. Rather, if you brace (or quote) them, they may have more leading arguments (in technical terms, ''currying''- see [Custom curry]), as demonstrated by the "[string] toupper" example below. In Tcl's glorious spirit of "everything is a string" (so don't be afraid of nothing ;-), we just build up a well-formed [proc] body (the closing braces were factored out to prevent over-long lines), declare that with the fancy name and the boring "x" argument, return the name, and off we go... proc , args { set name [info level 0] set closing [string repeat {]} [expr [llength $args]-1]] set body "[join $args { [}] \$x $closing" proc $name x $body set name } if 0 {Now testing... both use cases of "on-the-fly", and saving the generated name in a variable for subsequent use: the first example is strictly alphabetic, while in the second, "T" comes before "c" and" "l" - where it belongs ;-} % [, lsort {string toupper}] {z R a} A R Z % set try [, {string tolower} lsort] , {string tolower} lsort % info body $try string tolower [lsort $x ] % $try {l c T} t c l if 0 { Final note: Reading on Haskell, I sometimes have a vague feeling of inferiority: They have so much (at a cost of increased syntax complexity, types and all) - but then again, our simple Tcl can catch up in 7 lines of code... ---- [Reinhard Max] contributed this condensed version: proc ��· {args} { proc [set name [info level 0]] x "[join $args { [}] \$x [string repeat \] [expr {[llength $args]-1}]]" set name } ([RS])...or this one-liner:-) proc , args {append _ [proc [set _ [info level 0]] x "[join $args { [}] \$x [string repeat \] [expr {[llength $args]-1}]]"]} ---- [CL]: There are deep things to say about functional composition. Meta-summary: functions are a sufficient model for *anything* interesting/significant, and composition is the natural operation on functions, so functional composition is a universally-expressive idiom. 'Nother way to say the same: we do SOOOOOOO much with the duality between code and data. Well, look at functional composition: it's the natural first step in viewing code (operation, function) as data (subject of algebraic analysis). ---- See [Playing Joy] for a Forth-like language that does everything with functional composition. ---- [DKF] remarked in the chat: "Actually, the most well known combinator of all is 'o' (usually written inline) which does function composition: o(f,g)(x) == f(g(x))" - [RS] likes "o" better than the comma. ---- Good usage examples (with the fancy "o" name) are at [Functional imaging]. ---- [TV] Is aware of the relevance of the subject in various ways, and thought it might be interesting to include functional composition with more than one argument function for the sake of example on this page take 3 functions: f: x1,x2 --> f(x1,x2) g: x --> g(x) h: x --> h(x) Then one could make k: x1,x2 --> f(g(x1),h(x2)) The function evaluation order becomes permutable in this case, to compute the value of k, one can compute g(x1), h(x2), f(g,h) or h(x1), g(x2), f(g,h) Of course it is quite possible to directly implement this in tcl. In fact I'll make a [bwise] page starting with the subject of [automatically decomposing a nested function into a bwise graph of composed functions] , which is in fact an important part of the target graphs of bwise, though by no means all. Once one has the functions and their composition it is usefull to have a good representation of their composition, to optimize (re-use of intermediate subfunction results), think, and re-compose. ---- [Category Concept] | [Arts and crafts of Tcl-Tk programming] | [Category Functional Programming]