Slick
Submission details
REPL link:
https://repl.it/@SlickLang/slick
N.B. We have struggled getting our project to run on repl.it due to the OCaml REPLs being buggy. We hacked together a solution that is running in bash, but if it doesn't work, you can clone the repo and install Slick locally.
This language was developed for the language jam.
About Slick (reproduced below).
Type system (not completely up-to-date)
About Slick
Slick is a statically-typed, interpreted programming language.
It melds the type safety of languages like Haskell, OCaml, and Rust with the
versatility of languages like Python and Swift.
Slick is designed to be simple, concise, and safe. Below are some features that
demonstrate these values.
About the about
All of the code examples beginning with slick>
are invocations of the Slick
REPL. You can try them yourself!
The first line describes the input, and the second line is its output when run.
The output consists of two parts: the value returned and the inferred type,
separated by a colon.
slick> "hello, slick!"
"hello, slick" : String
First class functions
Most things in Slick are values, including functions.
slick> (\f -> f 3) (\x -> x + 2)
5 : Int
A lot of the code in Slick that you will write boils down to transforming one
value into another.
Powerful type inference
You don't need to declare types, Slick will infer them for you and ensure that
your programs are free of type mismatches.
slick> \f -> \x -> f (x+1)
<function> : ((Int -> α) -> (Int -> α))
For pratical purposes, you can ignore the type signatures if your program passes
type checking. Types in Slick are just a mechanism for catching mistakes.
slick> (\f -> \x -> f(x+1)) 5
! Type mismatch !
If you enjoy type signatures, you can check out how inference handles an example
like the strict Y combinator.
slick> \f -> (\x -> f (\v -> (x x) v)) (\x -> f (\v -> (x x) v))
<function> : (((α25 -> α26) -> (α25 -> α26)) -> (α25 -> α26))
Neat.
Flexible records
Records are like Objects in Javascript: they are maps from labels to values. In
Slick, record access is guaranteed safe by the type system.
slick> {x=1}.x
1 : Int
slick> {x=1}.y
! Type mismatch !
Records in Slick are flexible, meaning they can be extended with new values
slick> { {x=1} | y=3 }
{x = 2, y = 3} : {x : Int, y : Int}
And functions which expect records are happy with any record that has the fields
they need (provided those fields have the right type). So even though the record
below has an additional field y
, the type checker is fine with it.
slick> (\r -> r.x) {x=1,y=3}
1 : Int
Tags
For additional type safety, you can give any value a tag. This allows you to
safely separate data into semantic categories.
slick> \t -> case t: | Seconds s -> s | Minutes m -> 60 * m | Hours h -> 3600 * h
<function> : (⟦Seconds : Int, Minutes : Int, Hours : Int⟧ -> Int)
slick> (\t -> case t | Seconds s -> s | Minutes m -> 60 * m | Hours h -> 3600 * h) (Hours 2)
7200 : Int
This guarantees before your code is run that Seconds
, Minutes
, and Hours
are all treated differently, and the type checker rejects the input t
if it
isn't one of these categories.
slick> (\t -> case t: | Seconds s -> s | Minutes m -> 60 * m | Hours h -> 3600 * h) (Lightyears 30)
! Type mismatch !
Pattern matching
Putting the above together, Slick lets you pattern match on most variables.
def greet_person person:
case person:
| (Adult {age,job,name="Kye"}) -> "burger time"
| (Adult {age,job=(Programmer _),name}) -> "hello, world"
| (Adult _) -> "hello, adult"
| (Child _) -> "hello, child"
(REPL-friendly definition)
def greet_person person: case person | (Adult {age,job,name="Kye"}) -> "burger time" | (Adult {age,job=(Programmer _),name}) -> "hello, world" | (Adult _) -> "hello, adult" | (Child _) -> "hello, child"
For example, in the above case statement, the top branch will only match when
the person
is an Adult
whose name
is "Kye"
. Check it out.
slick> greet_person (Adult {age=20,job=Worker,name="Kye"})
“burger time” : String
slick> greet_person (Adult {age=21,job=Programmer,name="cole"})
“hello, world” : String
slick> greet_person (Adult {age=30,job=Worker,name="Bob"})
“hello, adult” : String
slick> greet_person (Child {age=5,name="Joe"})
“hello, child” : String
# Original submission before 12:00 AM 8/31 PT
Slick is a language we made for the jam.
Check it out [here](https://github.com/kwshi/slick/).
Authors:
@coleck @kshi
[This is the latest commit before 12:00 AM 8/31 PT](https://github.com/kwshi/slick/tree/607da5132a5e5c252ab31fbbdbbc80973098f7e5).
Check out our REPL here:
https://repl.it/@SlickLang/slick