Skip to content

Commit 673f364

Browse files
hyperpolymathclaude
andcommitted
docs(readme): convert README.adoc -> Markdown README.md
README must be real Markdown to render in GitHub community-health, the GitHub profile, and external MCP directories (Glama) — AsciiDoc shows as raw markup there. pandoc asciidoc->GFM, badges fixed to clickable, SPDX header kept as an HTML comment, duplicate README.adoc removed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 8772a9b commit 673f364

2 files changed

Lines changed: 158 additions & 109 deletions

File tree

README.adoc

Lines changed: 0 additions & 109 deletions
This file was deleted.

README.md

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
<!--
2+
SPDX-License-Identifier: CC-BY-SA-4.0
3+
SPDX-FileCopyrightText: 2025-2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
4+
-->
5+
6+
[![License: MPL-2.0](https://img.shields.io/badge/License-MPL_2.0-blue.svg)](https://opensource.org/licenses/MPL-2.0)
7+
8+
CoffeeScript-syntax AffineScript. Write code that looks like
9+
CoffeeScript — significant whitespace, ``/`` arrows, `@` for self,
10+
`unless`/`until`, postfix conditionals, `Yes`/`No`/`On`/`Off` — and get
11+
affine resource guarantees and typed-wasm output.
12+
13+
# What it is
14+
15+
CafeScripto is
16+
[AffineScript](https://github.com/hyperpolymath/affinescript) with its
17+
`cafe` face pre-selected. If you wrote CoffeeScript, you already know
18+
the surface: `(args)` `` `body` and `` `body` arrows, `@x` shorthand
19+
for self, `unless` and `until`, postfix `if` / `unless`,
20+
`Yes`/`No`/`On`/`Off` literal aliases, `#` line comments, `###` block
21+
comments, and significant indentation. The compiler checks that your
22+
resources (files, sockets, tokens, handles) are used **exactly as many
23+
times as you declare** — and proves it at compile time. No null pointer
24+
exceptions. No use-after-free. No silent data races. No GC overhead.
25+
26+
This repo is a **brand surface only**. The compiler, type checker,
27+
borrow checker, and codegen all live in
28+
[affinescript](https://github.com/hyperpolymath/affinescript). This repo
29+
carries:
30+
31+
- Examples idiomatic to CoffeeScript developers
32+
33+
- Documentation aimed at the CoffeeScript community
34+
35+
- A `cafe` shim CLI that aliases `affinescript` `--face` `cafe`
36+
37+
- Tutorial and migration guides for moving CoffeeScript-shaped code into
38+
a strongly-typed, affine-typed, WASM-targeting world
39+
40+
# Hello
41+
42+
`examples/hello.affine`:
43+
44+
```affine
45+
# face: cafescripto
46+
47+
effect IO {
48+
fn println(s: String) -> ();
49+
}
50+
51+
fn main() -{IO}-> () {
52+
let greeting = "Hello, CafeScripto!";
53+
let ready = Yes;
54+
println(greeting);
55+
}
56+
```
57+
58+
``/`` arrows, `@` for self, `unless`/`until`, postfix `if`,
59+
`Yes`/`No`/`On`/`Off` — all lower to canonical AffineScript and produce
60+
the same typed-wasm output as every other face.
61+
62+
# Install
63+
64+
```bash
65+
opam install affinescript
66+
git clone https://github.com/hyperpolymath/cafescripto
67+
cd cafescripto
68+
```
69+
70+
The `affinescript` binary does the work. The `bin/cafe` shim in this
71+
repo just defaults the `--face` flag.
72+
73+
# Use
74+
75+
```bash
76+
# Direct, via affinescript:
77+
affinescript eval --face cafe examples/hello.affine
78+
affinescript compile --face cafe examples/hello.affine -o hello.wasm
79+
80+
# Or via the cafe shim (same thing):
81+
./bin/cafe eval examples/hello.affine
82+
./bin/cafe compile examples/hello.affine -o hello.wasm
83+
84+
# Or via the justfile:
85+
just run examples/hello.affine
86+
just preview examples/hello.affine # show the canonical lowering
87+
```
88+
89+
Source files use the canonical `.affine` extension. The face is selected
90+
by the `#` `face:` `cafescripto` pragma on the first comment line, or by
91+
the `--face` `cafe` flag.
92+
93+
# Different faces, same cube
94+
95+
CafeScripto is one of six established faces over the AffineScript core:
96+
97+
- AffineScript — the canonical face
98+
99+
- [RattleScript](https://github.com/hyperpolymath/rattlescript)
100+
Python-style
101+
102+
- [JaffaScript](https://github.com/hyperpolymath/jaffascript)
103+
JavaScript / TypeScript-style
104+
105+
- [LucidScript](https://github.com/hyperpolymath/lucidscript)
106+
PureScript / Haskell-style
107+
108+
- **CafeScripto** — CoffeeScript-style (this repo)
109+
110+
- [PseudoScript](https://github.com/hyperpolymath/pseudoscript)
111+
pseudocode-style
112+
113+
All six share the canonical `.affine` extension and lower to the same
114+
AST. Errors are reported in face-appropriate vocabulary.
115+
116+
# Why CafeScripto
117+
118+
CoffeeScript gave a generation of developers a coherent syntax
119+
aesthetic: significant whitespace, ``/`` arrows, `@` for self,
120+
`unless`, postfix conditionals, and the `Yes`/`No`/`On`/`Off` literals.
121+
That community never loved JavaScript, and when the ecosystem moved on
122+
to TypeScript and vanilla JS they were forced off the syntax they
123+
preferred. CafeScripto is a home for them — the same surface aesthetics,
124+
but resting on a sound type system, affine resource semantics, effect
125+
tracking, and portable typed-wasm output rather than untyped JavaScript.
126+
127+
For a CoffeeScript developer moving in, the path looks like:
128+
129+
1. Keep your `` / `` arrows, `@` shorthand, `unless` / `until`, and
130+
postfix conditionals — the face accepts them and lowers them to
131+
canonical AffineScript.
132+
133+
2. Add `#` `face:` `cafescripto` at the top of each `.affine` file.
134+
135+
3. Type-annotate your function signatures (CoffeeScript had none;
136+
AffineScript wants them, but they buy you the whole-program
137+
guarantees).
138+
139+
4. Keep writing `Yes`/`No`/`On`/`Off` — the face maps them to canonical
140+
boolean literals.
141+
142+
5. Compile to typed-wasm; the output runs in browsers, Node, Deno,
143+
Wasmtime, and any WASI runtime.
144+
145+
# Status
146+
147+
Alpha. The face transformer is implemented in
148+
`affinescript/lib/cafe_face.ml`. Known limitations are tracked in [the
149+
affinescript faces
150+
README](https://github.com/hyperpolymath/affinescript/blob/main/examples/faces/README.adoc)
151+
under "Known transformer gaps".
152+
153+
# License
154+
155+
This project is licensed under the Mozilla Public License, v. 2.0. See
156+
the `LICENSE` file for details. Documentation is licensed CC-BY-SA-4.0.
157+
158+
SPDX-License-Identifier: CC-BY-SA-4.0

0 commit comments

Comments
 (0)