maroon-lang
maroon is my attempt at a functional programming language. I wanted to become more familiar with the Lambda Calculus, so I made this! It's very simple to use.
There are some rules though.
A function takes and returns exactly one argument. Here's an example.
Fun = a.(a)
PutStrln[Fun["Test"]]The equals sign binds the left side of the statement to the right, the parentheses group the function body, the square brackets call a function with arguments.
Some weird quirks
Stack
maroon is a stack based language, and a weird one at that. There is no differentiation between data that's already been parsed and data that hasn't. Data that's been parsed is pushed to the back of the stack, and data to be parsed is popped off the front. When a function is called, it pops its argument off the back.
Flags
In addition, there are several flags used to interact with the interpreter, some are not useful in their current stage, though. Each of the useful flags has their own function to interface with it, so there is no real need for the users to touch them.
Math
The only supported mathmatical operations are Succ, Add, and Pred :(
Standard Library
// takes two arguments returns first
True = (True_A.(True_B.(True_A)))
// takes two arguments returns second
False = (False_A.(False_B.(False_B)))
// logical and[a][b]
And = (And_P.And_Q.(And_P [And_Q][And_P]))
// logical or[a][b]
Or = (Or_P.Or_Q.(Or_P [Or_P][Or_Q]))
// logical not[a][b]
Not = (Not_P.(Not_P[False][True]))
// logical nand[a][b]
Nand = Nand_A.Nand_B.(Not[And[Nand_A][Nand_B]])
// if[condition][then_case][else_case]
If = If_P.(If_A.(If_B.(If_P[If_A][If_B])))
// Eq[a][b] returns a=b?
Eq = Eq_A.Eq_B.(Eq_A Eq_B @eq)
Eq = Eq_A.Eq_B.(If [Eq[Eq_A][Eq_B]][True][False])
// NotEq[a][b] returns a=/=b?
NotEq = NotEq_A.NotEq_B.(Not[Eq[NotEq_A][NotEq_B]])
// logical xor[a][b]
Xor = Xor_A.(Xor_B.(And[Or[Xor_A][xor_b]][Not[Eq[Xor_A][Xor_B]]]))
// Pair[a][b] is a linked list
Pair = Pair_X.Pair_Y.(Pair_Z.(Pair_Z&[Pair_X][Pair_Y]))
// Head[Pair[a][b]] returns a
Head = First_P.(First_P[True])
// Tail[Pair[a][b]] returns b
Tail = Second_P.(Second_P[False])
// Index[Pair[a][b]][0] returns a
Index = Index_P.Index_N.(Head[Index_N[Tail][Index_P]])
// ToStr[test] returns "test"
ToStr = ToStrA.( none.(ToStrA) )
// Put[test] prints test to screen
Put = PutA.(PutA @print)
// Putln[test] prints test\n to screen
Putln = PutLnA.(PutLnA @println)
// PutStr["test"] prints test to screen
PutStr = PutStrA.(PutStrA[_] @print*)
// PutStrln["test"] prints test\n to screen
PutStrln = PutStrLnA.(PutStrLnA[_] @println*)
// PipeFn[Function][Arg] calls Function with Arg just for its side-effects.
// Returns Arg.
PipeFn = Pipe_function.Pipe_x.(v.()[Pipe_function[Pipe_x]] Pipe_x)
// Newln["test"] prints \n to screen and returns "test"
Newln = NewlnA.(\\_ @println NewlnA)
// Pipe[test] prints test to screen and returns test
Pipe = PipeA.(PipeA @print_pipe)
// Pipeln[test] prints test\n to screen and returns test
Pipeln = PipelnA.(PipelnA @print_pipe \\_ @println)
// PipeStr["test"] prints test to screen and returns test
PipeStr = PipeStrA.(PipeStrA @print_pipe*)
// PipeStrln["test"] prints test\n to screen and returns test
PipeStrln = PipeStrlnA.(PipeStrlnA @print_pipe* \\_ @println)
// Input["test"] returns user input
Input = InputA.(ToStr[@input])
// Rec[f][x] returns f recursively applied to f[x]
Rec = Rec_Function.Rec_Argument.(Rec_Argument Rec_Function @rec)
// Break["test"] breaks out of a Rec loop
Break = Break_A.(@break)
// Pred[n] returns n-1
Pred = Pred_N.(Pred_N @pred)
// Succ[n] returns Add[n][1]
Succ = Succ_N.Succ_F.Succ_X.( Succ_F[Succ_N&[Succ_F&][Succ_X&] ] )
// Add[m][n] returns m+n
Add = Plus_M.Plus_N.Plus_F.Plus_X.( Plus_M[Plus_F]Plus_N[Plus_F][Plus_X]] )
// 0 is False
0 = False
// 1 is f.x.(f[x])
1 = Succ[0]Install Rust and Compile Maroon
It's super easy.
For *nix
cd ~/Desktop
curl https://sh.rustup.rs -sSf | sh
git clone https://github.com/adam-mcdaniel/maroon-lang
cd maroon-lang
cargo build --release
./target/release/maroon examples/hello_world.mThe path to the maroon executable is "target/release/maroon". It's statically linked, so you can move it where ever youd like without worrying about dependencies :)