After studying some Mondrian code a few years ago, I decided to call my language Hieronymus after my own favorite painter Hieronymus Bosch. However, Hi seems to be so ever more nice.
Good, the interpreter is as good as done. I rewrote it in such a manner that it should be relatively easy to implement a small runtime.
I still got some problems with the type checker and rank-1 polymorphism which I am not sure I want to solve.
namespace system (
interface num = #a where (
def plus: a -> a -> a
def min: a -> a -> a
def mul: a -> a -> a
def div: a -> a -> a
)
def +: ::num a => a -> a -> a =
\x,y -> x.plus x y
def -: ::num a => a -> a -> a =
\x,y -> x.min x y
def *: ::num a => a -> a -> a =
\x,y -> x.mul x y
def /: ::num a => a -> a -> a =
\x,y -> x.div x y
)
namespace system (
interface ord = #a where (
def compare: a -> a -> int
)
def ==: ::ord a => a -> a -> bool =
\x,y -> int_eq (x.compare x y) 0
def <: ::ord a => a -> a -> bool =
\x,y -> int_less (x.compare x y) 0
def <=: ::ord a => a -> a -> bool =
\x,y -> int_less (x.compare x y) 1
def >: ::ord a => a -> a -> bool =
\x,y -> int_less (x.compare y x) 0
def >=: ::ord a => a -> a -> bool =
\x,y -> int_less (x.compare y x) 1
)
namespace system (
type bool = [ true | false ]
def not: bool -> bool =
[ true -> false
| _ -> true ]
def and: bool -> bool -> bool =
[ true, true -> true
| _ , __ -> false ]
def or: bool -> bool -> bool =
[ false, false -> false
| _ , __ -> true ]
def eq: bool -> bool -> bool =
[ false, false -> true
| true , true -> true
| _ , __ -> false ]
instance ord bool where (
def compare: bool -> bool -> int =
[ false, false -> 0
| true, true -> 0
| false, _ -> 0-1 ]
)
)
namespace system (
// type int = [ MININT | ... | -1 | 0 | 1 | 2 | ... | MAXINT ]
type int = {system.int}
def int_monadic_min: int -> int =
\v0 -> {int_monadic_min[v0]}
def int_dyadic_min: int -> int -> int =
\v0,v1 -> {int_dyadic_min[v0,v1]}
def int_plus: int -> int -> int =
\v0,v1 -> {int_plus[v0,v1]}
def int_mul: int -> int -> int =
\v0,v1 -> {int_mul[v0,v1]}
def int_div: int -> int -> int =
\v0,v1 -> {int_div[v0,v1]}
def int_compare: int -> int -> int =
\v0,v1 -> {int_compare[v0,v1]}
def int_eq: int -> int -> bool =
\v0,v1 -> {int_eq[v0,v1]}
def int_less: int -> int -> bool =
\v0,v1 -> {int_less[v0,v1]}
def int_magic_tick: () -> bool =
\v0 -> {int_magic_tick[v0]}
instance num int where (
def plus: int -> int -> int = int_plus
def min: int -> int -> int = int_dyadic_min
def mul: int -> int -> int = int_mul
def div: int -> int -> int = int_div
)
instance ord int where (
def compare: int -> int -> int = int_compare
)
)
namespace system (
type char = {system.char}
def char_compare: char -> char -> char =
\v0,v1 -> {char_compare[v0,v1]}
def char_eq: char -> char -> bool =
\v0,v1 -> {char_eq[v0,v1]}
def char_less: char -> char -> bool =
\v0,v1 -> {char_less[v0,v1]}
def char_ascii_code: char -> int =
\v0 -> {char_ascii_code[v0]}
def char_ascii_char: int -> char =
\v0 -> {char_ascii_char[v0]}
instance ord char where (
def compare: char -> char -> int = char_compare
)
)
namespace system (
def file_read: list char -> list char =
\v0 -> {file_read[v0]}
def file_write: list char -> list char -> unit =
\v0,v1 -> {file_write[v0,v1]}
)
namespace list (
using system
type list = \a => [nil | cons a (list a)]
instance ord (list a) where (
def compare: ::ord a => int =
[ nil , nil -> 0
| nil , _ -> 0-1
| _ , nil -> 1
| cons x xx, cons y yy ->
if x == y then xx.compare xx yy
else x.compare x y ]
)
def concat: list a -> list a -> list a =
[ nil, yy -> yy
| cons x xx, yy -> cons x (concat xx yy) ]
def map: (a -> b) -> list a -> list b =
[ f, nil -> nil
| f, cons x xx -> cons (f x) (map f xx) ]
def head: list a -> list a = [ cons x xx -> x ]
def tail: list a -> list a = [ cons x xx -> xx ]
)
namespace system (
type tuple_2_t = \t0 => \t1 => [tuple_2 t0 t1]
instance ::ord t0 => ::ord t1 => ord (tuple_2 t0 t1) where (
def compare: tuple_2_t t0 t1 -> tuple_2_t t0 t1 -> int =
[ tuple_2 x0 x1, tuple_2 y0 y1 ->
let c = x0.compare x0 x1 in
if c == 0 then x1.compare x1 y1 else c ]
)
type tuple_3_t = \t0 \t1 \t2 => [tuple_3 t0 t1]
)
/* Some example programs */
using system
using list
def fac: int -> int =
[ 0 -> 1
| 1 -> 1
| n -> n * (fac (n - 1)) ]
def collatz: int -> int =
let even = [n -> (n / 2) * 2 == n] in
[ 1 -> 1
| n -> if even n
then collatz (n / 2)
else collatz (1 + (n * 3)) ]
def fibs: int -> list int =
[ 0 -> cons 1 (cons 1 nil)
| n -> let ff = fibs (n-1) in
cons (head ff + (head (tail ff))) ff]
def main: (int, list int) =
let f = [(x,y) -> y] in
let p = (let n = 3 in (n, fibs n)) in f p