Prelude
Drop
Discard the top stack item.
Print Drop "foo" "bar";
Source
Def Drop as ( Let X );
Swap
Swaps the top two stack items.
Print Swap 1 2;
Source
Def Swap as ( Let X ; Let Y ; Y X );
Do
Execute a block.
Do ( Print "hello world!" );
Source
Def Do as ( Def F ; F );
Any?
Takes a parameter of any type and returns True
Print Any? 12;
Print Any? "hello";
Print Any? List (1 2 3);
Source
Def Any? ( True Drop );
Twin
Duplicate the top stack item.
Def Square as (* Twin);
Print Square 8;
Source
Def Twin as (Let X ; X X);
Triplet
Triplicates the top stack item
Def Cube as (* * Triplet);
Print Cube 8;
Source
Def Triplet as (Twin ; Twin);
When
Takes a boolean (Cond) and a block (F) as parameters. Executes F, given Cond is True.
When True ( Print "hello!" );
When False ( Print "bye!" );
Source
Def When as (
Let Cond;
Def F;
Do If Cond then ( F ) else ();
);
Unless
Opposite of When. Takes a boolean (Cond) and a block (F) as parameters. Executes F, given Cond is False.
Unless True ( Print "hello!" );
Unless False ( Print "bye!" );
Source
Def Unless as (
Let Cond;
Def F;
Do If Cond then ( ) else ( F );
);
While
Takes two block parameters (Cond and F). Continually execute F while Cond evaluates to True.
While (True) ( Print "This will print forever..." );
While (False) ( Print "This won't print at all..." );
Source
Def While (
Def Cond;
Def F;
Let Result be Cond;
When Result then ( F ; While (Cond) (F) )
);
Until
Opposite of While. Takes two block parameters (Cond and F). Continually execute F until Cond evaluates to True.
Until (False) ( Print "This will print forever..." );
Until (True) ( Print "This won't print at all..." );
Source
Def Until (
Def Cond;
Def F;
Let Result be Cond;
Unless Result then ( F ; Until (Cond) (F) );
);
Times
Takes a number (N) and a block (F) as parameters. Evaluates F N times.
Times 3 ( Print "Hip Hip Hooray!" );
Source
Def Times (
Let N be Of (Integer?);
Def F;
Unless Zero? N ( F ; Times - 1 N (F) );
);
With
Takes symbol parameter Mode, string parameter Filename and block parameter Body. Opens the file Filename in mode Mode. Evaluates Body, passing it a reference to the file.
With \read "foo.txt" (
Let F be the file handle;
Print Read-file F;
);
Source
Def With (
Let Mode be Of (Symbol?);
Let Filename be Of (String?);
Def Body;
Let Fp be Open as Mode Filename;
Body Fp;
Close Fp
);
Reverse
Returns the list parameter reversed.
Print Reverse List (1 2 3);
Source
Def Reverse (
Fold ( Push ) from Empty over List!;
);
For
Takes a block (F) and a list (L) as parameters. Applies a block to each element in a list
For each in Range 1 to 100 ( Print );
Source
Def For (
~~ Tail recursive;
Let L be Of (List?);
Def F;
When Not Empty? L (
F First L;
For each in Rest L do (F);
)
);
Fold
Takes a block (F), initial value (I), and list (L) as parameters. Applies F to each element in L, pushing I to the stack first.
Fold (*) from 1 over Range 1 to 10;
Print;
Source
Def Fold (
Def F;
Let I;
Let L be Of (List?);
I ; For each in L do (F);
);
Puts
Builds a string from a block parameter and prints it to standard output, without a newline.
Puts ( "The square of 10 is " * Twin 10 "\n");
Source
Def Puts ( Put Fold ( Join Show ) from "" over Reverse List);
Prints
Builds a string from a block parameter and prints it to standard output, with a newline.
Puts ( "The square of 10 is " * Twin 10);
Source
Def Prints ( Print Fold ( Join Show ) from "" over Reverse List);
Filter
Takes a block parameter Predicate and a list L. Applies Predicate to each element in L. Returns a list containing only the elements where Predicate evaluated to True.
Def Even? as (Zero? Modulo 2);
Filter (Even?) over Range 1 to 100;
Print;
Source
Def Filter (
Def Predicate;
Let L be Of (List?);
Empty;
For each in L (
Let I;
Let R be Predicate I;
When R ( Push I );
);
Reverse;
);
Min
Takes two number parameters and returns the smaller one.
Print Min 3 10;
Source
Def Min as (
Let A be Of (Number?);
Let B be Of (Number?);
If < A B then B else A;
);
Max
Takes two number parameters and returns the larger one.
Print Max 3 10;
Source
Def Max as (
Let A be Of (Number?);
Let B be Of (Number?);
If < A B then A else B;
);
Take-while
Takes a predicate block (F) and a list (L) as parameters. Builds a new list by taking elements one by one from L and evaluating F on them. Stops building the list when the F first evaluates to False.
Print Take-while (< 10) Range 1 to 100;
Source
Def Take-while (
Def F;
Let L be Of (List?);
Def H as (
Let L;
Unless Empty? L (
Let I be First L;
Let R be F of I;
When R then (
Push I;
H Rest L
)
)
);
Reverse H L Empty;
);
All
Takes a predicate block (F) and list (L) as parameters. Applies F to each element of L, returning True if F returned True every time, else returning False.
Print All (< 100) Range 1 to 10;
Print All (< 10) Range 1 to 100;
Source
Def All (
Def F;
Let L be Of (List?);
Do If Empty? L then ( True )
else (
Do If F on First L
then ( All (F) of Rest of L )
else ( False )
)
);
None
Takes a predicate block and list as parameters. Returns True if evaluating the predicate on all of the list elements gives False, else returns False.
Print None (> 100) Range 1 to 10;
Print None (> 10) Range 1 to 100;
Source
Def None (
Def P;
Let L;
All ( Not P ) of L;
);
Append
Takes two list parameters and returns a new list created by joining the first list onto the end of the second list.
Print Append List (4 5 6) to List (1 2 3);
Source
Def Append (
Let L2;
Let L1;
L2;
For each in Reverse L1 (
Push;
)
);
Prepend
Takes two list parameters and returns a new list created by joining the second list onto the end of the first list.
Print Prepend List (1 2 3) to List (4 5 6);
Source
Def Prepend ( Swap ; Append );
Case
Takes a predicate block Pred and two other blocks If-true and If-false. Returns a block that takes one parameter (X) and applies the predicate to it. If this gives True then If-true is evaluated with X as a parameter. If not If-false is evaluated with X as a parameter.
Def Multiple as ( Zero? Modulo );
Def Fizzbuzz
Case (Multiple of 15) then ( "Fizzbuzz" Drop )
Case (Multiple of 3) then ( "Fizz" Drop )
Case (Multiple of 5) then ( "Buzz" Drop )
else ( just return the number );
For each in Range 1 to 100 ( Print Fizzbuzz )
Source
Def Case as (
Def Pred;
Def If-true;
Def If-false;
(
Let X;
Let B be Pred X;
Do If B then (If-true X) else (If-false X)
);
);
Sort
Takes a list of numbers as a parameter and returns a list containing the same numbers in ascending order.
Print Sort List ( 9 6 2 5 7 4 1 3 8);
Source
Def Sort
Case (Empty?) ()
else (
Let L;
Let Pivot be First of L;
Sort Filter (< Pivot) L;
Sort Filter (>= Pivot) Rest of L;
Push Pivot;
Append
);
Map
Takes a block (F) and a list (L) as parameters. Creates a new list where each element is the result of applying F to the corresponding element in L.
Def Square as (* Twin);
Map (Square) over the Range from 1 to 10;
Print
Source
Def Map (
Def F;
Let L be a List!;
Do If Empty? L ( L )
else (
Let X be First of L;
Let Res be F X;
return Push Res to Map (F) over Rest of L;
);
);
Discard
Takes an integer (N) and a list (L) as parameters. Returns a list created by removing the first N elements of L.
Print Discard 4 from Range 1 to 10;
Source
Def Discard (
Let N be Of (Integer?);
Let L be Of (List?);
Do If Zero? N ( L ) else (
When Empty? L ( Error "Cannot Discard more elements than in list" );
Discard - 1 N from Rest L
);
);
Take
Takes an integer (N) and a list (L) as parameters. Returns a list containing only the first N elements of L.
Print Take 4 from Range 1 to 10;
Source
Def Take (
Let N be Of (Integer?);
Let L be Of (List?);
Do If Zero? N ( Empty list ) else (
When Empty? L ( Error "Cannot Take more elements than in list" );
Push First L to Take - 1 N from Rest of L
);
);
Index
Takes an integer (N) and a list (L) as parameters. Returns the Nth element (indexed from zero) of L.
Print Index 4 of Range 0 to 100;
Source
Def Index (
Let N be Of (Integer?);
Let L be List!;
When < 0 N ( Error Join "Invalid index " Show N );
Do If Zero? N ( return First element of L )
else (
When Empty? L ( Error "Index is beyond end of list" );
Index - 1 N of Rest of L
);
);
Range
Takes two number parameters (Start and End). Returns a list of numbers ranging from Start to End inclusive of Start but not End with a step of 1.
Print Range 1 to 100;
Source
Def Range (
Let Start be Number!;
Let End be Number!;
When > End Start ~~ TODO? maybe we could have this create a reverse range.
(
Error Join Join Join "Invalid range " Show Start "..." Show End;
);
Reverse List (
Start;
While (Triplet ; < End) ( + 1 );
Drop; Drop;
)
);
Assert
Takes a string (Assertion) and a boolean (Result). If Result is not True then throws an error, with the text of Assertion in the error message.
Assert "This assertion will pass" True;
Assert "This assertion will fail" False;
Source
Def Assert (
Let Assertion be String!;
Let Result be Boolean!;
Unless Result ( Error Join Join "Failed assertion: '" Assertion "'" );
);