neuron-explorer
Qwen3.5‑4B 전용 조향형 뉴런 탐색기, 모든 MLP 뉴런을 밀어 결과를 보관·탐색
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Silk is an unreleased low-level systems language built around explicit memory and execution
control, typed failures, replaceable service requirements, deterministic cleanup, and
tooling-friendly semantics. The repository is a strict TypeScript, ESM-only monorepo containing the
stage-0 compiler, runtime-facing libraries, editor tooling, and language-pressure programs.README 전문 보기 ↗Silk compiles to native code and WebAssembly through LLVM, with no garbage collector, no hidden allocation and no ambient I/O. A function's signature tells you everything it can do: what it returns, how it can fail, and which services it needs. The compiler checks all of it, and cleanup runs at a point you can see in the source.
effect fn remaining(deadline: u64) -> u64 ! Expired | LogError ? &Clock | &mut Logger {
let now = run Clock.now()
if now > deadline { fail Expired {} }
run Effect.log("{left} ticks left\n", &.{ left: deadline - now })
return deadline - now
}
Read it as "returns a u64, may fail with Expired or LogError, and needs a Clock to read and
a Logger to write to". The function doesn't know which clock or logger it gets. The caller
decides, and a test can hand it fakes.
The compiler is written in Silk and builds itself.
! E lists every error a computation can raise. fail raises one,
Effect.catch handles it, and the handled error leaves the type.services that a computation asks for with ? &Service. Providers are
ordinary values, so a test or a browser host swaps one in without mocking anything global.move transfers them, & and &mut borrow
them, and Drop runs exactly once at a deterministic point. Using a value after it moved is a
compile error.? &mut Allocator, and you choose which allocator it gets.static parameters, let static and static if run at compile time
against the selected target, and only the chosen branch reaches the program.Intrinsic namespace. Effect, Result, List, logging and the file system are ordinary Silk
in stdlib/, and you can read them like your own code.On macOS (Apple Silicon) or Linux (x86-64 or ARM64):
curl -fsSL https://raw.githubusercontent.com/silk-lang/silk/main/install.sh | sh
The script installs the latest stable release in ~/.silk/toolchains/<version> (set SILK_HOME
to change ~/.silk) and makes it your default. It also installs the silk tool, the command
you type for Silk, as ~/.silk/bin/silk; each release's compiler is silkc. It verifies the
compiler's SHA-256 and reported version, and the release signature when minisign is installed.
Earlier versions stay installed beside it.
Set SILK_RELEASE=v0.2.0-beta.1 to select a published prerelease explicitly. Building programs
needs Clang 22 or newer on PATH, or SILK_CLANG pointing at it.
With Homebrew, which also installs Homebrew's LLVM and points silk at its Clang:
brew install silk-lang/tap/silk
With mise, from the release archives:
mise use -g 'github:silk-lang/silk[version_prefix=v]'
Homebrew follows the same channel as the script. mise picks stable releases only; until the first
one exists, use github:silk-lang/silk[version_prefix=v,prerelease=true] to get dev releases.
A project pins its Silk version with silk-version in silk.toml, under [package] or
[workspace]. silk reads the pin and runs that version from ~/.silk/toolchains, so projects on
different versions work side by side. Outside a pinned project it runs your default version. In a
workspace the [workspace] pin wins over the members' own, and silk set sets it and moves any
member pins along with it.
silk use # install the version this project pins
silk use 0.1.0-dev.11 # install a version and make it your default
silk set latest # pin this project to the newest stable release (--dev: include dev releases)
silk use list # installed versions, and which one is selected here
silk use which # the version selected here, and why
silk +0.1.0-dev.11 build # run one command with an installed version
silk update self # update the silk tool itself
Every other command, such as silk build or silk test, runs unchanged in the selected
version's compiler. When the pinned version is missing, the command exits with status 3 and names
the silk use command that fixes it. Set SILK_AUTO_INSTALL=1, or auto-install = true in
~/.silk/settings.toml, to install it automatically instead. SILK_TOOLCHAIN=<version>
overrides the selection for a shell. See tool/README.md for the rest. Homebrew and mise
install silk beside its release's silkc, which it runs when nothing selects another version.
silk init hello && cd hello
silk run
Hello, world!
silk init writes a silk.toml and a src/main.silk. Even "hello world" names what it needs:
import silk.core.effect { Effect }
import silk.io.logger { LogError }
import silk.io.logger_native { StdoutLogger }
pub effect fn main() -> ()
! LogError {
let mut logger = StdoutLogger.make()
run Effect.log("Hello, world!", &()) |> Effect.provideMut(&mut logger)
}
silk change records release notes and cuts releases. It is implemented in the changes/
Silk package and reads the [release] table of silk.toml. From a package directory:
silk change minor "Reads now return a future." --migration "Await read()."
silk change status
silk change version --tag beta
silk change version
silk change release --json
silk change since 0.1.0 --json
Each contribution gets its own .changes/<random>.md, avoiding shared changelog edits in PRs.
Write the summary as one line. Migration guidance is only for changes that consumers must act on;
no guidance means no action is needed. Releases
consume pending changes, update the package version, and write authoritative
.changes/releases/<version>.toml records. CHANGELOG.md is regenerated from those records
with a warning that manual edits will be overwritten. An optional [release].version-file
generates a Silk module exposing the package's version in the same recovery transaction.
Commit the records, changelog, manifest, generated module, and consumed-file deletions together.
release checks the prepared release and exports its notes and metadata for a publisher.
These commands do not commit, tag, publish, or access Git.
silk change since selects compiler upgrades from the project's package.silk-version.
since <dependency> starts at that dependency's installed manifest version; --to VERSION
selects an exact target. Published queries compare immutable changes-snapshot.toml release
assets, including pending notes that actually shipped in a dev release—not today's open changes.
Unchanged notes are deduplicated across dev-to-stable promotion; edited migration guidance is
shown again as updated. --source PATH supports offline checkouts and snapshot files.
silk change --help lists the discovery and trust settings.
The compiler uses this flow itself. A maintained draft release PR collects pending changes;
merging it publishes stable after the native gates pass. Daily or manually triggered dev releases
use 0.1.0-dev.N+<commit> versions without consuming pending notes or changing the committed
changelog. 0.1.0 remains reserved for the first announcement. See the
compiler release procedure.
A service declares operations. Any value can provide it through an impl, and Effect.provide
hands that value to a computation.
service Clock {
effect fn now() -> u64 ? &Clock
}
struct FixedClock { at: u64 }
impl Clock for FixedClock {
effect fn now(self: &Self) -> u64 { return self.at }
}
struct Expired {}
effect fn expired(error: Expired) -> u64 { return 0 }
pub effect fn main() -> () ! LogError {
let clock = FixedClock { at: 58 }
let mut logger = StdoutLogger.make()
let left = run Effect.catch<Expired>(remaining(100), expired)
|> Effect.provide(&clock)
|> Effect.provideMut(&mut logger)
}
42 ticks left
Effect.catch<Expired> takes Expired out of the error type. main still declares LogError,
because nothing handled it.
silk test finds test declarations through the import graph. This one runs remaining against
the fixed clock and the standard library's in-memory logger:
test effect fn reportsTheTimeLeft() -> () ! AssertionError<'static> | Expired | LogError {
let clock = FixedClock { at: 58 }
let mut logger = Logger.inMemoryProvider()
let left = run remaining(100)
|> Effect.provide(&clock)
|> Effect.provideMut(&mut logger)
run Testing.expect(left == 42 && Logger.length(&logger) == 1, "one log line, 42 ticks left")
}
$ silk test
main::reportsTheTimeLeft
PASS 19 us
Tests 1 passed, 0 failed (0 cached, 1 executed, 1 selected, 1 discovered)
import silk.core.ownership { Drop }
struct Connection { id: i32 }
impl Drop for Connection {
fn drop(self: &mut Connection) -> () { return () }
}
fn peek(connection: &Connection) -> i32 { return connection.id }
fn close(connection: Connection) -> i32 { return connection.id }
pub fn main() -> i32 {
let connection = Connection { id: 7 }
let seen = peek(&connection)
let closed = close(move connection)
return seen + closed
}
peek borrows the connection. close takes ownership, so drop runs when close returns. Change
the last line to return seen + closed + connection.id and the compiler stops you:
src/main.silk:17:26: error[OWN0001] connection was moved and cannot be used again
Unions are structural, and a match has to cover every case.
struct Circle { radius: f64 }
struct Rect { width: f64, height: f64 }
fn area(shape: Circle | Rect) -> f64 {
return match move shape {
Circle c => 3.14159 * c.radius * c.radius
Rect r => r.width * r.height
}
}
import silk.core.target { Target, Arch }
fn wordBits() -> u32 {
static if Target.arch() == Arch.Wasm32 {
return 32
} else {
return 64
}
}
The condition is evaluated for the target being built. Only the chosen branch reaches the program, so nothing is checked at run time.
| Command | What it does |
|---|---|
silk init | Create a package with silk.toml and src/main.silk |
silk build / silk run | Compile for one or more targets, in debug or --release |
silk check | Check types, ownership and effects without building |
silk test | Discover and run test declarations |
silk format | Format source canonically, with --check for CI |
silk doc / silk doctest | Extract documentation from /// comments and compile their examples |
silk clean | Remove build output |
The standard library is written in Silk and documented with silk doc.
It includes:
Effect, Result, Option, List, HashMap, Box, Shared, strings, Unicode,
formatting, and checked arithmetic for every scalar type.Native hosts are Apple Silicon macOS (aarch64-apple-darwin), x86-64 Linux
(x86_64-unknown-linux-gnu) and ARM64 Linux (aarch64-unknown-linux-gnu). WebAssembly
(wasm32-unknown-unknown) is a freestanding output target. WASI commands target
wasm32-wasip1 (core modules) or wasm32-wasip2 (components). Preview 2 also supports
TCP, UDP, DNS, HTTP clients and servers, and custom WIT worlds. See the
WASI guide for build tools, runtime commands, and host services.
Silk is pre-alpha. The language is still being designed, and any API may change without notice. The language reference is prescriptive, and each rule says whether it is confirmed, a candidate or still open.
Every change has to build the compiler with itself twice in a row and get identical LLVM IR both times. It also has to run a shared corpus of 443 programs with exactly the expected results.
| Path | Contents |
|---|---|
compiler/ | The compiler, written in Silk |
changes/ | Changes, release versions, migration notes, and changelogs |
tool/ | The silk tool, the front door: Silk versions and forwarding |
tomledit/ | Comment-preserving silk.toml edits, shared by both |
stdlib/ | The standard library |
reference/ | The language reference and the generated stdlib reference |
corpus/ | The shared acceptance corpus |
examples/ | Larger example programs |
The root silk.toml defines a native workspace containing compiler, changes, tomledit and
tool. Members
share the root build/ directory; the root is not itself a package. Select a member explicitly
from the root, for example silk build --manifest-path compiler/silk.toml --stdlib stdlib or
silk change --dir compiler status. Release operations affect one package at a time.
The compiler builds itself from the published seed pinned in
compiler/native-seed.json. compiler/README.md
walks through building it and running its source-written test suites. Repository tooling runs on
Node and pnpm:
pnpm install
pnpm test:scripts
On Debian or Ubuntu, bash scripts/setup-linux-llvm.sh installs the verified LLVM 22 toolchain
under .scratch/llvm-22.1.8. Put its bin directory on PATH.
MIT © 2026 Julia Ortiz