Version 0 of Playing Joy

Updated 2002-04-24 07:31:51

Richard Suchenwirth - Joy is a programming language described by Manfred von Thun in http://www.latrobe.edu.au/philosophy/phimvt/joy/j01tut.html , which has similarities with Forth (see RPN in Tcl), but allows things of any complexity as stack elements. It is radically functional (see Steps towards functional programming) in that it is based on functional composition and has no variables at all - no constants either, for seeming constants are considered functions that take a stack as argument, push their value on the stack, and return the augmented stack. The power of the language is rather in combinators which take one or more functions and return a function. Here the famous K combinator can also be seen in a framework.

To read about Joy is a mind-boggling experience. Of course I asked myself: "Can we have that in Tcl too?" How easily RPN can be implemented in Tcl was independently shown by JCW in Trying Forth in Tcl, so my interest focused first on certain combinators.

Primitive recursion is handled by primrec: given two "programs", it pops the stack, and pushes the evaluation of the first "program" if the popped value is zero; otherwise it applies the second "program" to the popped value and a recursive invocation, in which the stack is decremented by 1. My simple implementation limits the first "program" to a constant and the second to a binary expr operator, but that's enough to try the first exercises.

By isolating the process of recursion into this combinator, typical applications of recursion can be had by simply currying it (see Custom curry) into an interp alias:

 interp alias {} factorial {} primrec 1 *
 interp alias {} sumTo     {} primrec 0 +

}

 proc primrec {b0 bn Stack} {
    set x [lindex $Stack end]
    if {$x>0} {
        set res [expr $x $bn [primrec $b0 $bn [incr x -1]]]
    } else {
        set res $b0
    }
    lreplace $Stack end end $res
 }

# Here starts my collection of "TclJoy" components:

 proc dup Stack {lappend Stack [lindex $Stack end]}
 proc op2 {op Stack} {
    set x [lindex $Stack end-1]
    set y [lindex $Stack end]
    lreplace $Stack end-1 end [expr $x $op $y]
 }
 foreach op {+ - * / % > >= == <= < !=} {
    interp alias {} $op {} op2 $op
 }

if 0 {Usage examples:

   + [dup {2 3 4}] ==> 2 3 8

}


Tcl and other languages | Arts and crafts of Tcl-Tk programming