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
A B C D
In an applicative language, you'd write something like the following:
(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":
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:
"/etc/passwd" ascii file-lines [ "#" head? not ] filter [ ":" split first ] map
This is very similar to the following Unix shell script:
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:
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.
This revision created on Wed, 21 Dec 2022 19:57:43 by CapitalEx (Update UI code to work in 0.99)