rascal
rascal copied to clipboard
A simple (almost)functional interpreted language made by Rust
Rascal 
A (almost)functional interpreted language made by Rust
Features of functional languages
According with Haskel wiki the features of a functional language are:
- [x] Functions
- [x] Higher-order functions
- [ ] Purity
- [x] Immutable data
- [x] Referential transparency
- [ ] Lazy evaluation
- [x] Recursion
Use
rascal ./example.rl
Repl
rascal
>>
Install and run
git clone https://github.com/cristianoliveira/rascal.git
cd rascal
cargo build && cargo install
rascal ./example.rl
Motivation?
“If you don’t know how compilers work, then you don’t know how computers work. If you’re not 100% sure whether you know how compilers work, then you don’t know how they work.” — Steve Yegge
Structure
- Integers:
0-9
- Boolean:
true
,false
- Imutables by default:
let x = 1;
- Mutables explicit:
var x = 1;
- Assign values:
x = 0;
- Blocks:
{ .. }
- Operator:
+
,-
,*
,/
and%
- Comparison:
==
,!=
,>
,<
,and
andor
- If else:
if 1==1 { .. else .. }
- Loop:
while 1==1 { .. }
- Function:
let foo = fn [x] { x + 1 }
- Print:
print (1+1)
- Line Comments:
# this is a comment
Example
First project euler challenge:
# Sum a number only whether it's multiple of 5 or 3
var sum = 0;
var number = 0;
let is_multiple = fn [x, y] { (x % y) == 0 };
while number < 10 {
if is_multiple(number, 5) or is_multiple(number, 3) { sum = sum + number };
number = number + 1
};
sum
Each statement requires a ;
unless the last statement. Example of runnable code:
Integers expressions
let x = 20;
let y = 15;
let z = x + y;
z - 5
Result: 30
Bolean expressions
let x = 2;
let y = 1;
let z = x != y;
z == true
Result: true
If Else blocks
let x = 2;
var y = 0;
if x != 2 {
y = 13
else
y = 42
};
y == 42
Result: true
Loops
var y = 0;
while y < 4 {
y = y + 1
};
y == 4
Result: true
Scope per block
var y = 0;
{
var x = y + 1
};
x == 4
Error: "Variable x doesn't exist in this context"
Functions
let foo = fn [x] { x + 1 };
foo(10)
Result: 11
High Order Functions
let composed = fn [f] { f(10) };
let foo = fn [x] { x + 1 };
composed(foo)
Result: 11
Closures
let plus = fn[x, y] { x * y };
let teen = fn[f, b] { f(10, b) };
print(teen(plus, 5));
# prints 50
let plus_builder = fn[number] {
let func = fn[y] { plus(number, y) }; func
};
# This quite ugly but the currently parser don't allow anonymous functions :/
let double = plus_builder(2);
double(20)
Result: 40
Future implementations
- Strings: support for strings
- String comparison: support for compare strings
- Return: return in the middle of a block
- Stable REPL: run code without exiting for sintax errors
The Architecture
It is a simple interpreded language that walks on an AST executing the program. I would like to implement some bytecode, just for science sake, but for now this is fine. Example of an AST generated by code:
var a = 10;
var b = 1;
while b != 0 {
if a > b {
a = a - b;
else
b = b - a;
}
};
return a
Licence
MIT