Cara¶
Cara is a programming language aiming to be pleasant to use and maintain while staying safe and dependable.
Warning
Cara is in development: @janiczek is still figuring out the design, syntax and functionality. In the meantime, some code snippets can be found in the compiler's end-to-end test suite on GitHub.
Features¶
To put it shortly, Cara combines:
Elm and its safety, maintainability and friendliness
Haskell and its brevity and power (in moderation)
Kotlin and its familiarity and syntax sugar
INTERCAL and its... just kidding!
Here is an incomplete list of Cara's features:
- General-purpose
- Compiled to automatically parallel native code via HVM...
- ...or interpreted (handy for scripting)
- Immutable
- Purely functional
- Familiar ALGOL-like syntax
- Statically typed with automatic type inference
- ADTs with exhaustive pattern matching
Examples¶
Tip
There is a large sampling of Cara programs in the end-to-end test suite.
quickSort(List[Int]): List[Int]
quickSort([]) = []
quickSort([x,...xs]) = {
(lt, gt) = List.partition(#(x >= _), xs)
quickSort(lt) ++ x ++ quickSort(gt)
}
[5,1,3,2,4]
|> quickSort
|> IO.println!
#!/usr/bin/env cara
dst = IO.ask!("Enter destination filename: ")
dstHandle = FS.open!(dst, FS.Write)
timestampFmt = "hh:mm:ss.fff"
1..10 |> IO.forEach!(\i -> IO {
time = Time.now!()
dstHandle |> FS.write!("[${Time.format(timestampFmt, time)}] Hello number $i\n")
})
fizzbuzz(n) =
if n % 15 == 0 then "FizzBuzz"
else if n % 3 == 0 then "Fizz"
else if n % 5 == 0 then "Buzz"
else "$n"
1..20
|> List.map(fizzbuzz)
|> String.join(", ")
|> IO.println!
type Maybe[a] =
| Nothing
| Just(a)
traverse(fn: a -> Maybe[b], list: List[a]): Maybe[List[b]]
traverse(fn,list) = go(list,[])
where
go([],bs) = Just(List.reverse(bs))
go([a,...as],bs) =
case fn(a) of
Nothing -> Nothing
Just(b) -> go(as,b++bs)
xs = [1,2,3,4,5]
ys = [6,7,8,9,10]
f = \n -> if n == 3 then Nothing else Just(n)
IO.println!(xs |> traverse(f)) // -> Nothing
IO.println!(ys |> traverse(f)) // -> Just([6,7,8,9,10])
Installation¶
Right now the language tooling is very rough around the edges: if you want to try the language out, you'll need to git clone
the compiler repository.
You'll need Deno to run the compiler.
git clone https://github.com/cara-lang/compiler cara-compiler
cd cara-compiler
./run.ts end-to-end-tests/int/main.cara
./debug.ts end-to-end-tests/int/main.cara
./test.ts
Tip
The .ok
files across the Cara repositories are generally a good way to get an idea of how to work with the repositories. (Shout out to @secretGeek's ok
tool!)
Contribute¶
As of Q1 2023, I (1) am still largely trying to design how the language will look and behave rather than implementing it.
If you'd like to discuss it, feel free to open a GitHub issue or send me a message on Twitter or Mastodon. I do want to keep some creative freedom so I won't promise this will be "design by commitee" nor any kind of democracy, but I would be very happy to hear your opinions, experience and tales from the trenches! (1)
- "This will be impossible to parse because XYZ!"
If you instead want to contribute to the documentation (this website), feel free to head over to the website repo and make a PR or an issue!