Powerful, Declarative, Functional.

Halcyon packs the expressive power of polymorphism, traits, and higher-kinded types into an elegant and readable syntax.

example.hc
bundle temperature

let farenheit_to_celcius =
  fn temp => (temp - 32.0) / 1.8

do readln "Enter a temperature in Farenheit: "
      |> parse
      +> farenheit_to_celcius
      +> show
      +> prepend "The tempareture in Celcius is: "
      |> unwrap_or "Input must be a number"
      |> println
fn

ML traditions

Inspired by and built upon decades of research in ML family languages

do

Side effectful

Functional where its useful, imperative where its necessary

|

Strong typing

ADT's, polymorphism, traits, higher kinded types, its all here

::

Smart type inference

Constraint-based type system that lets you focus on the logic, not the types

>>

Portable anywhere

Compile to WebAssembly, execute anywhere; from the browser, to embedded devices

[]

Prioritizing safety

Garbage collection and bracketed I/O give your program strong guardrails

Language Features

Built for clarity

Algebraic Data Types

Model your domain with sum types. The compiler checks that every case is handled, catching bugs before your code ever runs.

example.hc
type Expr =
  | Lit Integer
  | Add (Expr, Expr)
  | Mul (Expr, Expr)

let eval = fn
  | Lit n       => n
  | Add (lhs, rhs) => eval lhs + eval rhs
  | Mul (lhs, rhs) => eval lhs * eval rhs

-- (2 + 3) * 7
do eval (Mul (Add (Lit 2) (Lit 3)) (Lit 7))
  |> show |> println

Traits

Define shared behavior across types. Trait constraints let you write generic code that works with any type implementing the right interface.

example.hc
trait Area: a =
  let area: a -> Real
end

type Circle = Real
type Rect = (Real, Real)

impl Area for Circle =
  let area = fn | Circle r => 3.14159 * r * r
end

impl Area for Rect =
  let area = fn | Rect (w, h) => w * h
end

do Circle 5.0
  |> area
  |> show
  |> println

Higher Kinded Types

Abstract over type constructors like Option and Array. Write a function once and reuse it with any container that shares the same structure.

example.hc
-- +> maps over containers
let a = Some 21 +> (fn n => n * 2)
let b = [1, 2, 3] +> (fn n => n * 2)

do show a |> println   -- Some 42
do show b |> println   -- [2, 4, 6]

-- sequence flips containers inside-out
let c = sequence [Some 1, Some 2, Some 3]
let d = sequence [Some 1, None, Some 3]

do show c |> println   -- Some [1, 2, 3]
do show d |> println   -- None

Install

Get Halcyon

Available for Linux, macOS, and Windows. Requires a WebAssembly runtime.

$ TODO