Skip to content


๐ŸŒ‡ Cara is a programming language aiming to be pleasant to use and maintain while staying safe and dependable.


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.


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



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)

  |> quickSort
  |> IO.println!
#!/usr/bin/env cara

dst = IO.ask!("Enter destination filename: ")
dstHandle =!(dst, FS.Write)

timestampFmt = "hh:mm:ss.fff"

1..10 |> IO.forEach!(\i -> IO {
  time =!()
  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"

  |> 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,[])
    go([],bs) = Just(List.reverse(bs))
    go([a,],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])


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.

Running the compiler
git clone cara-compiler
cd cara-compiler

./run.ts end-to-end-tests/int/main.cara
./debug.ts end-to-end-tests/int/main.cara


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!)


As of Q1 2023, I (1) am still largely trying to design how the language will look and behave rather than implementing it.

  1. @janiczek

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)

  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!