Henk

A high-performance implementation of the Pure Type System (Calculus of Construction) with extraction to Erlang/OTP, featuring Church-encoded IO monads and comonad machines. Henk is peer reviewed by American Institute of Physics in 2018: https://doi.org/10.1063/1.5045439.

Abstract

Henk is a minimal yet powerful functional programming language based on the top vertice of Henk Barendregt's λ-Cube — Pure Type System (or Thierry Coquand's Calculus of Inductive Constructions). It implements the λPω logic, similar to Morte, but uses countable universes and a friendly Miranda-style syntax. Henk serves as an intermediate minimal fibrational proto language for the whole Groupoid Infinity stack, providing a sound foundation for theorem proving in higher languages with general induction principle like Frank and Christine.

Key features include Church encoding of all inductive data types, a robust FFI system for Erlang integration, and native support for Let-bindings and Case-expressions to bridge the gap between pure PTS and practical execution for constrained environments.

Multilingual Core

Henk supports multiple surface syntaxes, allowing for both higher-level mathematical modeling and low-level lambda programming.

AUT-68 (Automath)


Original AUT-68 by Nikolaas Govert de Bruijn. Designed for low-level Calculus of Construction programming and formal mathematical verification.

-- head
(a: *) (xs: [email protected] a) xs ([email protected] a)
((x: a) (_: [email protected] a) Maybe.Just.main a x)
(Maybe.Nothing.main a)

-- foldr
(a: *) (b: *) (f: [x: a] [y: b] b) (z: b) (xs:
[List: *] [Cons: [head: a] [tail: List] List]
[Nil: List] List) xs ([List: *] [Cons: [head:
a] [tail: List] List] [Nil: List] List) ((head:
a) (tail: b) f head tail) z

-- map
(a: *) (b: *) (f: [_ : a] b) (xs: [List: *] [Cons:
[head: a] [tail: List] List] [Nil: List] List) xs
([List: *] [Cons: [head: b] [tail: List] List]
[Nil: List] List) ((head: a) (tail: [List: *]
[Cons: [head: b] [tail: List] List] [Nil: List]
List) (List: *) (Cons: [head: b] [tail: List]
List) Nil: List) Cons (f head)(tail List Cons Nil))
((List: *) (Cons: [head: b] [tail: List] List)
(Nil: List) Nil)

Minimalist, binder-driven syntax for categorical foundational proofs.

Miranda-style


Miranda by David Turner. The root of Haskell-like languages, optimized for higher programming purposes and readability.

module Data.List where

head x = case x of
    Nil  -> Nothing
    Cons h t -> Just h

foldr f z xs = case xs of
    Nil      -> z
    Cons h t -> f h t

map f xs = case xs of
    Nil      -> Nil
    Cons h t -> Cons (f h) t

Familiar, expressive syntax for practical functional engineering.

Proven Semantics

Compact Formal Core

The core of Henk consists of 5 fundamental AST nodes of the single type called Dependent Type Pi, the fibrational generalization of functions from algebraic geometry:

type term =
  | Var of name
  | Universe of level
  | Pi of name * term * term
  | Lam of name * term * term
  | App of term * term

Operational Semantics

Henk leverages Definition Equality and β-reduction. Inductive types are represented as their own elimination principles (Church encoding). The compiler performs type erasure on Universes and Pi types, extracting pure runtime terms to Erlang Abstract Format.

Infinitary I/O

Henk supports two distinct models of side-effects, both purely represented within the Type System.

Recursive (Monad)


The Monadic IO model uses a Church-encoded Free Monad. It is suitable for sequential imperative-style programs.

module Test.Recursive where
import Control.IO

echo = io_bind io_get_line (\s -> io_put_line s)

main = replicate_io five echo

Corecursive (Comonad)


The Comonadic IOI model represents IOI as an infinite state machine (anamorphism). It is the canonical model for long-running servers.

module Test.Corecursive where
import Control.IOI

step m = case m of
    Nothing -> iof_get_line_f (\s -> Just Any s)
    Just s  -> iof_put_line_f s (Nothing Any)

main = mk_io Any (Maybe Any) (Nothing Any) step

Continuous Practicum

$ mix henk.base --syntax=miranda
Compiling Henk base library...
  Compiling [miranda] priv/henk/Control/IO.henk -> Control.IO... OK
  Compiling [miranda] priv/henk/Control/IOI.henk -> Control.IOI... OK
  Compiling [miranda] priv/henk/Data/Bool.henk -> Data.Bool... OK
  Compiling [miranda] priv/henk/Data/Fin.henk -> Data.Fin... OK
  Compiling [miranda] priv/henk/Data/List.henk -> Data.List... OK
  Compiling [miranda] priv/henk/Data/Maybe.henk -> Data.Maybe... OK
  Compiling [miranda] priv/henk/Data/Nat.henk -> Data.Nat... OK
  Compiling [miranda] priv/henk/Data/Prod.henk -> Data.Prod... OK
  Compiling [miranda] priv/henk/Prelude.henk -> Prelude... OK

Henk base library compilation finished.
$ mix henk.repl --syntax=miranda
🧊 Henk Programming Language version 11.3.15 [miranda syntax]
Copyright (c) 2015-2026 Groupoid Infinity
https://groupoid.github.io/henk/

miranda> :eval map
TYPE: (f : Any) -> (xs : Any) -> Any
TERM: \f -> \xs -> xs Any Nil (\h -> \t -> Cons (f h) t)
miranda> :check map
TYPE: (f : Any) -> (xs : Any) -> Any
miranda> map id
= \xs -> xs Any Nil (\h -> \t -> Cons (id h) t)
miranda> :eval map id [1]
TYPE: Any
TERM: \x2 -> \R -> \nil -> \cons -> cons (Nil Any) x2
miranda>
        

Open Source

GitHub Logo