Concatenative language
Concatenative topics
Concatenative meta
Other languages
Meta
Suppose we wish to compose a sequence of functions %A%, %B%, %C%, %D%. In a concatenative language, you just write [factor{A B C D}] In an applicative language, you'd write something like the following: [lisp{(D (C (B (A x))))}] This looks "backwards", because one must read it from right to left; A is the first function to execute, then B, then C, then D. Haskell has an infix operator for function composition, so the excessive nesting is gone but the code still looks "backwards": [haskell{D . C . B . A}] In the [[Factor]] community, we call such code "pipeline code". Pipeline code is one of the simplest idioms in a stack language; you have a sequence of words, where each word takes a single value from the stack and leaves a new value there. Such words can be chained together much like commands in the Unix shell. For example, here is some [[Factor]] code: [factor{"/etc/passwd" ascii file-lines [ "#" head? not ] filter [ ":" split first ] map}] This is very similar to the following Unix shell script: [shellscript{cat /etc/passwd | grep -v '^#' | sed -e 's/:.*//'}] A variation on pipeline code can be found in the UI framework. Here, we are building a tree of gadgets, so it is not quite a pipeline: we create child gadgets, build them up, then add them to the parent using %add-gadget ( parent child -- parent )%. Here is an elaborate example: [factor{USING: ui.gadgets.packs ui.gadgets.labels ui.gadgets.borders ui.gadgets ui.gadgets.buttons ui.backend ui.render ui colors ui.pens.solid ; <pile> "Hello" <label> add-gadget "Click me" [ drop beep ] <border-button> add-gadget <shelf> "A" <label> COLOR: red <solid> >>interior add-gadget "B" <label> COLOR: green <solid> >>interior add-gadget "C" <label> COLOR: blue <solid> >>interior add-gadget add-gadget 5 <iota> <border> COLOR: black <solid> >>boundary "Test" open-window}] Notice it reads almost like a declarative description, but really it is just stack code.
Describe this revision:
Save