ML
- OCaml 96.4%
- Zig 3%
- Nix 0.2%
- Emacs Lisp 0.2%
- C 0.2%
| .claude | ||
| bin | ||
| docs | ||
| emacs | ||
| examples | ||
| lib | ||
| runtime | ||
| stdlib | ||
| test | ||
| .envrc | ||
| .gitignore | ||
| .ocamlformat | ||
| CLAUDE.md | ||
| dune-project | ||
| flake.lock | ||
| flake.nix | ||
| README.md | ||
Amelie
Design
Amelie is a primarily functional language in the style of ML, but drawing inspiration from Rust, Haskell, Erlang, and Julia.
- Inferred types with mostly optional annotations
- Pascal/ML hybrid syntax
TODO LIST
- make jit default backend for repl
- finalizer trait
- value/reference semantics (future)
unboxedcurrently means only "inline this struct field" (a layout choice on Flat types); binding-level unboxed modes and the mode-analysis pass were removed for now- open question: a separate
ref/borrow concept for passing values around- box entails shared ownership
- ref entails borrow
- box coerce to ref by lending
- ref must be cloned to make a box
- GC + ref semantics
- moving GC breaks refs
- box can actually not be coerced to ref
- port runtime to a less deranged language
- fuzzing?
Syntax
- imperative programming
- docs in sigs
- try/try let or similar
- user annotations, derives
- multiline string literals
- string formatting
- how do we do formatting strings in a language without macros?
- type safety; an f-string defines an ad hoc record needed for interpolation
- basically just N things that are Show
- later; Debug, Binary, Hex
- f strings are closures (!)
- compile to fn() -> String
Type system
- clean up inference of interface/instances to use a more general unification concept
- currently ad hoc checks and manual substitutions
- ghetto row poly for tuple generalization
- kind checking pass to catch kind errors with a better error isntead of failing unification
- some kind of string, chars/bytes, list
- complex numbers
- associated types for interfaces
Standard Library
- persistent datastructures
- making them in amelie is a litmus test for the language
Module system
- packages vs. modules
- how is module hierarchy defined and how are modules named?
Codegen
- unboxed field layout (inline Flat struct fields; see llvm-roadmap Phase 6)
- make structless enums flat with repr u64
- tail calls
- stack traces?
Deranged Ideas
- Arity part of function identity
- Natural way to hide helper functions (pub fn sum/1 calls fn sum/2 with accumulator as an example)
- Makes (-)/1 and (-)/2 completely natural
- Num interface could define both, or (-1)/1 in terms of (-1)/2 and zero
AI
Claude Code has been used extensively as a sparring partner, and for generating the most tedious parts of the code, like the parser.
The core of the semantic analysis is based on a prior artisanal imlementation ™️ of the paper "Algorithm W Step by Step" (Martin Grabmüller) by myself.
The project has now taken on a sort of personal experiment of pushing vibe coding to the limit of what I'm comfortable with.