ludic/kw-enum.html
2026-09-17 22:10:03 +00:00

56 lines
No EOL
4.4 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>enum — Ludic</title>
<meta name="description" content="A named set of integer constants — names for a magic-number space.">
<link rel="stylesheet" href="base.css">
<link rel="stylesheet" href="docs.css">
</head>
<body>
<header class="nav"><div class="wrap nav-in"><a class="brand" href="index.html"><span class="logo">L</span> Ludic</a><button class="nav-toggle" aria-label="Toggle menu" aria-expanded="false">☰</button><nav class="nav-links"><a href="index.html">Home</a><a href="api.html">API Reference</a><a class="nav-cta" href="https://git.workshopsoft.io/workshopsoft/ludic">Source ↗</a></nav></div></header>
<main class="wrap item">
<div class="crumbs"><a href="api.html">API Reference</a> <span>›</span> <a href="api.html#structure">Program structure</a> <span>›</span> <span class="here">enum</span></div>
<div class="item-head">
<span class="kind-badge kind-keyword">keyword</span>
<h1 id="top">enum</h1>
</div>
<code class="sig">enum Name { A, B, C }</code>
<div class="desc"><p>An <code>enum</code> gives names to a set of related integer values so a magic-number space — a menu selection, a game mode, a machine state — reads as names instead of bare literals. Variants number themselves from <code>0</code> in declaration order, and you access one as <code>Name.Variant</code>, which is a compile-time <code>int</code> usable anywhere an int is: in <code>match</code> patterns, comparisons, and assignments. When every variant is a bare name, an enum value lives in an ordinary <code>int</code> or <code>var</code> and is saved with it, so a plain <code>enum</code> is best understood as a zero-cost naming layer over <code>int</code>.</p><p>## Tagged unions — variants with payloads</p><p>A variant may also carry a **payload**, written as a parenthesized list of types after its name. Doing so turns the whole enum into a *tagged union*: a value is now one of several shapes, each with its own data, and the type remembers which.</p><p>You **construct** a variant by name — <code>Door(3)</code>, <code>Portal(x, y)</code>, or bare <code>Empty</code> for a payload-less one — and store or pass it as a value of the enum's type (<code>let t: Tile = Door(3)</code>). Each value is a small boxed record: a tag naming the variant, plus its payload.</p><p>You take one apart with <code>match</code>, binding the payload names in each arm:</p><p>A tagged <code>match</code> must be **exhaustive**: it either handles every variant or ends with a <code>_</code> catch-all. Leaving a variant out is a compile-time error (<code>match on Tile is not exhaustive: variant Door is unhandled</code>), so adding a new variant surfaces every site that must learn about it. Constructor and pattern arities are checked the same way. A plain (all-bare) enum keeps its compile-time-ordinal <code>Name.Variant</code> form and is unaffected.</p></div>
<div class="examples"><h2>Example</h2><pre data-lang="ludic">enum Tile { Empty, Wall, Door(int), Portal(int, int) }</pre><pre data-lang="ludic">function walk_cost(t: Tile) -&gt; int {
match t {
Empty =&gt; { return 1 }
Wall =&gt; { return 0 }
Door(n) =&gt; { return 10 + n } # n is the door's int payload
Portal(x, y) =&gt; { return x + y } # both fields bound in this arm
}
}</pre><pre data-lang="ludic">program BattleMenu {
enum Action { Attack, Guard, Item, Flee }
var current_action: int = Action.Attack
handler ChooseAction phase Input {
let pressed = Input.key()
if pressed == 'a' { current_action = Action.Attack }
if pressed == 'g' { current_action = Action.Guard }
if pressed == 'f' { current_action = Action.Flee }
}
handler DrawWorld phase Render {
Screen.clear(Color.MidnightBlue)
match current_action {
Action.Attack =&gt; Screen.draw_text(x: 8, y: 8, text: "ATTACK", color: Color.Crimson, scale: 2)
Action.Guard =&gt; Screen.draw_text(x: 8, y: 8, text: "GUARD", color: Color.White, scale: 2)
_ =&gt; Screen.draw_text(x: 8, y: 8, text: "FLEE", color: Color.Gold, scale: 2)
}
Screen.show()
}
}</pre></div>
<a class="back" href="api.html">← All symbols</a>
</main>
<script src="ludic-highlight.js"></script>
<script>Ludic.highlightAll(); Ludic.installCards(); Ludic.flashTarget();</script>
</body></html>