mirror of
https://github.com/hi-language/hi-language.github.io.git
synced 2026-01-14 08:38:36 +00:00
328 lines
12 KiB
HTML
328 lines
12 KiB
HTML
<!doctype html><html lang=en>
|
||
<head>
|
||
<meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1">
|
||
<title>Hi — a tiny, symbolic, AI‑first language</title>
|
||
<link rel=preconnect href=https://fonts.googleapis.com>
|
||
<link rel=preconnect href=https://fonts.gstatic.com crossorigin>
|
||
<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>
|
||
<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://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github.min.css integrity=sha512-3mb8zCey3p+3w0lI04lH8mKeb4d0x1c6PXo2g0Q9yQkQhy/c6v2dGEZ7V6o0H6YugyS0r5uEIAJ0u8oHNoq6tA== crossorigin=anonymous referrerpolicy=no-referrer>
|
||
<style>
|
||
: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}
|
||
html,body{height:100%}
|
||
html{color-scheme:light dark}
|
||
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)}
|
||
@media (prefers-color-scheme:dark){body{background:var(--bgD)}}
|
||
.markdown-body{font-size:12.6px;max-width:920px;padding:64px 18px 80px;margin:0 auto;color:inherit}
|
||
code,kbd,pre,samp{font-family:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:12px}
|
||
header{position:sticky;top:8px;z-index:9;display:grid;place-items:center;height:0}
|
||
#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}
|
||
@media (prefers-color-scheme:dark){#brand{background:linear-gradient(180deg,#16191f,#0e1116);border:1px solid #2b313a;color:#fff}}
|
||
#brand:disabled{opacity:.95}
|
||
.hero{display:grid;place-items:center;text-align:center;margin:16px 0 6px}
|
||
.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>
|
||
</head>
|
||
<body>
|
||
<header><button id=brand disabled aria-disabled=true title="You can’t click this">Hi</button></header>
|
||
|
||
<main class="markdown-body" id=app></main>
|
||
|
||
<!-- Content (Markdown). Use ~~~ fences to avoid backticks in this file -->
|
||
<script id=md type=text/markdown>
|
||
<div class="hero">
|
||
<div class="stamp">
|
||
<svg class="ring" viewBox="0 0 200 200" width="120" height="120" role="img" aria-label="Symbol ring">
|
||
<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>
|
||
<text font-size="11.6" fill="currentColor">
|
||
<textPath href="#circ" startOffset="0%">
|
||
: = # ? * [ ] { } ( ) → ƒ · ¬ ∧ ∨ × ⊕ : = # ? * [ ] { } ( ) →
|
||
</textPath>
|
||
</text>
|
||
<circle cx="100" cy="100" r="3" fill="currentColor"/>
|
||
</svg>
|
||
<div><small>symbol-first • ai-friendly • code-golfable</small></div>
|
||
</div>
|
||
</div>
|
||
|
||
# The “Hi” programming language <i data-lucide="sparkles" style="width:16px;height:16px;vertical-align:-2px;"></i>
|
||
|
||
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.
|
||
|
||
<div class="badges">
|
||
<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>
|
||
|
||
> 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.
|
||
|
||
<hr class="soft">
|
||
|
||
## Hello, world
|
||
~~~js
|
||
// Hello World in Hi
|
||
_("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>
|