An experimental functional language
Pure code.
Explicit effects.
A strict, purely functional language inspired by Elm, Haskell and Koka: type inference, algebraic effects, structured concurrency and metaprogramming. Programs compile to Go.
Experimental: the language is still changing.
1effect Prompt2 ask : String -> Int3 say : String -> ()45guess : Int ->{Prompt} ()6guess secret =7 n = ask "Your guess: "8 if n == secret then9 say "Correct!"10 else11 say (if n < secret then "Higher" else "Lower")12 guess secretAlgebraic effects.
Effects are part of function types, like a ->{Console} b, and handlers decide what they mean. Code stays in direct style.
Structured concurrency.
Spawn native tasks, await their results and communicate through channels. Scopes drain their children; cancellation is cooperative.
Metaprogramming.
Splices run hygienic, pure Fango code at compile time. Reflect on types and write your own derivers.
Small on purpose.
One compiler, local source modules and a bundled standard library. The implementation is kept small enough to read and change.
A short tour
What Fango looks like.
Data and patterns.
Unions and records, taken apart with case. Types are inferred, so total needs no annotation, and every match must cover all cases.
type Tree a = Leaf a | Branch (Tree a) (Tree a) deriving (Show)total tree = case tree of Leaf n -> n Branch left right -> total left + total rightmain() = print (total (Branch (Leaf 1) (Branch (Leaf 2) (Leaf 3))))Effects and handlers.
An effect declares operations, and code calls them like functions. The handler decides what ask means and continues the computation with resume.
effect Ask ask : () -> Stringgreeting _ = "Hello, #{ask ()}"main() = print (handle greeting () on ask () -> resume "Fango" return text -> text)Structured concurrency.
Spawn native tasks inside an Async.run scope. The runner waits for its children and reports completion, application failure or cooperative cancellation.
import Async exposing (Async)jobs : () ->{Async} (Int, Int)jobs() = first = Async.spawn { 20 + 1 } second = Async.spawn { 7 * 3 } (Async.await first, Async.await second)main() = print (Async.runOutcome jobs)Metaprogramming.
A deriver teaches deriving about your own classes. It runs at compile time, reflects on the type’s constructors, and generates the instance.
import Metaclass Tag a tag : a -> Stringderiver Tag tag subject valueCode = Meta.match subject valueCode { bound -> Meta.lift bound.ctor.name }type Colour = Red | Green Int deriving (Tag)main() = print (tag (Green 3)) -- GreenDocumentation
Read the docs.
An installation guide and the complete reference: the language, the standard library, and the concurrency runtime.
Install
Build from source.
Fango is experimental: the language and standard library still change. Building it requires Go 1.26:
$ git clone https://github.com/waj/fango.git
$ cd fango
$ make build
$ ./fango run examples/guess.fango


