neuron-explorer
Qwen3.5‑4B 전용 조향형 뉴런 탐색기, 모든 MLP 뉴런을 밀어 결과를 보관·탐색
An actor-based systems language that compiles to readable C. Native, no VM, no garbage collector.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
A compiled actor language whose permissions are part of the source, enforced from compile time down to libc (the libc layer on Linux/FreeBSD; Windows gets the compile-time and scope layers). No VM and no garbage collector: the compiler emits readable C.README 전문 보기 ↗A compiled actor language whose permissions are part of the source, enforced from compile time down to libc (the libc layer on Linux/FreeBSD; Windows gets the compile-time and scope layers). No VM and no garbage collector: the compiler emits readable C.
Website: aether-lang.dev
Most languages treat "what may this program touch?" as a deployment problem. Aether makes it a language problem: code runs against an explicit grant list, enforced three times over. At compile time, --emit=lib starts capability-empty and the host opts modules in with --with=fs,net,os. At scope level, hide and seal except stop ambient names from leaking into any lexical block, a closure, a trailing-block DSL, an actor handler. At runtime, an LD_PRELOAD shim checks libc itself (open*, connect/bind, execve, mmap, dlopen, getenv) against the same grants, inherited across execve. This third layer is Linux/FreeBSD only (there is no LD_PRELOAD on Windows). See Containment Sandbox for the threat model, the prior art it draws on, and the known bypass surface.
Concurrency is actor-shaped: actor, receive and !, with automatic multi-core scheduling, lock-free mailboxes, and migration that converges chatty actors onto one core. The compiler emits readable C, not bytecode and not a VM, which is an implementation choice rather than the pitch: it buys native speed, direct linking against existing C libraries, and a runtime that ports anywhere a C toolchain reaches.
Where it sits on the OO / FP spectrum: structs are plain data, behaviour lives in free functions, and closures and trailing blocks are first-class, so the language leans closer to functional than object-oriented. There are no classes, no inheritance and no method dispatch; the one piece of OO machinery present is the actor, which is stateful and encapsulated behind a message boundary but has no polymorphism. See Language Reference § Paradigm placement.
The load-bearing features:
--emit=lib typed SDKs with per-guest memory and deadline caps. See Embedding & emit=lib.sendfile(2), plus a reverse proxy with load balancing, health checks, caching and a circuit breaker. See HTTP Server and Reverse Proxy.defer. Each meaningful combination of value kind, place and transfer is a cell of the ownership grid, which CI runs on every pull request to catch leaks, double frees and use after free. See Memory Management.(value, err) multi-value returns, optionals and sum types checked at compile time, named and default arguments, requires/ensures contracts, @derive(eq) and @derive(schema), and a single ae command for build, run, test, fmt and packages. See Language Reference.Cross-language benchmark suite based on the Savina Actor Benchmark Suite, 11 languages × 5 patterns (ping-pong, counting, thread ring, fork-join, skynet). Both the benchmark runner and the visualization server are written in Aether, dogfooding the stdlib.
make benchmark # Builds runner, runs all 55 benchmarks, opens UI at http://localhost:8080
See Performance Benchmarks for methodology and benchmarks/cross-language/ for source.
Linux / macOS / FreeBSD, prebuilt binary (no toolchain, no build):
Every release ships a ready-to-run tarball (ae + aetherc + stdlib) named aether-<version>-<platform>.tar.gz, where <platform> is one of linux-x86_64, macos-arm64, macos-x86_64, freebsd-x86_64, android-aarch64. Take the version and your platform from the latest release, then extract and add its bin/ to your PATH:
# Substitute the latest version and your platform:
VER=0.830.0; PLATFORM=linux-x86_64
curl -fsSL "https://github.com/aether-lang-dev/aether/releases/download/v${VER}/aether-${VER}-${PLATFORM}.tar.gz" | tar xz -C ~/.local
export PATH="$HOME/.local/bin:$PATH" # add to ~/.bashrc / ~/.zshrc to persist
ae version
Linux / macOS, build from source (remote one-liner, no clone):
curl -sSL https://raw.githubusercontent.com/aether-lang-dev/aether/main/get.sh | sh
Fetches a pinned source tarball, builds the toolchain (Aether compiles to C, so the only prerequisites are a C compiler + GNU make, no tests run), and installs to ~/.local (sudo-free). Pin a version with AETHER_REF=<tag> (see the releases page for tags), or change the prefix with PREFIX=/usr/local (system-wide; needs sudo). Add ~/.local/bin to your PATH if it isn't already.
Linux / macOS, full clone install (editor extension, ae version management, shell-PATH setup, ~/.aether layout):
git clone https://github.com/aether-lang-dev/aether.git
cd aether
./install.sh
Installs to ~/.aether and adds ae to your PATH. Restart your terminal or run source ~/.bashrc, ~/.zshrc, or ~/.bash_profile. Add --contrib-too (./install.sh --contrib-too) to also build and install the native contrib modules (sqlite, embedded Python/Lua/…) whose dev libraries your machine has.
Windows, download and run:
aether-*-windows-x86_64.zip from ReleasesC:\aether)C:\aether\bin to your PATHae init hello && cd hello && ae runGCC is downloaded automatically the first time you run a program (~80 MB, one-time), no MSYS2 or manual toolchain setup required.
All platforms, install, upgrade, and switch versions:
ae version list # see all available releases (newest first)
ae upgrade # install the latest release and switch to it
ae install # install the latest release (or `ae install <tag>` for a specific one)
ae use <tag> # switch to an already-installed version
Run ae version list (or check the latest release) to find the current tag; there's no need to hard-code one.
(The longer ae version install <v> / ae version use <v> forms still
work and are equivalent to ae install / ae use.)
# Create a new project
ae init hello
cd hello
ae run
Or run a single file directly:
ae run examples/01-language/01-hello.ae
Install syntax highlighting for a better coding experience:
VS Code / Cursor:
cd editor/vscode
./install.sh
This provides:
.ae file iconsIf you prefer to build without installing:
make ae
./build/ae version
./build/ae run examples/01-language/01-hello.ae
ae Commandae is the single entry point for everything, like go or cargo:
ae init <name> # Create a new project
ae run [file.ae] # Compile and run (file or project)
ae build [file.ae] # Compile to executable
ae build --trace f.ae # ...with message tracing compiled in (docs/message-tracing.md)
ae check [file.ae] # Type-check without compiling (skips codegen + link)
ae fmt [--check] [path] # Format source (stdin, or .ae files/dirs in place)
ae fmt --short-names src # Rewrite json.json_free(v) as json.free(v) where both are one function
ae test [file|dir]... # Discover and run tests (every file and directory named)
ae examples [dir] # Build the example programs (examples/README.md)
ae add <host/user/repo> # Add a dependency (any forge; no git, hash-pinned)
ae repl # Start interactive REPL
ae cache # Show build cache info
ae cache gc # Trim the cache to its limit (AETHER_CACHE_MAX_MB, default 5120)
ae cache clear # Clear the build cache
ae inspect [file.ae] # Show what a script declares (imports, capabilities, exports)
ae bindgen consts <h> # Import C macro constants from a header as Aether consts
ae cflags # Print -I/-L/-laether for embedding in external builds
ae checksec <binary> # Report the hardening a built artifact carries
ae lib-path # Print the resolved module-search chain
ae lib-info <library> # Print the symbol catalog of an --emit=lib library
ae version # Show current version
ae upgrade # Install the latest release and switch to it
ae install <v> # Install a specific release (latest if omitted)
ae use <v> # Switch to an installed version
ae version list # List all available releases
ae version installed # List only the releases installed locally
ae version gc --keep 3 # Prune the store to the newest 3
ae version dedupe # Share identical files across versions
ae help # Show all commands
ae <command> --help # A command's own options (or -h); runs nothing
In a project directory (with aether.toml), ae run and ae build compile src/main.ae as the program entry point. You can also pass . as the directory: ae run . or ae build ..
Using Make (alternative):
make compiler # Build compiler only
make ae # Build ae CLI tool
make test # Run runtime C test suite
make test-ae # Run .ae source tests
make test-all # Run all tests
make examples # Build and run every example, checking its output
make -j8 # Parallel build
make help # Show all targets
The Aether build is GNU-make based. Use one of the two paths below, nmake from a Visual Studio Developer Prompt will not work (the Makefile uses GNU-only syntax that NMAKE can't parse).
Just running Aether? Skip this section and use the release binary, no MSYS2 setup required.
Building from source, recommended (MSYS2 / MinGW-w64):
pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-make \
mingw-w64-x86_64-openssl mingw-w64-x86_64-zlib \
mingw-w64-x86_64-ca-certificates pkg-config make bc
git clone https://github.com/aether-lang-dev/aether.git
cd aether
make ci # full suite: compiler, ae, stdlib, REPL, C tests, .ae tests, examples
For HTTPS to verify certificates on Windows, both TLS stacks (OpenSSL and the pure-Aether client) trust every certificate in the system ROOT store, the one Windows itself uses, together with the first of these bundle files that exists:
| Where | Bundle |
|---|---|
| The release archive, beside the program | <root>\share\ssl\ca-bundle.crt for <root>\bin\prog.exe (share\ssl\ in the program's own directory when it is not in a bin\) |
MSYS2 + mingw-w64-x86_64-ca-certificates | C:\msys64\mingw64\etc\ssl\certs\ca-bundle.crt, the UCRT64 one, then etc\ssl\cert.pem in each |
| Git for Windows | C:\Program Files\Git\mingw64\etc\ssl\certs\ca-bundle.crt |
So a program copied to a machine with neither MSYS2 nor Git for Windows still makes HTTPS requests. The bundle joins the store rather than replacing it because Windows adds a root certificate to its store only the first time it needs one, so the store of a machine that has never met a server can lack the root that server chains to.
SSL_CERT_FILE (a PEM bundle) or SSL_CERT_DIR (a directory of PEM files, ;-separated) replaces all of that when set, for a corporate CA, a custom bundle or a test CA. It takes the bundle's native Windows path:
export SSL_CERT_FILE="C:/Program Files/Git/mingw64/etc/ssl/certs/ca-bundle.crt"
An MSYS-style path (/mingw64/...) will not work: a compiled Aether program is a plain Win32 binary and does not inherit MSYS2's virtual mounts. An SSL_CERT_FILE that cannot be read fails every HTTPS request at the handshake, on both stacks, rather than falling back to the store.
Note also that a source build without OpenSSL has no TLS backend linked at all; such a program must import std.cryptography.tls13_client to get HTTPS. The error message says so if you forget.
Native MSVC (cl.exe / nmake): not a supported build path. The MSVC job in CI checks that the public headers parse under cl.exe, and that the C the compiler writes for a set of programs compiles under it (make test-msvc-compat runs the same check locally; that C has no GNU statement expressions, #2765), but the build itself requires GNU make. The MSYS2 MinGW build above is the supported source build on Windows.
aether/
├── compiler/ # Aether compiler (lexer, parser, codegen)
│ ├── parser/ # Lexer, parser, tokens
│ ├── analysis/ # Type checker, type inference
│ ├── codegen/ # C code generation, optimizer
│ └── aetherc.c # Compiler entry point
├── runtime/ # Runtime system
│ ├── actors/ # Actor implementation and lock-free mailboxes
│ ├── config/ # Platform detection, optimization tiers, runtime config
│ ├── memory/ # Arena allocators, memory pools, batch allocation
│ ├── scheduler/ # Multi-core scheduler + cooperative single-threaded backend
│ └── utils/ # CPU detection, SIMD, thread portability
├── std/ # Standard library
│ ├── string/ # String operations
│ ├── file/ # File operations (open, read, write, delete)
│ ├── dir/ # Directory operations (create, delete, list)
│ ├── path/ # Path utilities (join, basename, dirname)
│ ├── fs/ # Combined file/dir/path module
│ ├── collections/ # List, HashMap, Vector, Set, PQueue
│ ├── list/ # Dynamic array (ArrayList)
│ ├── map/ # Hash map
│ ├── intarr/ # Fixed-size packed int buffer
│ ├── json/ # JSON parser and builder
│ ├── http/ # HTTP client + server (TLS, keep-alive, h2, WS, SSE, metrics)
│ │ ├── client/ # Builder client (request builder, full response, JSON sugar)
│ │ ├── middleware/ # CORS, basic/bearer/session auth, rate-limit, real-IP, vhost, gzip, static, rewrite, error pages
│ │ ├── proxy/ # Reverse proxy: upstream pool, LB (RR/LC/iphash/WRR), health, cache, circuit breaker
│ │ └── server/h2/ # HTTP/2 framing via libnghttp2 (h2 + h2c + ALPN + GOAWAY + concurrent dispatch)
│ ├── tcp/ # TCP client and server
│ ├── net/ # Combined TCP/HTTP networking module
│ ├── cryptography/ # Hash family (SHA-2/3, BLAKE2, RIPEMD, Whirlpool, Tiger, Skein, SM3), HMAC, HKDF/PBKDF2/scrypt/Argon2, DRBG
│ ├── zlib/ # One-shot deflate/inflate
│ ├── math/ # Math functions and random numbers
│ ├── io/ # Console I/O, environment variables
│ ├── os/ # Shell execution, command capture, env vars, ISO-8601 time
│ └── log/ # Structured logging
├── contrib/ # Optional / opinionated modules outside std/
│ ├── vulkan/ # GPU tier: Vulkan, with d3d12/ and metal/ of the same shape
│ ├── sqlite/ # SQLite bindings (open, prepare, bind, step, column, ...)
│ ├── quickjs/ # Embedded QuickJS (quickjs-ng)
│ ├── jq/ # The jq language over std.json values
│ ├── parsers/ # xml_expat (SAX XML via libexpat)
│ ├── templating/ # liquid (Shopify-Liquid port) + native emitter DSL
│ ├── tinyweb/ # Server-side request/response DSL
│ └── host/<lang>/ # Embed js, lua, perl, python, ruby, tcl, duktape,
│ # tinygo, go, java, factor, racket, rhombus in-process
├── tools/ # Developer tools
│ ├── ae.c # Unified CLI tool (ae command)
│ └── apkg/ # Project tooling, TOML parser
├── tests/ # Test suite (runtime, syntax, integration, regression)
├── examples/ # Example programs (.ae files)
│ ├── basics/ # Hello world, variables, arrays, etc.
│ ├── actors/ # Actor patterns (ping-pong, pipeline, etc.)
│ └── applications/ # Complete applications
├── docs/ # Documentation
└── docker/ # Docker (CI, dev, WASM, embedded)
// Counter actor with message handling
message Increment {}
message Decrement {}
message Reset {}
actor Counter {
state count = 0
receive {
Increment() -> {
count = count + 1
}
Decrement() -> {
count = count - 1
}
Reset() -> {
count = 0
}
}
}
main() {
// Spawn counter actor
counter = spawn(Counter())
// Send messages
counter ! Increment {}
counter ! Increment {}
counter ! Decrement {}
counter ! Reset {}
counter ! Increment {}
// Wait for all messages to be processed
wait_for_idle()
println("Final count: ${counter.count}")
}
A block after a function call takes one of three shapes. They look alike but differ in semantics, and the choice is how a program separates DSL structure from runtime behaviour.
| Mode | Syntax | Semantics |
|---|---|---|
| Immediate | func() { block } | Runs inline at the call site, used for DSL structure |
| Closure | func() |x| { block } | Real closure with explicit params, hoisted to a C function |
| Callback | func() callback { block } | Real closure that captures enclosing scope, no params needed |
// Immediate, declarative structure, runs during construction
panel("Settings") {
button("OK")
button("Cancel")
}
// Closure, explicit params, deferred invocation
apply_twice(x: int, f: fn) { return call(f, call(f, x)) }
doubler = |x: int| -> x * 2
println(apply_twice(3, doubler)) // 12
// Callback, captures from scope, runs when invoked
counter = ref(0)
btn("increment") callback { ref_set(counter, ref_get(counter) + 1) }
btn("decrement") callback { ref_set(counter, ref_get(counter) - 1) }
The compiler distinguishes them at parse time, which is what the sandboxing above relies on: hide/seal except checks run against the hoisted form of closure and callback blocks, so a seal except req, res on a callback body keeps the body from reaching the outer scope. Immediate blocks inherit the caller's lexical scope by design: they are structure, not callbacks.
Inspired by Smalltalk blocks, Ruby's blocks/procs, Groovy closures, and Kotlin/SwiftUI's trailing-block DSLs. See Closures and Builder DSL for the builder-context mechanism, ref cells, and full DSL pattern; see Closure lineage and runtime tradeoffs for why Aether keeps closure-shaped values without adopting a Lisp/Smalltalk runtime.
Don't ship a YAML loader. If your Aether library has a "start the thing" surface, HTTP server, daemon, agent, scheduler, test rig, expose it as a closure-DSL block and let the operator's "config" be a .ae file they run with ae run. The pattern collapses YAML → templating → second-language-DSL (HCL, Helm) → embedded-scripting all into one thing: real Aether, type-checked, sandboxable, with the full stdlib available when the operator needs it.
import avnserver
main() {
avnserver.serve {
host("127.0.0.1")
port(9990)
superuser_token(env("SUPER_TOKEN")) // computed at config time
repo("alpha", "/srv/alpha")
repo("beta", "/srv/beta")
}
}
Same file is config, validation, conditional logic, and the entry point. No second parser, no second type system, no template language. Sandboxing (--emit=lib --with=..., hide, seal except) keeps it safe to accept untrusted configs as the embedded-DSL case demands. See Config IS Code for the full progression (YAML → HCL → Pulumi → here) and library-author recipe.
std.spec BDD framework (describe/it, assertions, fluent chain) + ae test discovery and --format=tap|aeocha-v1 reportingstd.http.proxy upstream pool, load balancing, health, cache, circuit breakerservirtium-vcr monorepo; no longer in the Aether stdlib~/.aether, MANIFEST format, downstream-link contract# Full CI suite (11 steps; the compiler is built with -Werror), on your current platform
make ci
# Unit tests only (runtime C test suite)
make test
# Integration + regression .ae tests
make test-ae
# Everything (unit + .ae)
make test-all
# Build and run every example, checking what it prints
make examples
# Full CI + Valgrind + ASan in Docker (Linux)
make docker-ci
CI runs on every pull request on: Linux (GCC, Clang, and a hardened GCC build), macOS (ARM64 and x86_64), Windows (MinGW/MSYS2, including the ownership grid), FreeBSD (a native build with the unit tests), and cross-compiles for FreeBSD and Android.
# Cooperative scheduler (no Docker needed)
make ci-coop
# Windows cross-compile syntax check (requires mingw-w64 or Docker)
make ci-windows # needs: brew install mingw-w64
make docker-ci-windows # or use Docker
# WebAssembly (requires Docker with Emscripten)
make docker-ci-wasm
# ARM embedded syntax check (requires Docker with arm-none-eabi-gcc)
make docker-ci-embedded
# All portability checks (coop + WASM + embedded)
make ci-portability
make ci tests your current OS only. macOS cannot be virtualized on Linux or Windows, and a Windows build and run needs MSYS2, so the other platforms are covered by GitHub Actions on every pull request. The Docker targets (docker-ci-windows, docker-ci-wasm, docker-ci-embedded) check cross-compilation from any host.
See CONTRIBUTING.md for the full pre-PR checklist.
# Run cross-language benchmark suite with interactive UI
make benchmark
# Open http://localhost:8080 to view results
The benchmark runner is written in Aether (run_benchmarks.ae), dogfooding the stdlib. It compiles and runs all 11 languages, parses output, and writes JSON results.
The Aether ecosystem includes downstream consumers that live in their own repos and release independently:
contrib/aether_ui/ in
this repo; spun out so it can iterate on its own cadence.share/aether/MANIFEST (the
authoritative list of link-suitable runtime/stdlib .c files) and
dispatches per-package builds with cache reuse and incremental
relinking.If you're adding to Aether and the change isn't a runtime / compiler /
stdlib concern, the right home may be one of the siblings above. Both
repos consume Aether the same way external users do, import against
the installed share/aether/ tree plus $(ae cflags) for the link
line, so they're useful references for downstream integration shapes.
Aether is under active development. The compiler, runtime, and standard library are functional and tested.
Contributions are welcome. See CONTRIBUTING.md for guidelines.
Areas of interest:
Aether is free and open source, built and maintained in personal time. CI runners, cross-platform testing infrastructure, and future project hosting cost real money.
If Aether is useful to you, consider sponsoring the project on GitHub. Every contribution goes directly into development and infrastructure.
Aether's main lineage is:
(value, err) returns,
and stdlib surfaces that favor direct operational code over framework magic.hide / seal, and explicit grants.do |x| ... end-style readability, and DSL-shaped APIs where the
closure is the configuration.Smaller facets are deliberately borrowed or adapted from elsewhere:
*StringSeq: O(1) head/tail/cons/length,
structural sharing, and pattern matching with [h | t].using embed: Sub while omitting
Odin's broader using statement form.<<MARKER ... MARKER syntax.filepath.Clean / filepath.Rel-style path helpers and proxy environment
handling compatible with HTTP_PROXY, HTTPS_PROXY, and NO_PROXY.MIT License. See LICENSE for details.
ae build --target=<triple>. See Architecture..aeaae bindgen consts, C macro constants as Aether constsimport/exports, PATH-style --lib search chain, selective imports, package layoutae help) - Offline heuristic diagnostics for closure-DSL config scripts (Levenshtein, YAML→call form, missing-import suggestions, --fix, --json, optional --llm)extern keyworddefer for handles, the ownership gridf(b: 1, a: 2), default parameters, platform selectionae fmt, --check, --short-namesae build --trace, per-message delivery trace as JSONL; compiled out entirely by default