CoffeeScript-syntax AffineScript. Significant whitespace, arrow functions, postfix conditionals, @ shorthand — and behind the surface, affine resource guarantees and typed-wasm output.
CafeScripto is AffineScript with its cafe face pre-selected. CoffeeScript developers will recognise: (args) → body arrows, @x for self, unless and until, postfix if / unless, Yes/No/On/Off literal aliases, line comments, ## block comments, and significant indentation.
This repo is a brand surface only. The compiler lives in affinescript. This repo carries:
-
Examples idiomatic to CoffeeScript developers
-
A
cafeshim CLI that aliasesaffinescript --face cafe -
Migration guides for CoffeeScript codebases (most have already migrated to JS / TS, but the syntax is still beloved by some)
examples/hello.affine:
# face: cafescripto
###
Distinctive features exercised below:
- `#` line comments and `###` block comments
- paren-arrow `(args) -> body`
- bare-arrow `-> body`
- Yes/No/On/Off literal aliases
###
effect IO {
fn println(s: String) -> ();
}
fn main() -{IO}-> () {
let greeting = "Hello, CafeScripto!";
let ready = Yes;
println(greeting);
}opam install affinescript
git clone https://github.com/hyperpolymath/cafescripto
cd cafescripto# Direct, via affinescript:
affinescript eval --face cafe examples/hello.affine
affinescript compile --face cafe examples/hello.affine -o hello.wasm
# Or via the cafe shim:
./bin/cafe eval examples/hello.affine
# Or via the justfile:
just run examples/hello.affine
just preview examples/hello.affine # show the canonical loweringSource files use the canonical .affine extension. The face is selected by the # face: cafescripto pragma on the first comment line, or by the --face cafe flag.
CafeScripto is one of six established faces over the AffineScript core:
-
AffineScript — the canonical face
-
RattleScript — Python-style
-
JaffaScript — JavaScript / TypeScript-style
-
LucidScript — PureScript / Haskell-style
-
CafeScripto — CoffeeScript-style (this repo)
-
PseudoScript — pseudocode-style
CoffeeScript peaked in 2014 and most of its population migrated to TypeScript or vanilla JavaScript years ago. CafeScripto isn’t a mass-market acquisition play; it’s a category-builder, and a comfortable destination for developers who liked CoffeeScript’s syntax aesthetics and want it back, but with stronger guarantees and a real runtime story (typed-wasm everywhere).
Some CoffeeScript surface features need AST-level rewrites that the text-to-text face transformer doesn’t yet handle:
-
List comprehensions (
(x*2 for x in xs when x>0)) -
No-paren calls (
f x, y) -
Splat / destructuring (
…args) -
String interpolation (
"Hello, #{name}")
These are tracked in the affinescript faces README. Until they land, write the explicit forms (.map / .filter, paren-everything calls, explicit string concat).
Alpha. The face transformer is implemented in affinescript/lib/cafe_face.ml (added in commit 74024c6).