initial training pipeline: Jerboa LoRA on Qwen3-Coder-30B-A3B
ober
14ca8f04978191c636ea4e89336eefab0012b56e
new file mode 100644 --- /dev/null +++ b/.gitignore @@ -0,0 +1,47 @@ +# Training outputs +jerboa-lora-output/ +jerboa-qwen-gguf/ + +# Downloaded adapter, merged model, and converted GGUF +together-adapter/ +together-adapter-mlx/ +together-adapter-v3/ +together-adapter-v3-mlx/ +together-merged/ +jerboa-lora-adapter.gguf + +# llama.cpp (cloned for converter) +llama.cpp/ + +# Pipeline + adapter outputs (multi-GB binary) +runpod-pipeline-final/ +jerboa-mlx-4bit-v2/ +mlx_data/ +mlx_data_v1/ +mlx_adapters/ +mlx_adapters_v1/ + +# Logs +*.log + +# Local state (file/job IDs, pod IDs, ssh hosts — keep local) +.together_state.json +.together_state_v2.json +.together_state_v3.json +.runpod_state.json + +# Editor / agent state +.claude/ + +# Python +__pycache__/ +*.pyc +*.egg-info/ +.venv/ + +# Large generated data (track the generator, not the output) +# Uncomment these if you want to track the data in git: +# training_data.jsonl +# training_data_alpaca.jsonl +# training_data_alpaca.json +# training_data_together.jsonl new file mode 100644 --- /dev/null +++ b/Modelfile @@ -0,0 +1,8 @@ +FROM qwen2.5:7b-instruct +ADAPTER ./jerboa-lora-adapter.gguf + +SYSTEM "You are an expert in Jerboa Scheme, a Chez-Scheme-based dialect with a Gerbil-flavored prelude. You provide accurate, idiomatic Jerboa code with correct imports, function names, and arities. Module paths use the (jerboa ...) and (std ...) forms — never :std/foo (Gerbil) or (srfi :NN) (R7). You know the prelude, the actor system, fibers, the FFI, capability security, the macro system (defrules, syntax-case), pattern matching (match), and how Jerboa diverges from Gerbil/Racket/Clojure/SRFI. When writing code, always include required (import ...) statements." + +PARAMETER temperature 0.2 +PARAMETER num_ctx 32768 +PARAMETER stop "<|im_end|>" new file mode 100644 --- /dev/null +++ b/TODO.md @@ -0,0 +1,154 @@ +# Jerboa Scheme LoRA Training — Together AI + +## Status + +- [x] Scaffold scripts (forked from gerbil-lora) +- [x] Generate training data (4,622 entries from cookbooks, docs, api signatures, divergence, tests, source) +- [ ] Upload training data to Together AI +- [ ] Start fine-tuning job +- [ ] Wait for training to complete (~7 min expected for 7B / 3 epochs) +- [ ] Download adapter and convert to GGUF +- [ ] Deploy locally with Ollama +- [ ] Push to Ollama registry (`./push_ollama.sh jaimef`) +- [ ] Deploy to RunPod serverless (`./deploy_runpod.sh`) +- [ ] Verify model with `verify_model.py` +- [ ] Connect to OpenCode + +--- + +## Training Data + +Generated **4,622 training entries** in `~/mine/jerboa-lora/`: + +| File | Format | Size | +|--------------------------------|------------------------|--------| +| `training_data_together.jsonl` | Together AI (messages) | 8.7 MB | +| `training_data.jsonl` | ChatML/ShareGPT | 9.0 MB | +| `training_data_alpaca.jsonl` | Alpaca JSONL | 6.1 MB | + +### Source breakdown + +| Source | Count | +|--------|-------| +| doc | 2,320 | +| cookbook | 924 | +| api | 626 | +| test | 270 | +| divergence | 238 | +| errorfix | 112 | +| security | 83 | +| convention | 24 | +| std-source | 21 | +| source | 4 | + +Regenerate: `python3 convert_training_data.py` + +--- + +## Step 1: Setup + +```bash +pip install together +export TOGETHER_API_KEY="your-key-here" +``` + +## Step 2: Upload + +```bash +python3 train_together.py upload +``` + +Saves `file_id` to `.together_state.json`. + +## Step 3: Train + +```bash +python3 train_together.py train +``` + +Saves `job_id` to `.together_state.json`. Training settings: +- LoRA r=16, alpha=32 +- 3 epochs, learning rate 1e-5, batch size 8 +- Base model: Qwen/Qwen2.5-7B-Instruct + +## Step 4: Wait & Status + +```bash +python3 train_together.py status +``` + +When done, the model name (e.g. `jaimef_xxxx/Qwen2.5-7B-Instruct-yyyyyyyy`) is saved to state. + +--- + +## Step 5: Deploy — Choose Your Option + +### Option A: Local Ollama (free, needs GPU for good speed) + +**No merge required** — Ollama supports LoRA adapters natively. + +```bash +./download_and_convert.sh +``` + +Or pull from the registry once published: +```bash +ollama pull jaimef/jerboa-qwen +``` + +Configure OpenCode: +```bash +./configure_opencode.sh ollama +``` + +### Option B: RunPod Serverless (scale-to-zero, ~$0.39/hr active) + +```bash +export RUNPOD_API_KEY="your-key" +hf auth login +./deploy_runpod.sh jaimef21/jerboa-qwen-7b +``` + +The script auto-reads JOB_ID from `.together_state.json`. + +Configure OpenCode: +```bash +./configure_opencode.sh runpod <ENDPOINT_ID> +``` + +### Option C: Local Unsloth training (free, needs 16GB+ GPU) + +If you have an RTX 4090 / 3090 / A100 etc.: +```bash +python3 train_unsloth.py # → ./jerboa-lora-output/ +python3 merge_and_export.py # → ./jerboa-qwen-gguf/ +ollama create jerboa-qwen -f Modelfile +``` + +--- + +## Verification + +```bash +# Local +python3 verify_model.py --base-url http://localhost:11434/v1 --model jerboa-qwen -v + +# RunPod +python3 verify_model.py \ + --base-url https://api.runpod.ai/v2/<ENDPOINT_ID>/openai/v1 \ + --model jaimef21/jerboa-qwen-7b \ + --api-key $RUNPOD_API_KEY -v +``` + +10 test cases covering: prelude imports, divergence (hash-has-key? → hash-key?), fibers, JSON, try/catch, pattern matching, sort, actor system, error conditions. + +--- + +## Iteration + +To improve quality: +1. Add recipes to `~/mine/jerboa-mcp/cookbooks.json` +2. Add new divergence entries for caught hallucinations +3. `python3 convert_training_data.py` +4. `python3 train_together.py upload && python3 train_together.py train` +5. Redeploy new file mode 100644 --- /dev/null +++ b/TRAINING_PIPELINE.md @@ -0,0 +1,208 @@ +# Jerboa LoRA — Staged Training Pipeline + +This document explains the **CPT → SFT → DPO** pipeline now driving the Jerboa +fine-tune, why it replaces the previous single-stage SFT approach, and what +each piece is contributing. + +--- + +## TL;DR + +| | Old (single-stage SFT) | New (staged pipeline) | +|---|---|---| +| Stages | 1 (SFT only) | 3 (CPT → SFT → DPO) | +| Where | Together AI (whitelisted) **or** local MLX | Axolotl on RunPod A100 80GB | +| MoE expert coverage | ✗ on Together, partial on MLX | ✓ full (`experts.gate_up_proj`, `experts.down_proj`) | +| Teaches token distribution | ✗ (skipped — model never sees raw Jerboa) | ✓ (CPT stage) | +| Suppresses Gerbil/Racket hallucinations | weak (SFT teaches right form once) | strong (DPO actively penalises wrong form) | +| Uses divergence pairs as preferences | ✗ (turned into Q/A — wasted signal) | ✓ (DPO triples) | +| Uses raw Jerboa source files | ✗ | ✓ (499 files, 4.3 MB) | +| Total wall clock | ~7 min (Together) / ~17 hr (MLX) | ~6 hr | +| Total cost | ~$3 (Together) / free (MLX) | ~$11 | +| Final val loss (best run) | 1.14 (MLX v1) / 2.08 (Together v3) | TBD — pipeline running now | +| Output runs locally on 48 GB Mac | ✓ | ✓ | + +--- + +## What the previous approach did + +A single SFT pass on `training_data_together.jsonl`: 4,622 ChatML-format Q/A +pairs derived from the Jerboa cookbook, docs, API signatures, divergence +entries, tests, and source. The model saw "user asks about X → assistant +answers correctly" and gradient-stepped its weights toward producing the +target answer. + +Three places this ran: + +1. **Together AI** — fastest and cheapest, but the hosted whitelist for + Qwen3-Coder-30B-A3B-Instruct is **attention-only** (`q/k/v/o_proj`). + Everything else — gate_proj, up_proj, down_proj, MoE experts, routers — + returns `400 cannot find X in LoRA-trainable modules`. Final val loss + plateaued at **2.08** and the model still hallucinated Gerbil forms. + +2. **MLX on Apple Silicon** — local, free, attention + MLP layers reachable. + The 1500-iter v1 run reached val loss **1.14** and produced the best + qualitative output to date. 4-bit base, ~17 hours wall clock. + +3. **Axolotl on RunPod (planned)** — would have reached MoE experts for the + first time, but only as a single SFT stage. Never run. + +### Why single-stage SFT alone isn't enough + +There are three signals about Jerboa that an SFT-only run misses: + +1. **Token distribution.** SFT trains on Q/A pairs. The model never sees a + page of plain Jerboa source. It learns "what to say *about* Jerboa" but + not "how Jerboa code looks when written naturally." Real Jerboa source + has structural patterns — which forms cluster, which imports go with + which idioms, how comments relate to code — that SFT cannot teach + because the data doesn't contain them. + +2. **The 119 divergence entries are wasted as Q/A.** Each entry is a + wrong→right pair (`hash-has-key?` → `hash-key?`, `(srfi :NN)` → + `(srfi NN)`, etc.). The previous pipeline expanded these into Q/A + examples teaching the right form. SFT then nudges the model toward the + right form — once, with the same weight as any other Q/A pair. It + never tells the model that the wrong form is *wrong*. So the wrong + form's prior (learned from the base model's massive Racket/Gerbil + training data) survives essentially intact. + +3. **Catastrophic forgetting risk.** Three epochs over 4,622 narrow Q/A + examples on a 30B base is enough to start blunting general coding + ability. With nothing balancing it (no general code, no raw Jerboa + source, no preference signal), the model can over-fit to the answer + templates and lose flexibility. + +--- + +## What the new pipeline does + +Three stages, each addressing one of the gaps above. The output of each +stage is the base model for the next; LoRA adapters are merged between +stages so the next stage trains on the absorbed weights, not on stacked +adapters. + +### Stage 1 — Continued Pre-Training (CPT) + +**Goal:** teach the model that Jerboa source code exists. + +- **Data:** `cpt_corpus.jsonl` — 499 entries built by `build_cpt_corpus.py`, + which walks `~/mine/jerboa` for `.ss`, `.scm`, and `.md` files. Each + entry is one file with a header comment (`;; FILE: path/to/file.ss`) + preserved so the model learns that imports cluster with file structure. +- **Format:** axolotl `type: completion`. No chat template. The loss is + next-token over the raw text. +- **Hyperparams:** lr `5e-6`, 1 epoch, LoRA r=16/α=32. Low LR because we + are only nudging the distribution; we don't want to overwrite the base + model's general coding ability. +- **Targets:** attention + MLP + MoE experts (`experts.gate_up_proj`, + `experts.down_proj`). All the layers where Jerboa's vocabulary needs to + land. +- **Result:** the LoRA is merged into the base on the pod, producing a + bf16 model directory at `/workspace/cpt_merged`. This is the new base + for Stage 2. + +### Stage 2 — Supervised Fine-Tuning (SFT) + +**Goal:** teach the model to answer Jerboa questions in chat format. + +- **Data:** `training_data_together.jsonl` — the same 4,622 Q/A pairs the + old pipeline used. Reusing the existing dataset; it's good. +- **Format:** axolotl `type: chat_template`, tokenizer-default messages. +- **Hyperparams:** lr `1e-4`, 2 epochs (down from 3 in the old config — + CPT already did some of the heavy lifting, and fewer epochs reduces + forgetting risk). +- **Base model:** `/workspace/cpt_merged` (substituted into the YAML on + the pod via `sed` once Stage 1 finishes; placeholder is + `__PIPELINE_BASE__`). +- **Targets:** same as Stage 1 (attention + MLP + MoE experts). +- **Result:** merged into bf16 at `/workspace/sft_merged`. Stage 1's + merged dir is deleted at this point to free disk. + +### Stage 3 — Direct Preference Optimization (DPO) + +**Goal:** suppress Gerbil/Racket/Clojure/SRFI hallucinations. + +- **Data:** `dpo_pairs.jsonl` — 119 preference triples built by + `build_dpo_pairs.py` from `~/mine/jerboa-mcp/divergence.json`. Each + triple is `{system, instruction, chosen_response, rejected_response}` + where `chosen` is the Jerboa-correct example and `rejected` is the + Gerbil/Racket/etc. form. +- **Format:** axolotl `type: chatml.argilla` with `rl: dpo`. +- **Hyperparams:** lr `5e-7` (10× lower than SFT — DPO is sensitive), + 1 epoch, LoRA r=16/α=32, micro-batch 1, gradient accumulation 4. +- **Base model:** `/workspace/sft_merged` (same substitution as Stage 2). +- **Why DPO instead of more SFT:** DPO directly optimises + `log P(chosen) − log P(rejected)`. It actively pushes the model away + from the wrong form. SFT only knows how to pull the model toward the + right form. The 119 divergence pairs are exactly the format DPO wants; + the old pipeline was leaving this signal on the floor. +- **Result:** merged into bf16 at `/workspace/dpo_merged`. This is the + final model. Stage 2's merged dir is deleted. + +--- + +## Conversion to MLX (final step, runs locally) + +After `runpod_train.py pull` brings `dpo_merged` down to +`./runpod-pipeline-final/`, `convert_to_mlx.sh` runs locally: + +```bash +./convert_to_mlx.sh runpod-pipeline-final jerboa-mlx-4bit +``` + +This calls `python -m mlx_lm.convert -q --q-bits 4`, producing a 4-bit +MLX bundle (~17 GB) that fits comfortably in 48 GB unified memory with +room for KV cache and long context. Runs via `mlx_lm.server` for the +OpenAI-compatible API or `mlx_lm.generate` for one-shot prompts. + +**Decoupling training precision from deployment quantisation matters.** +Training at bf16 preserves gradient dynamics; quantising to 4-bit only +at inference time means the LoRA was learned without 4-bit rounding +noise in the loss. The previous MLX-direct path trained on a 4-bit +base, which is faster but introduces quantisation noise into the +gradient signal. + +--- + +## Why this beats every option we tried before + +**Together (attention-only):** can't reach the layers where Jerboa names +need to live. Plateaued at val loss 2.08. Cheap and fast, but the +ceiling is too low. + +**MLX direct (attention + MLP, 4-bit base):** good enough to be the +"best so far" — but skips MoE experts entirely (4-bit MoE on MLX is +gnarly), trains on a quantised base (gradient noise), and runs only +SFT (no CPT, no DPO). + +**Axolotl single-stage LoRA (planned, never run):** would have reached +MoE experts at bf16, but still skips CPT and DPO. + +**Axolotl expert_ft (full FT of experts):** nuclear option, ~$45, +2× A100, only justified if cheaper paths fail. + +The new pipeline reaches MoE experts at bf16 (the v4 LoRA goal), +*and* adds the two missing stages (CPT before, DPO after) on the +same hardware in one pod lifecycle. It is the only path that uses +all three signals — raw source distribution, Q/A pairs, and +preference data — instead of just one. + +--- + +## Operational notes + +- **Idempotent.** Each stage writes a `.done` marker file with `OK` or + `FAIL <reason>`. Re-running `runpod_train.py train` skips stages whose + `OK` marker exists. If a stage fails mid-run, the orchestrator dumps + the last 80 lines of that stage's log and exits non-zero. +- **Resilient to SSH drops.** Each stage runs inside its own tmux session + (`stage_cpt`, `stage_sft`, `stage_dpo`) on the pod. The orchestrator + polls every 60 s; killing the orchestrator does not kill the training. +- **Disk-aware.** 200 GB container disk is enough for the 30B base plus + one previous merged checkpoint plus the new merged checkpoint, because + the previous merged dir is deleted as soon as the next stage's merge + succeeds. +- **One pod, three stages.** No tear-down between stages. The base model + weights are downloaded once. +- **Cost ~$11.** A100 SXM4 80GB at ~$2.10/hr × ~5–6 hr. new file mode 100644 --- /dev/null +++ b/api-signatures.json @@ -0,0 +1,67104 @@ +{ + "version": "1.1", + "generated": "2026-05-07", + "source_root": "/Users/user/mine/jerboa", + "stats": { + "modules": 632, + "symbols": 12543, + "total_exports": 19099, + "parse_errors": 0, + "tiers": { + "core": 18, + "compat": 47, + "unstable": 76, + "stable": 491 + } + }, + "tier_definitions": { + "core": "Language core (jerboa prelude, reader, core macros). Never breaks.", + "stable": "Curated stdlib (std io, std text, std net, ...). SemVer.", + "compat": "Compatibility shims for other Schemes (Gambit, Clojure, SRFI). Stable but import-gated.", + "unstable": "Experimental or vendor-specific (wasm, dev, lsp, thunderchez). May churn." + }, + "modules": { + "(jerboa build musl)": { + "file": "lib/jerboa/build/musl.sls", + "exports": [ + "build-musl-binary", + "make-musl-cross-target", + "musl-available?", + "musl-boot-files", + "musl-chez-lib-dir", + "musl-chez-prefix", + "musl-chez-prefix-set!", + "musl-cross-available?", + "musl-crt-objects", + "musl-gcc-path", + "musl-libkernel-path", + "musl-link-command", + "musl-sysroot", + "validate-musl-setup" + ], + "tier": "core" + }, + "(jerboa build)": { + "file": "lib/jerboa/build.sls", + "exports": [ + "build-binary", + "build-boot-file", + "build-project", + "build-release", + "build-static-binary", + "compile-for-target", + "compile-modules-parallel", + "compute-file-hash", + "cross-target-ar", + "cross-target-arch", + "cross-target-cc", + "cross-target-os", + "cross-target?", + "file->c-array", + "generate-main-c", + "link-static-archives", + "make-cross-target", + "module-changed?", + "musl-link-flags", + "static-link-flags", + "target-linux-aarch64", + "target-linux-x64", + "target-macos-aarch64", + "target-macos-x64", + "trace-imports", + "tree-shake-imports", + "wpo-compile" + ], + "tier": "core" + }, + "(jerboa cache)": { + "file": "lib/jerboa/cache.sls", + "exports": [ + "cache-clear!", + "cache-directory", + "cache-key", + "cache-lookup", + "cache-stats", + "cache-store!", + "with-compilation-cache" + ], + "tier": "core" + }, + "(jerboa cloj)": { + "file": "lib/jerboa/cloj.sls", + "exports": [ + "activate-cloj-reader!", + "fn-literal", + "reader-cloj-mode" + ], + "tier": "core" + }, + "(jerboa clojure)": { + "file": "lib/jerboa/clojure.sls", + "exports": [ + "*method-tables*", + "*struct-types*", + "->", + "->>", + "->>?", + "->?", + "1+", + "1-", + ":", + "<...>", + "<>", + "==", + "=?", + "ContractViolation", + "Datafiable", + "Error", + "Navigable", + "absento", + "acons", + "activate-cloj-reader!", + "add-watch!", + "aget", + "agetq", + "agetv", + "aif", + "alist", + "alist->hash-table", + "alist->plist*", + "alist?", + "alists->csv", + "and-then", + "any", + "append-map", + "append1", + "appendo", + "apply-dynamic-bindings", + "arem", + "arem!", + "aremq", + "aremq!", + "aremv", + "aremv!", + "as->", + "aset", + "aset!", + "asetq", + "asetq!", + "asetv", + "asetv!", + "assert!", + "assoc", + "assoc!", + "assoc-in", + "assoc-in!", + "atom", + "atom?", + "awhen", + "begin-ffi", + "bind-method!", + "binding", + "bound-fn", + "butlast", + "c-declare", + "c-lambda", + "call-method", + "call-with-list-builder", + "capture", + "capture-dynamic-bindings", + "caro", + "catch", + "cdro", + "chain", + "chain-and", + "clj-delay", + "clj-force", + "clj-future", + "clj-promise", + "comp", + "compare-and-set!", + "complement", + "compose", + "compose1", + "cond->", + "cond->>", + "conda", + "conde", + "condu", + "conj", + "conj!", + "conjoin", + "cons*", + "conso", + "constantly", + "contains?", + "count", + "csv->alists", + "csv-port->rows", + "curry", + "curryn", + "cut", + "cute", + "cycle", + "datafy", + "date->string", + "datetime->alist", + "datetime->epoch", + "datetime->iso8601", + "datetime->julian", + "datetime->string", + "datetime-add", + "datetime-clamp", + "datetime-day", + "datetime-diff", + "datetime-floor-day", + "datetime-floor-hour", + "datetime-floor-month", + "datetime-hour", + "datetime-max", + "datetime-min", + "datetime-minute", + "datetime-month", + "datetime-nanosecond", + "datetime-now", + "datetime-offset", + "datetime-second", + "datetime-subtract", + "datetime-truncate", + "datetime-utc-now", + "datetime-year", + "datetime<=?", + "datetime<?", + "datetime=?", + "datetime>=?", + "datetime>?", + "datetime?", + "day-of-week", + "day-of-year", + "days-in-month", + "dec", + "def", + "def*", + "def-dynamic", + "defclass", + "define-active-pattern", + "define-c-lambda", + "define-enum", + "define-match-type", + "define-rx", + "define-sealed-hierarchy", + "define-values", + "defmethod", + "defn", + "defrecord", + "defrule", + "defrules", + "defstruct", + "delay?", + "delete-duplicates/hash", + "deliver", + "deref", + "dfn", + "difference", + "directory-exists?", + "disj", + "disjoin", + "displayln", + "dissoc", + "dissoc!", + "distinct", + "dlet", + "doall", + "dorun", + "dotimes", + "doto", + "drop", + "drop-last", + "drop-until", + "drop-while", + "duplicates", + "duration", + "duration-nanoseconds", + "duration-seconds", + "duration?", + "empty?", + "epoch->datetime", + "eprintf", + "eql?", + "err", + "err->list", + "err?", + "error-irritants", + "error-message", + "error-trace", + "every", + "every-consecutive?", + "every-pred", + "ex-cause", + "ex-data", + "ex-info", + "ex-info?", + "ex-message", + "fail", + "false?", + "filter-err", + "filter-map", + "filter-ok", + "finally", + "first", + "first-and-only", + "flatten", + "flatten-result", + "flatten1", + "flip", + "fn-literal", + "fnil", + "for", + "for-each!", + "for/and", + "for/collect", + "for/fold", + "for/or", + "force-output", + "format", + "fprintf", + "frequencies", + "fresh", + "future-cancel", + "future-cancelled?", + "future-done?", + "future?", + "get", + "get-in", + "group-by", + "group-consecutive", + "group-n-consecutive", + "group-same", + "hash", + "hash->list", + "hash->plist", + "hash-clear!", + "hash-copy", + "hash-eq-literal", + "hash-find", + "hash-fold", + "hash-for-each", + "hash-get", + "hash-has-key?", + "hash-key?", + "hash-keys", + "hash-length", + "hash-literal", + "hash-map", + "hash-merge", + "hash-merge!", + "hash-put!", + "hash-ref", + "hash-remove!", + "hash-set", + "hash-table-set!", + "hash-table?", + "hash-update!", + "hash-values", + "identity", + "if-let", + "imap", + "imap-has?", + "imap-hash", + "imap-ref", + "imap-set", + "imap=?", + "imap?", + "in-bytes", + "in-chars", + "in-hash-keys", + "in-hash-pairs", + "in-hash-values", + "in-imap", + "in-imap-keys", + "in-imap-pairs", + "in-imap-values", + "in-indexed", + "in-lines", + "in-list", + "in-naturals", + "in-port", + "in-producer", + "in-pset", + "in-range", + "in-string", + "in-vector", + "inc", + "interleave", + "interpose", + "intersection", + "into", + "iota", + "iterate", + "iterate-n", + "ivec", + "ivec-length", + "ivec-ref", + "ivec-set", + "json-object->string", + "julian->datetime", + "juxt", + "keep", + "keys", + "keyword->string", + "keyword?", + "last", + "last-pair", + "lazy->list", + "lazy-all?", + "lazy-any?", + "lazy-append", + "lazy-chunk", + "lazy-concat", + "lazy-cons", + "lazy-count", + "lazy-cycle", + "lazy-drop", + "lazy-drop-while", + "lazy-filter", + "lazy-first", + "lazy-flatten", + "lazy-fold", + "lazy-for-each", + "lazy-force", + "lazy-interleave", + "lazy-interpose", + "lazy-iterate", + "lazy-map", + "lazy-mapcat", + "lazy-nil", + "lazy-nil?", + "lazy-nth", + "lazy-partition", + "lazy-range", + "lazy-realize", + "lazy-realized?", + "lazy-repeat", + "lazy-rest", + "lazy-seq?", + "lazy-take", + "lazy-take-while", + "lazy-zip", + "leap-year?", + "length<=?", + "length<=n?", + "length<?", + "length<n?", + "length=?", + "length=n?", + "length>=?", + "length>=n?", + "length>?", + "length>n?", + "let-alist", + "let-hash", + "list*", + "list->hash-table", + "list->lazy", + "list->pqueue", + "list-of?", + "loop", + "lvar", + "lvar?", + "make-date", + "make-datetime", + "make-duration", + "make-hash-set", + "make-hash-table", + "make-hash-table-eq", + "make-keyword", + "make-shared", + "make-time", + "map-err", + "map-invert", + "map-ok", + "map-results", + "map/car", + "mapcat", + "match", + "match/strict", + "max-key", + "maybe", + "membero", + "memo-proc", + "memoize", + "merge", + "merge-with", + "meta", + "meta-wrapped?", + "min-key", + "nav", + "negate", + "nested-empty-like", + "nested-get", + "next", + "nil?", + "nullo", + "ok", + "ok->list", + "ok?", + "or-else", + "pairo", + "parse-date", + "parse-datetime", + "parse-time", + "partial", + "partition", + "partition-all", + "partition-by", + "path-absolute?", + "path-directory", + "path-expand", + "path-extension", + "path-join", + "path-normalize", + "path-strip-directory", + "path-strip-extension", + "peek", + "persistent!", + "persistent-map?", + "persistent-queue", + "persistent-set", + "persistent-set->list", + "persistent-set-contains?", + "persistent-set-hash", + "persistent-set?", + "pget", + "pgetq", + "pgetv", + "plist->alist*", + "plist->hash-table", + "pop", + "pop!", + "pp", + "pp-to-string", + "ppd", + "ppd-to-string", + "pprint", + "pqueue->list", + "pqueue-conj", + "pqueue-count", + "pqueue-empty", + "pqueue-empty?", + "pqueue-peek", + "pqueue-pop", + "pqueue?", + "pr", + "pr-str", + "prem", + "prem!", + "premq", + "premq!", + "premv", + "premv!", + "printf", + "println", + "prn", + "prn-str", + "promise?", + "pset", + "pset!", + "psetq", + "psetq!", + "psetv", + "psetv!", + "push!", + "r-drop",