mirror of
https://github.com/hi-language/hi-language.github.io.git
synced 2026-01-14 08:38:36 +00:00
Feat: 1p intro w/ markdownit+hljs+lucide
This commit is contained in:
412
index.html
412
index.html
@@ -1,119 +1,327 @@
|
|||||||
<!doctype html><html lang=en>
|
<!doctype html><html lang=en>
|
||||||
<head>
|
<head>
|
||||||
<meta charset=utf-8>
|
<meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1">
|
||||||
<meta name=viewport content="width=device-width,initial-scale=1,viewport-fit=cover">
|
<title>Hi — a tiny, symbolic, AI‑first language</title>
|
||||||
<title>Hi — a tiny, symbolic, AI-first programming language</title>
|
|
||||||
<link rel=preconnect href=https://fonts.googleapis.com>
|
<link rel=preconnect href=https://fonts.googleapis.com>
|
||||||
<link rel=preconnect href=https://fonts.gstatic.com crossorigin>
|
<link rel=preconnect href=https://fonts.gstatic.com crossorigin>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;800&family=Fira+Code:wght@400;600&display=swap" rel=stylesheet>
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;800&family=JetBrains+Mono:wght@300;400;600&display=swap" rel=stylesheet>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<link rel=stylesheet href=https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/5.5.1/github-markdown.min.css integrity=sha512-ig3uzadlU/hJ2SXiczY2h5D7J26fI6z6mDbcf0sApsWsOqgSmnNoZiH+4rUrka+tp68Q2mEwMpsv/u+8mewaJQ== crossorigin=anonymous referrerpolicy=no-referrer>
|
||||||
<link rel=stylesheet href="https://cdn.jsdelivr.net/npm/github-markdown-css@5.8.1/github-markdown-light.min.css">
|
<link rel=stylesheet href=https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github.min.css integrity=sha512-3mb8zCey3p+3w0lI04lH8mKeb4d0x1c6PXo2g0Q9yQkQhy/c6v2dGEZ7V6o0H6YugyS0r5uEIAJ0u8oHNoq6tA== crossorigin=anonymous referrerpolicy=no-referrer>
|
||||||
<link rel=stylesheet href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.11.1/build/styles/github.min.css">
|
|
||||||
<style>
|
<style>
|
||||||
:root{color-scheme:light}
|
:root{--bg:radial-gradient(1200px 600px at 70% -20%,#d9e6ff22,transparent),radial-gradient(1000px 500px at 10% -10%,#ffd9f022,transparent),linear-gradient(#fafbff,#f7f9ff);--bgD:radial-gradient(1200px 600px at 70% -20%,#2a335522,transparent),radial-gradient(1000px 500px at 10% -10%,#4a234422,transparent),linear-gradient(#0c0f13,#0a0d10)}
|
||||||
*{box-sizing:border-box}
|
*{box-sizing:border-box}
|
||||||
html,body{height:100%}
|
html,body{height:100%}
|
||||||
body{font-family:Inter,ui-sans-serif,system-ui,Segoe UI,Roboto,Apple Color Emoji,Noto Color Emoji,Arial,Helvetica,sans-serif}
|
html{color-scheme:light dark}
|
||||||
code,pre,.font-mono{font-family:"Fira Code",ui-monospace,Menlo,Consolas,monospace}
|
body{margin:0;font:400 13.25px/1.55 Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial,Noto Sans,Apple Color Emoji,Segoe UI Emoji,sans-serif;background:var(--bg)}
|
||||||
.markdown-body{font-size:12px;line-height:1.6}
|
@media (prefers-color-scheme:dark){body{background:var(--bgD)}}
|
||||||
.markdown-body pre{overflow:auto}
|
.markdown-body{font-size:12.6px;max-width:920px;padding:64px 18px 80px;margin:0 auto;color:inherit}
|
||||||
.copy-btn{position:absolute;top:.4rem;right:.4rem;font-size:10px;padding:.125rem .375rem;border-radius:.375rem;background:rgba(17,17,17,.9);color:#fff}
|
code,kbd,pre,samp{font-family:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:12px}
|
||||||
pre{border:1px solid #e5e7eb;border-radius:.5rem;position:relative}
|
header{position:sticky;top:8px;z-index:9;display:grid;place-items:center;height:0}
|
||||||
.hero-grad{--g:radial-gradient(60% 60% at 50% 40%,rgba(120,119,198,.15),rgba(255,255,255,0) 60%);background:
|
#brand{pointer-events:none;user-select:none;letter-spacing:.5px;font:700 13px/1 Inter;padding:8px 16px;border-radius:999px;background:linear-gradient(180deg,#fff,#f5f5f5);border:1px solid #e1e4e8;box-shadow:0 1px 0 rgba(0,0,0,.02),0 12px 24px -16px rgba(0,0,0,.2);color:#111}
|
||||||
var(--g),conic-gradient(from 180deg at 50% 50%,#f0f5ff,#fff,#f0f5ff)}
|
@media (prefers-color-scheme:dark){#brand{background:linear-gradient(180deg,#16191f,#0e1116);border:1px solid #2b313a;color:#fff}}
|
||||||
.badge{border:1px solid #e5e7eb;background:#fff;border-radius:.5rem;padding:.125rem .375rem;font-size:10px}
|
#brand:disabled{opacity:.95}
|
||||||
kbd{border:1px solid #e5e7eb;border-bottom-width:2px;border-radius:.375rem;background:#fff;padding:.05rem .3rem;font-size:10px}
|
.hero{display:grid;place-items:center;text-align:center;margin:16px 0 6px}
|
||||||
a.anchor{color:#111827;text-decoration:none;border-bottom:1px dashed #d1d5db}
|
.hero .stamp{display:inline-grid;place-items:center;gap:8px;color:inherit}
|
||||||
|
.hero .stamp .ring{opacity:.72}
|
||||||
|
.hero h1{font-weight:800;font-size:20px;margin:6px 0 10px;letter-spacing:.2px}
|
||||||
|
.hero p{margin:0 auto;max-width:720px;opacity:.85}
|
||||||
|
.badges{display:flex;gap:8px;flex-wrap:wrap;justify-content:center;margin:12px 0 18px}
|
||||||
|
.badges .b{display:inline-flex;align-items:center;gap:6px;border:1px solid #e4e7eb;border-radius:999px;padding:4px 10px;background:linear-gradient(180deg,#fff,#fafafa)}
|
||||||
|
@media (prefers-color-scheme:dark){.badges .b{border-color:#2b313a;background:linear-gradient(180deg,#141821,#0c0f14)}}
|
||||||
|
hr.soft{border:0;height:1px;background:linear-gradient(90deg,transparent,#d6dbe2,transparent);margin:22px 0}
|
||||||
|
@media (prefers-color-scheme:dark){hr.soft{background:linear-gradient(90deg,transparent,#2b313a,transparent)}}
|
||||||
|
blockquote{border-left:3px solid #c7d1e6;padding:.2em .9em;margin:.6em 0;background:#f8fbff}
|
||||||
|
@media (prefers-color-scheme:dark){blockquote{border-color:#354157;background:#0c121b}}
|
||||||
|
.note{font-size:11.5px;opacity:.8}
|
||||||
|
.center{text-align:center}
|
||||||
|
kbd{border:1px solid #ccd1d7;border-bottom-color:#b6bcc3;padding:1px 4px;border-radius:4px;background:#fff;box-shadow:inset 0 -1px 0 #b6bcc3}
|
||||||
|
@media (prefers-color-scheme:dark){kbd{border-color:#333940;border-bottom-color:#242a31;background:#0c0f14;box-shadow:inset 0 -1px 0 #242a31}}
|
||||||
|
pre code.hljs{display:block;padding:12px;border-radius:10px}
|
||||||
|
.foot{opacity:.7}
|
||||||
|
small{opacity:.84}
|
||||||
|
svg{max-width:100%}
|
||||||
|
a{color:inherit}
|
||||||
</style>
|
</style>
|
||||||
<script>
|
|
||||||
tailwind.config={theme:{extend:{fontFamily:{sans:['Inter','ui-sans-serif','system-ui'],mono:['Fira Code','ui-monospace']}}}}
|
|
||||||
</script>
|
|
||||||
</head>
|
</head>
|
||||||
<body class="min-h-dvh bg-white text-gray-900 selection:bg-black/10 text-xs">
|
<body>
|
||||||
<header class="sticky top-0 z-20 bg-white/80 backdrop-blur border-b border-gray-200">
|
<header><button id=brand disabled aria-disabled=true title="You can’t click this">Hi</button></header>
|
||||||
<div class="mx-auto max-w-3xl px-3 py-2 grid grid-cols-3 items-center">
|
|
||||||
<nav class="flex gap-2 items-center">
|
<main class="markdown-body" id=app></main>
|
||||||
<a href="#overview" class="badge">Overview</a>
|
|
||||||
<a href="#syntax" class="badge">Syntax</a>
|
<!-- Content (Markdown). Use ~~~ fences to avoid backticks in this file -->
|
||||||
<a href="#blocks" class="badge">Blocks</a>
|
<script id=md type=text/markdown>
|
||||||
</nav>
|
<div class="hero">
|
||||||
<div class="flex items-center justify-center">
|
<div class="stamp">
|
||||||
<button aria-label="Hi" disabled class="pointer-events-none select-none h-8 px-4 rounded-full bg-gray-200 text-gray-900 font-semibold">Hi</button>
|
<svg class="ring" viewBox="0 0 200 200" width="120" height="120" role="img" aria-label="Symbol ring">
|
||||||
</div>
|
<defs><path id="circ" d="M100 100 m -64,0 a 64,64 0 1,1 128,0 a 64,64 0 1,1 -128,0"/></defs>
|
||||||
<div class="flex justify-end items-center gap-1">
|
<text font-size="11.6" fill="currentColor">
|
||||||
<a class="badge hidden sm:inline" href="https://github.com/hi-language" target="_blank" rel="noreferrer">GitHub</a>
|
<textPath href="#circ" startOffset="0%">
|
||||||
<button id="copyAll" class="badge" title="Copy all examples">Copy all</button>
|
: = # ? * [ ] { } ( ) → ƒ · ¬ ∧ ∨ × ⊕ : = # ? * [ ] { } ( ) →
|
||||||
</div>
|
</textPath>
|
||||||
|
</text>
|
||||||
|
<circle cx="100" cy="100" r="3" fill="currentColor"/>
|
||||||
|
</svg>
|
||||||
|
<div><small>symbol-first • ai-friendly • code-golfable</small></div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</div>
|
||||||
|
|
||||||
<main class="mx-auto max-w-3xl px-3">
|
# The “Hi” programming language <i data-lucide="sparkles" style="width:16px;height:16px;vertical-align:-2px;"></i>
|
||||||
<section class="hero-grad rounded-2xl border border-gray-200 mt-4 p-4 sm:p-6">
|
|
||||||
<div class="flex items-center gap-2 text-[11px] text-gray-600 mb-2">
|
|
||||||
<span class="badge">Symbolic</span>
|
|
||||||
<span class="badge">JS-inspired</span>
|
|
||||||
<span class="badge">AI-first</span>
|
|
||||||
<span class="badge">Code-golf friendly</span>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center gap-3">
|
|
||||||
<div class="h-12 w-12 rounded-xl bg-gradient-to-br from-black to-gray-600 text-white grid place-items-center font-extrabold">Hi</div>
|
|
||||||
<div>
|
|
||||||
<h1 class="text-base sm:text-lg font-extrabold leading-tight">Hi — a tiny, symbolic, AI-first programming language</h1>
|
|
||||||
<p class="text-[11px] sm:text-xs text-gray-600">Keep the core mostly symbols so everyone can read/write it. Let humans and AIs meet at the shortest path.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-4 grid sm:grid-cols-[1fr,220px] gap-4">
|
Hi is a tiny, JS‑inspired language that prefers symbols over keywords. Fewer words → fewer walls between people. And with an AI‑first mindset, we bias toward patterns that are easy to write, read, compress, and transform. The result feels like a playful toolbox that also respects production constraints.
|
||||||
<article id="mdOut" class="markdown-body"></article>
|
|
||||||
<aside class="rounded-xl border border-gray-200 bg-white/70 p-3">
|
|
||||||
<div class="text-[11px] text-gray-500 mb-2">Shape of a program</div>
|
|
||||||
<svg viewBox="0 0 220 180" width="100%" height="180" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<linearGradient id="g1" x1="0" x2="1">
|
|
||||||
<stop offset="0%" stop-color="#111827"/>
|
|
||||||
<stop offset="100%" stop-color="#4b5563"/>
|
|
||||||
</linearGradient>
|
|
||||||
</defs>
|
|
||||||
<rect x="1" y="1" width="218" height="178" rx="12" fill="#fff" stroke="#e5e7eb"/>
|
|
||||||
<g font-family="Inter" font-size="10" fill="#111827">
|
|
||||||
<rect x="18" y="18" width="70" height="32" rx="7" fill="#f3f4f6" stroke="#e5e7eb"/>
|
|
||||||
<text x="53" y="38" text-anchor="middle">Source.hi</text>
|
|
||||||
<rect x="132" y="18" width="70" height="32" rx="7" fill="#f3f4f6" stroke="#e5e7eb"/>
|
|
||||||
<text x="167" y="38" text-anchor="middle">Blocks</text>
|
|
||||||
|
|
||||||
<path d="M88 34h36" stroke="url(#g1)" stroke-width="1.2"/>
|
<div class="badges">
|
||||||
<polygon points="125,34 119,31 119,37" fill="#4b5563"/>
|
<span class="b"><i data-lucide="code-2"></i> JS‑fluent</span>
|
||||||
|
<span class="b"><i data-lucide="zap"></i> Symbol‑core</span>
|
||||||
|
<span class="b"><i data-lucide="scissors"></i> Code‑golf aware</span>
|
||||||
|
<span class="b"><i data-lucide="bot"></i> AI‑read/write</span>
|
||||||
|
<span class="b"><i data-lucide="package"></i> 1 Block to rule them all</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<rect x="18" y="74" width="184" height="36" rx="7" fill="#f9fafb" stroke="#e5e7eb"/>
|
> Feeling note: I love how symbols level the playing field. Fewer English words = less bias. It makes me think of music notation — dense, expressive, and multilingual.
|
||||||
<text x="110" y="96" text-anchor="middle">Symbols: <tspan fill="#374151">: = { } ( ) [ ] # ? *</tspan></text>
|
|
||||||
|
|
||||||
<rect x="18" y="128" width="184" height="32" rx="7" fill="#eef2ff" stroke="#e5e7eb"/>
|
<hr class="soft">
|
||||||
<text x="110" y="147" text-anchor="middle">Object ∧ Function = Block</text>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
<div class="mt-2 text-[11px] text-gray-600">
|
|
||||||
In Hi, a Block is both an object and a function. The last expression returns. Private fields start with <code>#</code>.
|
|
||||||
</div>
|
|
||||||
</aside>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<footer class="py-8 text-center text-[11px] text-gray-500">
|
## Hello, world
|
||||||
<div class="mb-2">Made with markdown-it, highlight.js (JS mode), and lucide icons.</div>
|
~~~js
|
||||||
<div>Hi is early and evolving. Syntax and semantics may change.</div>
|
// Hello World in Hi
|
||||||
</footer>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<script id="md" type="text/markdown">
|
|
||||||
<a id="overview"></a>
|
|
||||||
|
|
||||||
### Why Hi?
|
|
||||||
- Corely symbolic: fewer keywords, more universal glyphs. Symbols travel better across languages and scripts.
|
|
||||||
- JS-inspired pragmatism, but not JS. If you know JS, you’ll grok Hi fast.
|
|
||||||
- AI-first: short, rigid tokens make parsing/generation simpler for LLMs. Great for code-golf, great for machines.
|
|
||||||
|
|
||||||
> Printing uses `_()` — think “say”. Comments are `//`.
|
|
||||||
|
|
||||||
```js
|
|
||||||
// Hello, world
|
|
||||||
_("Hi world")
|
_("Hi world")
|
||||||
|
~~~
|
||||||
|
|
||||||
|
- `_` is the standard print/write function.
|
||||||
|
- Code fences use JS highlighting for now.
|
||||||
|
|
||||||
|
## Declarations and assignments
|
||||||
|
~~~js
|
||||||
|
// Symbols over keywords:
|
||||||
|
name: "Orion" // Declaration
|
||||||
|
times = 3 // Assignment
|
||||||
|
~~~
|
||||||
|
- `:` declares a name.
|
||||||
|
- `=` assigns to an existing name.
|
||||||
|
|
||||||
|
## Blocks unify data and behavior
|
||||||
|
In Hi, `{}` makes a Block. It’s always both an object and a function. That means you can store properties and also call it.
|
||||||
|
|
||||||
|
~~~js
|
||||||
|
// Function Block
|
||||||
|
sayHi: {
|
||||||
|
_("Hi")
|
||||||
|
}
|
||||||
|
sayHi() // call like a function
|
||||||
|
~~~
|
||||||
|
|
||||||
|
~~~js
|
||||||
|
// Object Block
|
||||||
|
player: {
|
||||||
|
name: "Orion" // public
|
||||||
|
#hp: 100 // private
|
||||||
|
}
|
||||||
|
_(player.name) // "Orion"
|
||||||
|
~~~
|
||||||
|
|
||||||
|
~~~js
|
||||||
|
// Hybrid Block (object + private state + behavior)
|
||||||
|
counter: {
|
||||||
|
#value: 0
|
||||||
|
inc: {
|
||||||
|
value = value + 1
|
||||||
|
_("The count is now: " + value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
counter.inc() // "The count is now: 1"
|
||||||
|
counter.inc() // "The count is now: 2"
|
||||||
|
~~~
|
||||||
|
|
||||||
|
- In JS you can’t have a bare object that is callable and also carries private state without factories/closures. Here it’s natural.
|
||||||
|
- My feeling: this is surprisingly calming. The “thingness” and the “action” live together, so I don’t have to keep mental tabs on where state hides. It reminds me of little self‑contained organisms.
|
||||||
|
|
||||||
|
### A quick philosophy riff
|
||||||
|
Blocks make programs read like small poems: name a thing with `:`, give it a heart with `#private` state, give it hands as callable parts, and let it speak with `_`.
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
~~~js
|
||||||
|
withParams: (str) {
|
||||||
|
_(str)
|
||||||
|
}
|
||||||
|
|
||||||
|
withParams("Hey!") // "Hey!"
|
||||||
|
~~~
|
||||||
|
|
||||||
|
## Truthiness (designed for clarity and golfing)
|
||||||
|
~~~js
|
||||||
|
0 // falsy (the official false)
|
||||||
|
!0 // truthy (the official true)
|
||||||
|
4 // truthy
|
||||||
|
"" // falsy (truthy if non-empty)
|
||||||
|
{} // falsy (truthy if non-empty)
|
||||||
|
[] // falsy (truthy if non-empty)
|
||||||
|
-0 // falsy / null / undefined (collapses empties)
|
||||||
|
== // equivalent to JS ===
|
||||||
|
~~~
|
||||||
|
- Short to type, easy for AI to normalize, and compact for code golfing.
|
||||||
|
|
||||||
|
## Conditionals as expressions with Blocks
|
||||||
|
~~~js
|
||||||
|
// if
|
||||||
|
(cond) ? { /* then */ }
|
||||||
|
|
||||||
|
// if / else
|
||||||
|
(cond) ? { /* then */ } : { /* else */ }
|
||||||
|
~~~
|
||||||
|
|
||||||
|
Like Rust, the last expression in a Block is returned.
|
||||||
|
|
||||||
|
~~~js
|
||||||
|
tern: (cond) ? {"A"} : {"B"}
|
||||||
|
|
||||||
|
// A lovely multi-branch:
|
||||||
|
score: 85
|
||||||
|
grade: (score > 90) ? {"A"}
|
||||||
|
: (score > 80) ? {"B"}
|
||||||
|
: {"C"}
|
||||||
|
|
||||||
|
_(grade) // "B"
|
||||||
|
~~~
|
||||||
|
|
||||||
|
> Unification vibe: conditions choose Blocks, not statements. Data and behavior stay composable. This makes composition and refactoring feel like sliding tiles instead of rewriting grammar.
|
||||||
|
|
||||||
|
## Arrays
|
||||||
|
~~~js
|
||||||
|
primes: [2, 3, 5, 7]
|
||||||
|
|
||||||
|
// Access
|
||||||
|
firstPrime: primes[0]
|
||||||
|
|
||||||
|
// Mutation
|
||||||
|
primes[0] = 1
|
||||||
|
_(primes) // [1, 3, 5, 7]
|
||||||
|
~~~
|
||||||
|
|
||||||
|
## Loops
|
||||||
|
~~~js
|
||||||
|
// for
|
||||||
|
(i: 0; i < 5; i = i + 1) * {
|
||||||
|
_(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
// while
|
||||||
|
(!0) * {
|
||||||
|
// ...do stuff forever (truthy)...
|
||||||
|
^ // break
|
||||||
|
}
|
||||||
|
|
||||||
|
// flow control
|
||||||
|
>> // continue
|
||||||
|
^ // break
|
||||||
|
~~~
|
||||||
|
|
||||||
|
### Bridging examples
|
||||||
|
Sometimes the smallest examples teach the most.
|
||||||
|
|
||||||
|
~~~js
|
||||||
|
// 1) Tiny math util
|
||||||
|
add: (a, b) { a + b }
|
||||||
|
_(add(2, 5)) // 7
|
||||||
|
|
||||||
|
// 2) A Block that is both config and runnable
|
||||||
|
job: {
|
||||||
|
name: "daily-report"
|
||||||
|
#runs: 0
|
||||||
|
run: {
|
||||||
|
runs = runs + 1
|
||||||
|
_("running " + name + " #" + runs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
job.run() // "running daily-report #1"
|
||||||
|
|
||||||
|
// 3) Method-style call reads well
|
||||||
|
user: {
|
||||||
|
name: "Kai"
|
||||||
|
hello: { _("Hi " + name) }
|
||||||
|
}
|
||||||
|
user.hello() // "Hi Kai"
|
||||||
|
|
||||||
|
// 4) Short-circuit with truthy/falsy style
|
||||||
|
safeName: user.name ? { user.name } : { "Anonymous" }
|
||||||
|
~~~
|
||||||
|
|
||||||
|
> Feeling note: the private `#` makes me smile. Privacy as a first thought, not an afterthought, nudges me to design better modules.
|
||||||
|
|
||||||
|
<hr class="soft">
|
||||||
|
|
||||||
|
## Why symbols? Why now?
|
||||||
|
- World‑friendly: Symbols sidestep English heavy keywords.
|
||||||
|
- AI‑friendly: Tokens are short, consistent, easy to learn and predict. Models thrive on regular patterns.
|
||||||
|
- Golf‑friendly: Less keystrokes, fewer ceremony characters, more signal.
|
||||||
|
|
||||||
|
I feel a little thrill when a language removes accidental complexity. The code shrinks and my intent gets louder.
|
||||||
|
|
||||||
|
## Design snapshot
|
||||||
|
- `:` declare • `=` assign
|
||||||
|
- `{}` Block = object ∧ function
|
||||||
|
- `#name` private field in its Block
|
||||||
|
- `()` call or params
|
||||||
|
- `? :` expressions that yield values (Blocks)
|
||||||
|
- `*` loop operator
|
||||||
|
- `>>` continue • `^` break
|
||||||
|
- `0` false • `!0` true • `-0` empty/nullish collapse
|
||||||
|
- `==` is JS `===`
|
||||||
|
|
||||||
|
## A tiny mental model
|
||||||
|
~~~js
|
||||||
|
// A program is a map of names → Blocks.
|
||||||
|
// A Block is:
|
||||||
|
// - a bag of properties (public + #private)
|
||||||
|
// - a callable body (optional)
|
||||||
|
// - a scope for its internals
|
||||||
|
// - an expression that returns its last value
|
||||||
|
~~~
|
||||||
|
|
||||||
|
### A miniature sketch that ties it all
|
||||||
|
~~~js
|
||||||
|
main: {
|
||||||
|
title: "Hi"
|
||||||
|
#visits: 0
|
||||||
|
|
||||||
|
greet: (who) { _("Hi, " + who) }
|
||||||
|
|
||||||
|
tick: {
|
||||||
|
visits = visits + 1
|
||||||
|
_("visits=" + visits)
|
||||||
|
}
|
||||||
|
|
||||||
|
run: {
|
||||||
|
greet("world")
|
||||||
|
tick()
|
||||||
|
(visits > 1) ? {"returning"} : {"first-time"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_(main.run()) // "returning" after second call
|
||||||
|
~~~
|
||||||
|
|
||||||
|
> Personal aside: the above reads like a little organism with memory and reflexes. I can almost feel the shape of the program in my hands.
|
||||||
|
|
||||||
|
<hr class="soft">
|
||||||
|
<div class="center">
|
||||||
|
<i data-lucide="beaker" style="width:16px;height:16px;vertical-align:-3px;"></i>
|
||||||
|
<strong>Status:</strong> Hi is in active development. Syntax and semantics may evolve.
|
||||||
|
<div class="note">We currently use JS highlighting in code fences until a dedicated Hi lexer lands.</div>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- libs -->
|
||||||
|
<script src=https://cdn.jsdelivr.net/npm/markdown-it@13.0.1/dist/markdown-it.min.js integrity=sha256-9XJMEdXL4iQOA06pW2FQk1rXyiZg8Wmrl9M4m1pG56o= crossorigin=anonymous></script>
|
||||||
|
<script src=https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js integrity=sha512-B9LYv1kbEKj4QywiJH7+UO7J9aD50S88H8+C4qQJY4kW3fH8c1G0k7L3CybA4g2w+O1QfM+2b0gM7bZ2BfY7xA== crossorigin=anonymous referrerpolicy=no-referrer></script>
|
||||||
|
<script src=https://unpkg.com/lucide@latest/dist/umd/lucide.min.js></script>
|
||||||
|
|
||||||
|
<!-- render -->
|
||||||
|
<script>
|
||||||
|
(()=>{const $=e=>document.querySelector(e),md=window.markdownit({html:!0,linkify:!0,typographer:!0,highlight:(s,l)=>{try{return hljs.highlight(s,{language:'javascript'}).value}catch{return hljs.highlightAuto(s).value}}});$("#app").innerHTML=md.render($("#md").textContent.trim());lucide&&lucide.createIcons({attrs:{'stroke-width':1.75}})})();
|
||||||
|
</script>
|
||||||
|
<footer class="markdown-body foot center"><small>© <span id=y></span> Hi language team • Built with markdown-it, GitHub Markdown CSS, Lucide, and highlight.js.</small></footer>
|
||||||
|
<script>y.textContent=(new Date).getFullYear()</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user