{"id":43661675,"url":"https://github.com/aalpar/wile","last_synced_at":"2026-04-06T21:01:28.397Z","repository":{"id":328400548,"uuid":"1113465939","full_name":"aalpar/wile","owner":"aalpar","description":"Pure Go R7RS Scheme — embeddable interpreter with hygienic macros, first-class continuations, and sandboxing","archived":false,"fork":false,"pushed_at":"2026-04-02T06:32:03.000Z","size":14490,"stargazers_count":43,"open_issues_count":19,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-04-02T08:38:01.021Z","etag":null,"topics":["bytecode","compiler","concurrency","continuations","embeddable","go","golang","hygienic-macros","interpreter","lisp","programming-language","pure-go","r7rs","sandboxing","scheme","scripting-language","virtual-machine","wile"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/aalpar/wile","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aalpar.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"security/access.go","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-10T02:42:15.000Z","updated_at":"2026-04-02T03:11:27.000Z","dependencies_parsed_at":"2026-02-26T19:06:13.049Z","dependency_job_id":null,"html_url":"https://github.com/aalpar/wile","commit_stats":null,"previous_names":["aalpar/wile"],"tags_count":27,"template":false,"template_full_name":null,"purl":"pkg:github/aalpar/wile","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aalpar%2Fwile","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aalpar%2Fwile/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aalpar%2Fwile/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aalpar%2Fwile/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aalpar","download_url":"https://codeload.github.com/aalpar/wile/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aalpar%2Fwile/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31489427,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-06T17:22:55.647Z","status":"ssl_error","status_checked_at":"2026-04-06T17:22:54.741Z","response_time":112,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bytecode","compiler","concurrency","continuations","embeddable","go","golang","hygienic-macros","interpreter","lisp","programming-language","pure-go","r7rs","sandboxing","scheme","scripting-language","virtual-machine","wile"],"created_at":"2026-02-04T22:03:44.858Z","updated_at":"2026-04-06T21:01:28.384Z","avatar_url":"https://github.com/aalpar.png","language":"Go","readme":"# Wile\n\n[![CI](https://github.com/aalpar/wile/actions/workflows/ci.yml/badge.svg)](https://github.com/aalpar/wile/actions/workflows/ci.yml)\n[![Go Reference](https://pkg.go.dev/badge/github.com/aalpar/wile.svg)](https://pkg.go.dev/github.com/aalpar/wile)\n\n**R7RS Scheme in pure Go. No CGo, no C toolchain, no cross-compilation pain.**\n\nFull hygienic macros, first-class continuations, numeric tower, and sandboxing. `go get` and it just works.\n\n### Embed Scheme in 4 lines of Go\n\n```go\nengine, _ := wile.NewEngine(ctx)\nengine.Define(\"width\", wile.NewInteger(800))\nengine.Define(\"height\", wile.NewInteger(600))\nresult, _ := engine.Eval(ctx, engine.MustParse(ctx, \"(* width height)\"))  // =\u003e 480000\n```\n\n## Table of Contents\n\n- [Why Wile?](#why-wile)\n- [Embedding in Go](#embedding-in-go)\n- [Quick Start](#quick-start)\n- [Key Features in Action](#key-features-in-action)\n- [Installation](#installation)\n- [Usage](#usage)\n- [R7RS Standard Libraries](#r7rs-standard-libraries)\n- [Architecture](#architecture)\n- [Hygiene Model](#hygiene-model)\n- [Types](#types)\n- [Sandboxing](#sandboxing)\n- [Documentation](#documentation)\n- [Contributing](#contributing)\n\n## Why Wile?\n\n**Embedding a Lisp in Go means tradeoffs:**\n\n| Approach | Problem |\n|----------|---------|\n| Chibi-Scheme, S7 via CGo | Slow builds, broken cross-compilation, platform toolchain pain |\n| Lisp subsets (Zygomys, etc.) | No R7RS compliance, limited ecosystem |\n| Lua via go-lua | Not a Lisp, no macros, different semantics |\n| JavaScript via goja | Heavy runtime, no hygiene, async complexity |\n\n**Wile solves this:** Full R7RS Scheme in pure Go. Scheme values are Go heap objects, collected by Go's GC. No custom allocator, no FFI tax, no surprises.\n\n| Feature | Wile | Chibi/S7 (CGo) | Goja (JS) | Starlark | Lua |\n|---------|------|----------------|-----------|----------|-----|\n| Pure Go | ✓ | ✗ | ✓ | ✓ | ✗ |\n| Hygienic macros | ✓ | ✓ | ✗ | ✗ | ✗ |\n| R7RS compliance | ✓ | ✓ | N/A | N/A | N/A |\n| First-class continuations | ✓ | ✓ | ✗ | ✗ | ✗ |\n| Cross-compilation | ✓ | ✗ | ✓ | ✓ | ✗ |\n| Go GC integration | ✓ | ✗ | ✓ | ✓ | ✗ |\n\n### Performance\n\nGabriel benchmarks (16 programs), cumulative gains from v1.3.0 through opcode promotion and pool optimizations:\n\n| Benchmark | v1.3.0 | v1.9.0 | Change |\n|-----------|-------:|-------:|-------:|\n| tak | 0.381s | 0.117s | -69% |\n| fib | 1.262s | 0.381s | -70% |\n| sumfp | 4.271s | 1.068s | -75% |\n| peval | 0.168s | 0.079s | -53% |\n\nFull results and methodology in [examples/benchmarks/](examples/benchmarks/).\n\n## Embedding in Go\n\nThe [`wile`](https://pkg.go.dev/github.com/aalpar/wile) package provides the public API for embedding Scheme in Go.\n\n### Basic Usage\n\n```go\nimport \"github.com/aalpar/wile\"\n\n// Create an engine\nengine, err := wile.NewEngine(ctx)\nif err != nil {\n    log.Fatal(err)\n}\n\n// Evaluate a single expression\nresult, err := engine.Eval(ctx, engine.MustParse(ctx, \"(+ 1 2 3)\"))\nfmt.Println(result.SchemeString()) // \"6\"\n\n// Evaluate multiple expressions (returns last result)\nresult, err = engine.EvalMultiple(ctx, `\n  (define x 10)\n  (define y 20)\n  (+ x y)\n`)\n```\n\n### Compile Once, Run Many Times\n\n```go\ncompiled, err := engine.Compile(ctx, engine.MustParse(ctx, \"(+ x 1)\"))\nresult, err := engine.Run(ctx, compiled)\n```\n\n### Bridging Go and Scheme\n\nDefine Go values in Scheme's environment:\n\n```go\nengine.Define(\"my-var\", wile.NewInteger(100))\nval, ok := engine.Get(\"my-var\")\n```\n\nRegister a Go function as a Scheme primitive:\n\n```go\nimport \"github.com/aalpar/wile/values\"\n\nengine.RegisterPrimitive(wile.PrimitiveSpec{\n    Name:       \"go-add\",\n    ParamCount: 2,\n    Impl: func(mc wile.CallContext) error {\n        a := mc.Arg(0).(*values.Integer).Value\n        b := mc.Arg(1).(*values.Integer).Value\n        mc.SetValue(values.NewInteger(a + b))\n        return nil\n    },\n})\n// Now callable from Scheme: (go-add 3 4) =\u003e 7\n```\n\nCall a Scheme procedure from Go:\n\n```go\nproc, _ := engine.Get(\"my-scheme-function\")\nresult, err := engine.Call(ctx, proc, wile.NewInteger(42))\n```\n\n### Value Constructors\n\n| Constructor | Creates |\n|---|---|\n| `wile.NewInteger(n)` | Exact integer |\n| `wile.NewBigInteger(n)` | Exact arbitrary-precision integer (`*big.Int`) |\n| `wile.NewFloat(f)` | Inexact real |\n| `wile.NewBigFloat(f)` | Inexact arbitrary-precision float (`*big.Float`) |\n| `wile.NewRational(num, den)` | Exact rational |\n| `wile.NewComplex(v)` | Complex number (`complex128`) |\n| `wile.NewString(s)` | String |\n| `wile.NewSymbol(s)` | Symbol |\n| `wile.NewBoolean(b)` | `#t` / `#f` |\n| `wile.True` / `wile.False` | Boolean constants |\n| `wile.NewVector(vals...)` | Vector |\n| `wile.NewList(vals...)` | Proper list |\n| `wile.EmptyList` | Empty list `'()` |\n| `wile.Void` | Void value |\n\nThe [`values`](https://pkg.go.dev/github.com/aalpar/wile/values) package provides additional constructors (e.g., `NewRationalFromBigInt`, `NewComplexFromParts`).\n\n### Engine Options\n\n| Option | Description |\n|---|---|\n| `wile.WithExtension(ext)` | Add a single extension |\n| `wile.WithExtensions(exts...)` | Add multiple extensions |\n| `wile.WithSafeExtensions()` | Add safe extension set (no filesystem, eval, system, threads, Go interop) |\n| `wile.WithoutCore()` | Skip core primitives — bare engine with only explicit extensions |\n| `wile.WithLibraryPaths(paths...)` | Enable R7RS library system with search paths |\n| `wile.WithMaxCallDepth(n)` | Set maximum VM recursion depth |\n| `wile.WithAuthorizer(auth)` | Set fine-grained runtime authorization policy |\n| `wile.WithRegistry(r)` | Use a custom registry instead of the default core primitives |\n| `wile.WithSourceFS(fsys)` | Add a virtual `fs.FS` layer to the source resolver chain |\n| `wile.WithSourceOS()` | Add OS filesystem to the source resolver chain |\n| `wile.WithNamespace(ns)` | Use a pre-built namespace (see `NewNamespace`) |\n\n## Quick Start\n\n```bash\n# Install as a command-line tool\ngo install github.com/aalpar/wile/cmd/wile@latest\n\n# Or download a prebuilt binary from releases\n# https://github.com/aalpar/wile/releases\n\n# Run the REPL\nwile\n\n# Try an example\nwile --file examples/basics/hello.scm\n\n# See all examples\nls examples/\n```\n\n**Explore**:\n- [**76 Examples**](examples/) — Basics, macros, concurrency, numeric tower, and more\n- [**Gabriel Benchmarks**](examples/benchmarks/) — Scheme benchmarks for performance testing\n- [**Schelog**](examples/logic/schelog/) — Full Prolog-style logic programming embedded in Scheme\n- [**Embedding Guide**](examples/embedding/) — How to use Wile from Go\n\n## Key Features in Action\n\n**Logic Programming** — Full Prolog embedded in Scheme\n\n```scheme\n(load \"examples/logic/schelog/schelog.scm\")\n\n(%rel (append xs ys zs)\n  ((append () ?ys ?ys))\n  ((append (?x . ?xs) ?ys (?x . ?zs))\n   (append ?xs ?ys ?zs)))\n\n(%which (zs)\n  (append '(1 2) '(3 4) zs))\n;; ⇒ ((zs 1 2 3 4))\n```\n\n*See [examples/logic/schelog/](examples/logic/schelog/) for a self-contained Prolog implementation in Scheme.*\n\n**Numeric Tower** — Exact rationals, complex numbers, and arbitrary precision\n\n```scheme\n(/ 1 3)              ; ⇒ 1/3 (exact rational, not 0.333...)\n(* 1/3 3)            ; ⇒ 1 (exact)\n(make-rectangular 0 1) ; ⇒ 0+1i (exact complex)\n(expt 2 1000)        ; ⇒ 10715086071862673209484250490...\n```\n\n**Hygienic Macros** — Build DSLs without variable capture\n\n```scheme\n(load \"examples/macros/state-machine.scm\")\n\n(define-state-machine traffic-light\n  (states: red yellow green)\n  (initial: red)\n  (transitions:\n   (red -\u003e green)\n   (green -\u003e yellow)\n   (yellow -\u003e red)))\n```\n\n**Go-Native Concurrency** — Goroutines and channels from Scheme\n\n```scheme\n(let ((ch (make-channel)))\n  (thread-start!\n   (make-thread\n    (lambda () (channel-send! ch 42))))\n  (channel-receive ch))  ; ⇒ 42\n```\n\n**First-Class Continuations** — Non-local control flow\n\n```scheme\n;; Early return\n(call/cc (lambda (return)\n  (for-each (lambda (x)\n              (if (negative? x)\n                  (return x)))\n            '(1 2 -3 4))\n  'not-found))  ; ⇒ -3\n\n;; See examples/control/ for generators, coroutines, and backtracking\n```\n\n## Installation\n\nRequires Go 1.24 or later.\n\n### As a library\n\n```bash\ngo get github.com/aalpar/wile@latest\n```\n\n### As a standalone interpreter\n\nDownload a prebuilt binary from [Releases](https://github.com/aalpar/wile/releases), or build from source:\n\n```bash\ngit clone https://github.com/aalpar/wile.git\ncd wile\nmake build\n```\n\nThe binary is built to `./dist/{os}/{arch}/wile`.\n\n## Usage\n\n```bash\n# Start REPL\nwile\n\n# Run a Scheme file\nwile example.scm\nwile --file example.scm\nwile -f example.scm\n\n# With library search path\nwile -L /path/to/libs example.scm\n\n# Enter REPL after loading file\nwile -f example.scm -i\n\n# Print version\nwile --version\n```\n\nThe `SCHEME_LIBRARY_PATH` environment variable provides additional library search paths (colon-separated).\n\n### REPL Debugger\n\nThe REPL includes a debugger. Commands start with `,`:\n\n| Command | Description |\n|---------|-------------|\n| `,break FILE:LINE` | Set breakpoint |\n| `,delete ID` | Delete breakpoint |\n| `,list` | List breakpoints |\n| `,step` | Step into next expression |\n| `,next` | Step over (same frame) |\n| `,finish` | Step out (return from function) |\n| `,continue` | Continue execution |\n| `,backtrace` | Show stack trace |\n| `,where` | Show current source location |\n\n## R7RS Standard Libraries\n\n| Library | Description |\n|---|---|\n| `(scheme base)` | Core language: arithmetic, pairs, lists, strings, vectors, control |\n| `(scheme case-lambda)` | `case-lambda` form |\n| `(scheme char)` | Character predicates and case conversion |\n| `(scheme complex)` | Complex number operations |\n| `(scheme cxr)` | Compositions of `car` and `cdr` |\n| `(scheme eval)` | `eval` and `environment` |\n| `(scheme file)` | File I/O |\n| `(scheme inexact)` | Transcendental functions (`sin`, `cos`, `exp`, `log`, `sqrt`, etc.) |\n| `(scheme lazy)` | Promises (`delay`, `force`, `make-promise`) |\n| `(scheme load)` | `load` |\n| `(scheme read)` | `read` |\n| `(scheme write)` | `write`, `display` |\n| `(scheme repl)` | `interaction-environment` |\n| `(scheme process-context)` | `command-line`, `exit`, `get-environment-variable` |\n| `(scheme time)` | `current-second`, `current-jiffy`, `jiffies-per-second` |\n| `(scheme r5rs)` | R5RS compatibility |\n\n### Additional Libraries\n\n| Library | Description |\n|---|---|\n| `(srfi 1)` | List library (constructors, predicates, fold, search, set operations) |\n| `(chibi test)` | Minimal test framework (for R7RS test compatibility) |\n| `(chibi diff)` | Diff utilities |\n| `(chibi optional)` | Optional value handling |\n| `(chibi term ansi)` | ANSI terminal escape codes |\n\n### Extension Libraries\n\nWith the library system enabled (`WithLibraryPaths`), Go extensions import as `(wile \u003cname\u003e)`:\n\n| Library | Description |\n|---|---|\n| `(wile math)` | Transcendental functions, numeric utilities |\n| `(wile files)` | File I/O |\n| `(wile threads)` | SRFI-18 multithreading (threads, mutexes, condition variables) |\n| `(wile system)` | System interaction (environment, process) |\n| `(wile gointerop)` | Go concurrency primitives (channels, wait groups, atomics) |\n| `(wile introspection)` | Reflection and introspection |\nSee [`docs/EXTENSION_LIBRARIES.md`](docs/EXTENSION_LIBRARIES.md) for import syntax and modifiers.\n\nGo static analysis extensions (AST, SSA, CFG, callgraph, lint) have been extracted to [wile-goast](https://github.com/aalpar/wile-goast).\n\n## Architecture\n\n```\nSource → Tokenizer → Parser → Expander → Compiler → VM\n```\n\n1. **[Tokenizer](internal/tokenizer/)** — Lexical analysis with comprehensive R7RS token support\n2. **[Parser](internal/parser/)** — Builds syntax tree with source location tracking\n3. **[Expander](https://pkg.go.dev/github.com/aalpar/wile/machine)** — Macro expansion using `syntax-rules`/`syntax-case` with scope sets\n4. **[Compiler](https://pkg.go.dev/github.com/aalpar/wile/machine)** — Generates bytecode operations\n5. **[VM](https://pkg.go.dev/github.com/aalpar/wile/machine)** — Executes bytecode with stack-based evaluation\n\n### Package Structure\n\n| Package | Purpose |\n|---------|---------|\n| [`wile`](https://pkg.go.dev/github.com/aalpar/wile) (root) | Public embedding API |\n| [`machine/`](https://pkg.go.dev/github.com/aalpar/wile/machine) | Virtual machine, compiler, macro expander |\n| [`values/`](https://pkg.go.dev/github.com/aalpar/wile/values) | Scheme value types (numbers, pairs, ports, threads, etc.) |\n| [`werr/`](https://pkg.go.dev/github.com/aalpar/wile/werr) | Error infrastructure (sentinel errors, contextual wrapping) |\n| [`environment/`](https://pkg.go.dev/github.com/aalpar/wile/environment) | Variable binding, scope chains, phase hierarchy |\n| [`registry/`](https://pkg.go.dev/github.com/aalpar/wile/registry) | Extension registration and primitives |\n| [`registry/core/`](https://pkg.go.dev/github.com/aalpar/wile/registry/core) | Essential primitives and bootstrap macros |\n| [`security/`](https://pkg.go.dev/github.com/aalpar/wile/security) | Fine-grained runtime authorization |\n| [`registry/helpers/`](https://pkg.go.dev/github.com/aalpar/wile/registry/helpers) | Shared utilities for primitive implementations |\n| [`extensions/`](https://pkg.go.dev/github.com/aalpar/wile/extensions) | Public extension packages (files, math, threads, system, etc.) |\n| [`runtime/`](https://pkg.go.dev/github.com/aalpar/wile/runtime) | Compile/Run API for embedding |\n| [`internal/syntax/`](internal/syntax/) | First-class syntax objects with scope sets |\n| [`internal/match/`](internal/match/) | Pattern matching engine for macros |\n| [`internal/parser/`](internal/parser/) | Scheme parser |\n| [`internal/tokenizer/`](internal/tokenizer/) | Lexer |\n| [`internal/validate/`](internal/validate/) | Syntax validation |\n| [`internal/forms/`](internal/forms/) | Compiled form definitions |\n| [`internal/schemeutil/`](internal/schemeutil/) | Scheme utility functions |\n| [`internal/repl/`](internal/repl/) | Interactive REPL with debugger |\n| [`internal/bootstrap/`](internal/bootstrap/) | Environment initialization |\n| [`internal/extensions/`](internal/extensions/) | Internal extension wiring (io, eval, aggregate registration) |\n\n### API Stability\n\nThese packages form the public API and follow [Go module versioning](https://go.dev/doc/modules/version-numbers):\n\n- **[`wile`](https://pkg.go.dev/github.com/aalpar/wile)** (root) — `Engine`, `RegisterFunc`, `Eval`/`Compile`/`Run`, error types\n- **[`values`](https://pkg.go.dev/github.com/aalpar/wile/values)** — Scheme value types, `Value` interface, numeric tower\n- **[`werr`](https://pkg.go.dev/github.com/aalpar/wile/werr)** — Sentinel errors, `WrapForeignErrorf`, error infrastructure\n- **[`registry`](https://pkg.go.dev/github.com/aalpar/wile/registry)** — `Registry`, `Extension`, `PrimitiveSpec`, phase constants\n- **[`security`](https://pkg.go.dev/github.com/aalpar/wile/security)** — `Authorizer`, `AccessRequest`, built-in authorizers\n- **[`extensions/*`](https://pkg.go.dev/github.com/aalpar/wile/extensions)** — Public extensions (files, math, threads, system, etc.)\n\nAll other packages ([`machine/`](https://pkg.go.dev/github.com/aalpar/wile/machine), [`environment/`](https://pkg.go.dev/github.com/aalpar/wile/environment), [`internal/`](internal/)) are implementation details and may change without notice. The `machine` package is importable but carries no compatibility guarantees.\n\n## Hygiene Model\n\nWile uses the \"sets of scopes\" approach from Flatt's 2016 paper. Each identifier carries a set of scopes, and variable resolution checks that the binding's scopes are a subset of the use site's scopes:\n\n```\nbindingScopes ⊆ useScopes\n```\n\nThis prevents unintended variable capture in macros:\n\n```scheme\n(define-syntax swap!\n  (syntax-rules ()\n    ((swap! x y)\n     (let ((tmp x))    ; tmp gets macro's scope\n       (set! x y)\n       (set! y tmp)))))\n\n(let ((tmp 5) (a 1) (b 2))  ; this tmp has different scope\n  (swap! a b)\n  tmp)  ; =\u003e 5, not captured by macro's tmp\n```\n\n## Types\n\n### Numeric Tower\n\n| Type | Description | Example |\n|------|-------------|---------|\n| Integer | Exact 64-bit signed | `42`, `-17` |\n| BigInteger | Exact arbitrary precision | `#z12345678901234567890` |\n| Rational | Exact fraction | `3/4`, `-1/2` |\n| Float | Inexact IEEE 754 double | `3.14`, `1e10` |\n| BigFloat | Inexact arbitrary precision | `#m3.14159265358979323846` |\n| Complex | Inexact complex (float64 parts) | `1+2i`, `3@1.57` (polar) |\n| BigComplex | Arbitrary-precision complex | Exact or inexact parts |\n\n### Concurrency Types\n\n| Type | Description |\n|------|-------------|\n| Thread | SRFI-18 thread |\n| Mutex | SRFI-18 mutex |\n| Condition Variable | SRFI-18 condition variable |\n| Channel | Go channel wrapper |\n| WaitGroup | Go sync.WaitGroup wrapper |\n| RWMutex | Go sync.RWMutex wrapper |\n| Atomic | Thread-safe mutable value |\n\n## Sandboxing\n\nWile sandboxes embedded engines with two independent, composable layers.\n\n### Layer 1: Extension-based (compile-time)\n\nPrimitives not loaded into the engine don't exist. Attempts to use them produce compile-time errors — there are no runtime checks to bypass.\n\n```go\n// Safe sandbox: no filesystem, eval, system, threading, or Go interop\nengine, err := wile.NewEngine(ctx, wile.WithSafeExtensions())\n```\n\nCompose with specific privileged extensions:\n\n```go\nengine, err := wile.NewEngine(ctx,\n    append(wile.SafeExtensions(),\n        wile.WithExtension(files.Extension),\n    )...,\n)\n```\n\nLibrary environments inherit the engine's registry, so restrictions propagate transitively to loaded libraries.\n\n### Layer 2: Fine-grained authorization (runtime)\n\nThe `security.Authorizer` interface gates privileged operations with K8s-style resource+action vocabulary:\n\n```go\nengine, err := wile.NewEngine(ctx,\n    wile.WithSafeExtensions(),\n    wile.WithExtension(files.Extension),\n    wile.WithAuthorizer(security.All(\n        security.ReadOnly(),\n        security.FilesystemRoot(\"/app/data\"),\n    )),\n)\n// Can read files under /app/data, nothing else\n```\n\nBuilt-in authorizers: `DenyAll()`, `ReadOnly()`, `FilesystemRoot(path)`, `All(authorizers...)` (AND-composition).\n\nSee [`docs/SANDBOXING.md`](docs/SANDBOXING.md) for the full security model, extension classification, known gaps, and custom authorizer examples.\n\n## Documentation\n\n| Document | Description |\n|----------|-------------|\n| [`docs/SCHEME_REFERENCE.md`](docs/SCHEME_REFERENCE.md) | Complete Scheme language reference |\n| [`docs/SANDBOXING.md`](docs/SANDBOXING.md) | Sandboxing and security model |\n| [`docs/EXTENSIONS.md`](docs/EXTENSIONS.md) | Extension system architecture and authoring guide |\n| [`docs/EXTENSION_LIBRARIES.md`](docs/EXTENSION_LIBRARIES.md) | R7RS library integration for extensions |\n| [`PRIMITIVES.md`](PRIMITIVES.md) | Complete reference of types and primitives |\n| [`docs/design/DESIGN.md`](docs/design/DESIGN.md) | Macro system design |\n| [`docs/design/EMBEDDING.md`](docs/design/EMBEDDING.md) | Embedding API design |\n| [`docs/design/DELIMITED_CONTINUATIONS.md`](docs/design/DELIMITED_CONTINUATIONS.md) | Delimited continuation implementation |\n| [`docs/dev/NUMERIC_TOWER.md`](docs/dev/NUMERIC_TOWER.md) | Numeric tower architecture |\n| [`docs/dev/ENVIRONMENT_SYSTEM.md`](docs/dev/ENVIRONMENT_SYSTEM.md) | Environment system architecture |\n| [`docs/dev/R7RS_SEMANTIC_DIFFERENCES.md`](docs/dev/R7RS_SEMANTIC_DIFFERENCES.md) | Documented differences from R7RS |\n| [`BIBLIOGRAPHY.md`](BIBLIOGRAPHY.md) | Academic references |\n| [`CHANGELOG.md`](CHANGELOG.md) | Release history |\n\n## References\n\n- [Binding as Sets of Scopes](https://www.cs.utah.edu/plt/scope-sets/) — Flatt (2016)\n- [R7RS Scheme](https://small.r7rs.org/) — Language specification\n- [SRFI-18](https://srfi.schemers.org/srfi-18/) — Multithreading\n\n## Contributing\n\nWile welcomes contributions. Help wanted:\n\n- **Documentation** — Examples, guides, tutorials\n- **Standard library** — R7RS-small features, SRFI implementations\n- **Test coverage** — Broader coverage across packages\n- **Performance** — Allocation reduction, targeted optimizations\n- **Tooling** — REPL improvements, debugging tools, IDE integration\n\n**Get started:**\n- Browse [issues labeled `good-first-issue`](https://github.com/aalpar/wile/labels/good-first-issue)\n- Check [help wanted](https://github.com/aalpar/wile/labels/help-wanted) for high-priority items\n- Read [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines and workflow\n\n## License\n\nThis project is licensed under the Apache License 2.0 — see the [LICENSE](LICENSE) file for details.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faalpar%2Fwile","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faalpar%2Fwile","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faalpar%2Fwile/lists"}