Skip to content

Repository files navigation

Goop banner

CI status Latest release License

Goop

OCaml-style safety on Go’s runtime.

  • Exhaustive ADTs and pattern matching
  • Branded IDs (single-ctor ADTs) so order_idsymbol
  • Go interop and deploy — same runtime, stdlib, and binaries
  • Cache-only builds — edit .goop, run goop build / goop test

Non-exhaustive match (EXHAUST003)

type OrderAck =
  | Filled of { order_id: string; qty: int }
  | Rejected of { reason: string }
  | PartialFill of { order_id: string; filled: int; remaining: int }

let handleAck (ack: OrderAck) : string =
  match ack with
  | Filled { order_id; qty } -> order_id
  | Rejected { reason } -> reason
  (* forgot PartialFill — Go compiles; Goop does not *)
✕ EXHAUST003: non-exhaustive match: missing constructor(s): PartialFill

Getting started

cd src && go build -o ../goop ./cmd/goop
../goop check docs/examples/hello.goop
../goop build docs/examples/hello.goop   # → ./goop-out (Go stays in $GOOP_HOME/build)
./goop-out
../goop test tests/

Generated .go never lands in your project tree by default. See CLI artifacts · tutorial.

How Goop compares

Compile-time checks that Go leaves to tests, panics, or -race. Style: STYLE.md.

Safety feature Go Rust OCaml Goop
Sum types + exhaustive match
No null by default (option)
Branded IDs (single-ctor ADT)
Effect handlers (OCaml 5-style) ✅ (CPS-lowered)
Nil channel misuse ❌ (runtime) N/A N/A ✅ (NIL001)
Data race detection ⚠️ -race ✅ (linear, conservative)
Refinement / contracts ⚠️ ⚠️ ✅ VC + optional Z3
Native Go stdlib + deploy

Go interop

Call Go packages, implement Go interfaces in Goop, and embed Go when needed:

module main

import go "strings" {
  val ToUpper : string -> string
}

@[go] {
  func greet(name string) string {
    return "Hello, " + name + "!"
  }
}
val greet : string -> string

let main () : unit =
  print_line (greet (ToUpper "goop"))

import go / import goop · implements · Go methods/fields · @[go] / @[c] embeds. Examples: extern_demo.goop · go_method_calls.goop · go_implements_slog_handler.goop.

Language & status

Everyday surface: STYLE.md · docs/examples/.

Current: v1.8.0 — cache-only goop build / compile under $GOOP_HOME/build, with transitive import goop deps. Prior highlights: Go struct/slog FFI (1.7), cross-package libraries (1.6), call lowering (1.5). Full history: CHANGELOG · RELEASE_NOTES.

FAQ

Production-ready? The compiler, checker, codegen, LSP, and e2e suite ship and are exercised in CI. Some OCaml corners are pragmatic subsets; we are not claiming production load readiness yet.

Borgo / Dingo? Goop is a full compiler with OCaml-aligned syntax and compile-time safety for gradual Go migration. Dingo-style ? and F# computation expressions were removed in 1.0.

Need OCaml or Z3? No. Pattern matching from Rust/Swift/Kotlin transfers. Z3 is optional ([check] smt = true).

Documentation

Resource Link
Tutorial Getting started through concurrency
Stdlib Prelude, builtins, std.*
Design STYLE, CLI artifacts, FFI
Examples Runnable; CI goop check
Contributing Build and test workflow

License

MIT / Apache-2.0 dual license.

About

Goop Lang: OCaml-style safety on Go’s runtime.

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages