On 9/23/05, Florian Gro? <florgro / gmail.com> wrote:
> Neville Burnell wrote:
>
> > I've been watching 'Factor' for sometime, but I havent used it yet ...
>
> Let me second this.

Let me third this :) Concatenative programming languages like Joy[1]
(very academic) and Factor[2] (a more practical language from the man
who brought us JEdit) are very interesting - giving Forth a
theoretical makeover and applying Lisp's program=data=program concept
to produce a very elegant and powerful paradigm.

In some ways, Factor and Joy feel like Ruby in RPN. Compare Ruby's

  [1, 2, 3, 4].map{|x| x * x}

=> [1, 4, 9, 16]

with Joy/Factor's

  [ 1 2 3 4 ]  [ dup * ]  map

=> [ 1 4 9 16 ]

This applies the quoted program [dup *] to the list [1 2 3 4] using
the map operator.

Where Ruby has blocks, and Lisp has lambdas, concatenative languages
have quoted programs.

A more impressive example is Joy's:

  5  [1]  [*]  primrec

which computes the factorial of 5 by using the primrec 'primitive
recursion' operator.

This is the explanation from the tutorial:

> It first pushes the number 5 and then it pushes the two short quoted programs. At this point the stack contains three elements. Then the primrec combinator is executed. It pops the two quotations off the stack and saves them elsewhere. Then primrec tests whether the top element on the stack (initially the 5) is equal to zero. If it is, it pops it off and executes one of the quotations, the [1] which leaves 1 on the stack as the result. Otherwise it pushes a decremented copy of the top element and recurses. On the way back from the recursion it uses the other quotation, [*], to multiply what is now a factorial on top of the stack by the second element on the stack. When all is done, the stack contains 120, the factorial of 5.

That's pretty funky.

The most interesting aspect of concatenative languages is - surprise,
surprise - concatenation, which makes it easy to do all the stuff
functional programming languages do but in a much easier to understand
fashion. For example, if you take a sequence like this:

  2 3 * 5 + .

=> 11

you can take any combination of symbols and cut them out and hey
presto you've got a function. E.g. (in Factor syntax);

  : times_three 3 * ;
  : plus_five 5 + ;

to get

  2 times_three plus_five .

=> 11

or you can do this:

  : three_times_and_five 3 * 5 ;

  2 three_times_and_five +

=> 11

the point being you can abstract ~any~ sequence of operations and data
- strong stuff!

(But if you want to get any real work done, try GForth[3], which is a
blazingly fast Forth that approaches C speed).

Have fun!

Sean

[1] Joy - http://www.latrobe.edu.au/philosophy/phimvt/joy.html

[2] Factor - http://factor.sourceforge.net

[3] GForth - http://www.complang.tuwien.ac.at/forth/gforth/