Rejoice!
Rejoice is a concatenative programming language where data is encoded as multisets and compose by multiplication. Think Fractran, without the rule-searching of rewriting, or a strange Forth in which the program state is unordered.
Basics
The program state is a bag of unordered things, transformations are represented as fractions where the denominator indicates things to remove from the bag, and the numerator, things to add.
The documentation below displays the content of the bag in bold. Multiple instances of things are grouped as thing^count.
( a comment ) red green blue [yellow red]/blue red^2 yellow
Evaluation consists of applying fractions in a sequence when their denominators are found.
blue^3 black/pink white/blue red/[blue^2 white] blue^3 white/blue red/[blue^2 white] blue^2 white red/[blue^2 white] red
A fraction can also put fractions and symbols back in the bag.
x [y z/y]/x y z/y z
Logic
Here is the implemenation of a NOT logic gate.
false not true/[false not] false/[true not] true false/[true not] true
true not true/[false not] false/[true not] true not false/[true not] false
The different handlers are sequenced one after the other, here is a OR gate. Notice the need for a sentinel or symbol.
x y or true/[x y or] true/[x or] true/[y or] false/or true true/[x or] true/[y or] false/or true true/[y or] false/or true false/or true
or true/[x y or] true/[x or] true/[y or] false/or or true/[x or] true/[y or] false/or or true/[y or] false/or or false/or false
Functions
Functions are symbols that are replaced their body if found in the bag. A definition starts with colon, and ends with a semi-colon. The definition comment indicates the state of the bag before and after the transformation.
: And? ( x y -- bool ) a true/[a x y] false/[a x] false/[a y] false/a ;
x y And? x y a true/[a x y] false/[a x] false/[a y] false/a true false/[a x] false/[a y] false/a true false/[a y] false/a true false/a true
Arithmetic
The function [x Add]/y drains y into x and calls itself again for as long as y is in the bag, effectively finding the sum by resource transfer.
: Add ( x y -- x^2 ) [x Add]/y ;
x^2 y^3 Add x^2 y^3 [x Add]/y x^3 y^2 Add x^3 y^2 [x Add]/y x^4 y Add x^4 y [x Add]/y x^5 Add x^5 [x Add]/y x^5
To find the difference between two symbols, the following recursive function can find the result:
: Sub ( x y -- x|y ) Sub/[x y] ;
x^4 y^2 Sub x^4 y^2 Sub/[x y] x^3 y Sub x^3 y Sub/[x y] x^2 Sub x^2 Sub/[x y] x^2
To double the value of a symbol:
: Double ( x -- res^2 ) [res^2 Double]/x ;
x^3 Double x^3 [res^2 Double]/x x^2 res^2 Double x^2 res^2 [res^2 Double]/x x res^4 Double x res^4 [res^2 Double]/x res^6 Double res^6 [res^2 Double]/x res^6
Loops
A function can include its own name in the definition, allowing for loops:
: loop ( x -- ) x done/x^4 [x^2 loop]/x ;
x loop x done/x^4 [x^2 loop]/x x [x^2 loop]/x x^2 loop x^2 done/x^4 [x^2 loop]/x x^2 [x^2 loop]/x x^3 loop x^3 done/x^4 [x^2 loop]/x x^3 [x^2 loop]/x x^4 loop x^4 done/x^4 [x^2 loop]/x done [x^2 loop]/x done
This is a first draft of the language, I'm currently working on an implementation. One last thing before I end this, here's a fizzbuzz:
: FizzBuzz ( i -- ) i^2 f b print-fb/[f^2 b^4] print-f/[f^2] print-b/[b^4] done/[i^100] FizzBuzz/i ;