All concatenative code is built on top of a concatenative and compositional language called Scat with extensible syntax and semantics. The term concatenative refers to program syntax being build from concatenation of subprogram names. The term compositional refers to program semantics where concatenation is interpreted as composition of named functions.
Like the Joy language, the meaning function is a homomorphism from the syntactic monoid onto the semantic monoid. That is, the syntactic relation of concatenation of identifiers maps directly onto the semantic relation of composition of functions. It is a homomorphism instead of an isomorphism because it is onto but not one-to-one, that is, some sequences of identifiers have the same meaning (i.e. dup + and 2 *) but no identifier has more than one meaning.
To load Scat use:
> (require (planet zwizwa/staapl/scat))
;; \__ scat
A scat: expression composes Scats functions.
(scat: word )
The words refer to Scat functions in the (scat) namespace. If there are no arguments, the identity function is returned.
A scat> expression can be used to test Scat compositions interactively.
(scat> word )
This constructs a function by passing the words to scat:, and prints the result of applying this function to an empty parameter stack, top element rightmost.
> (scat> 1 2)
<2> 1 2
> (scat> 1 2 +)
These forms support the unquote operation to introduce scheme expressions into Scat code. This can be done in two ways. Non-quoted unquote is interpreted as Scat functions, while quoted unquotes are interpreted as literal values. Note that otherwize identifiers in Scat code always represent functions. Literal values occuring in code are a notational shorthand for functions that push a value to the parameter stack.
New functions can be defined using the define-ns form.
(define-ns namespace name value)
The namespace refers to a list of prefixes for Scat identifiers when represented as a Scheme identifier, name is the base identifier, and value is the function value. I.e.:
> (define-ns (scat) foo (scat: 1 2 3))
> (define-ns (scat) bar (scat: + +))
> (scat> foo)
<3> 1 2 3
> (scat> foo bar)
There is a shorthand compositions for defining multiple words.
(compositions namespace composer (name word ) )
The namespace parameter defines the destination namespace of new definitions. The source namespace is encoded in the composer. I.e. scat: will pick from the (scat) namespace. This allows the definition of different primitive Scat semantics by taking functionality from one namespace to define primitives of another. The equivalent of the previous example is:
The primitives available in the Scat namespace are currently not documented. They are largely compatible with Joy or directly snarfed from Scheme. These primitives are not so important for general use, since we mostly employ a different semantics for Scat called Coma, a concatenative macro language.