A pure, functional programming language inspired most by Haskell, but a bit by TypeScript.
Notable differences from Haskell:
- Sound, axiomatic type system with subtyping, higher kinded type synonyms, and infix type constructors.
- A focus on anonymous functions, with concise syntax for both value functions and type constructors.
id = a. a
type id = a. a
S = x y z. x z $ y z
type S = x y z. x z $ y z
- A focus on minimizing language features. For example, do-notation as well as
in
andwhere
expressions are dropped. - (Speculative) Algebraic effects to address the configuration problem.
- ECMAScript-like module system.
Notable features kept from Haskell:
- Lazy evaluation
- Typeclassing
- Curried by default
Worth mentioning:
- Emphasis on pipe operator
|
(type∀a b. a -> (a -> b) -> b
) - List types are
List a
instead of[a]
- "Batteries-included" prelude
- Point-free pattern matching by default (see Haskell's
\case
)
For example, Maybe
's constructors are Some
and None
. I like Maybe
more than
Option
since it is more distinctive (more searchable, filters down autosuggest more).
I like Some
and None
and I dislike Just
and Nothing
.
Add structurally typed records inspired by TypeScript.
- Syntax
person = {
name = 'Alex Generic'
birthdate = Date 1821 4 20
customerStatus = {
joined = Date 2024 02 10
loyaltyPoints = 140
balance = 12310
}
}
- Reading and updating
ageWhenJoined = person.customerStatus.joined - person.birthdate
// Speculative
withNewAge = person | update {
name = const 'Alex Generic I'
birthdate = (+1)
customerStatus = update {
loyaltyPoints = (+30)
}
}
- Typing
type Person = {
name: String
birthdate: Date
customerStatus: {
joined: Date
loyaltyPoints: Int
}
}
- Destructuring
type Quadratic = { a: Double, b: Double, c: Double }
y: Quadratic -> Double -> Double
y = { a, b, c } x. a * x ** 2 + b * x + c
Structural typing enables convenient subtype polymorphism, and tighter functions which don't require unused fields.
type Line = {
slope: Double
intercept: Double
}
slope l: Pick Line 'slope'. l.slope
Fun with unions, intersections and differences
type StructuralMaybe = a. {
type: 'some'
data: a
} + {
type: 'none'
}
type StructuralSome = a. StructuralMaybe a & { type: 'some' }
type StructuralNone = StructuralMaybe () \ StructuralSome ()
Top and bottom too.
type Id = a. (a & unknown) + never
Time complexity for property access is currently undefined.
- Recommended practice for orphan instances
- Optional fields in records
- Type union operator.
|
is taken for the pipe function, and union is not divisible as+
would imply.
- Transparent RPC
- Algebraic effects