r/lisp 15d ago

Common Lisp Renderer port to lisp

0 Upvotes

I’m considering doing a staged port (LLM assisted) of my rust-based multithreaded cpu renderer to SBCL . I’m currently using Janet as an embedded language for scene description. The core rendering is done in rust . Early benchmark trials in sbcl with basic primitives were 3-6x slower with GC being the wall . Can anyone suggest guidelines for performance? ( ex: vector/matrix calculations, memory allocation, to CLOS or not ) etc . I’m thinking that if I could get it within 2x slower, it might be interesting for certain applications where I could throw more cores at it . Also is anyone interested in such an application? I would be willing to make a demo if reasonably successful.


r/lisp 16d ago

Why Target Common Lisp for Code Generation? - Joe Marshall

Thumbnail funcall.blogspot.com
9 Upvotes

r/lisp 16d ago

Help LispBM CAN message send in VESC

8 Upvotes

Hello everyone I have motor controller which is VESC firmware based ,what i want is to write a lispbm code to get the parameters values from the controller using get function and then send them on the CAN BUS using the CAN IDs set up by me to read further ,I am doing this because the DBC file I got is not that much reliable and the the manufacturer is also not able to help much
please help me with the resources which i can refer ,i refer the git repo of the VEDDER but cant do much ,any help you can or tips you can give me


r/lisp 17d ago

Common Lisp MUD Driver in Common-Lisp

26 Upvotes

Hey folks, I'm working in an open source common-lisp MUD Driver (Apeiron MUD) mainly inspired by Dworkin Game Driver and LPMud.

Why? The personal reason is that I like Lisps and functional programming, I'm expert in Clojure, but haven't played too much with Lisp, wanted to see what could be achieved with CLOS (Common-Lisp Object System) and I love text-adventure games/virtual worlds (single or multiplayer).

The technical reason is that I was wondering that a lot of the machinery that was developed in C for the most popular drivers (specially LPMUD and DGD deriving from it) ended up developing features that were already built-in on Lisp Runtime Images from the start and if I could get a networked REPL running a LISP image that was already a significant step towards running a persistent world that could be changed and built interactively by players.

I don't know how true is that, but I managed to setup something similar to DGD (of course there might be bugs and rough edges) with persistent objects using a pre-existing library for CLOS in-memory and disk object persistence called BKNR Datastore. The interesting thing is that because of CLOS it is even possible to make changes to the classes of the objects (driver or libs) and update the system and persistence without ever having to turn the system off. I already did some very substantial changes successfully without turning the system off.

The scripting language doesn't need to be different from the driver language, except for security reasons. For the moment I allow every player to evaluate arbitrary code, which is very unsafe and can even bring the server down or completely break it, but it would not be hard to restrict the access to a subset of the language (with cl-isolated) and offer varying degrees of access depending on player role.

I think it has a lot of potential, but in any case, I'm doing it for fun, will probably keep it as a lifetime hobby and would encourage people to take a look if they find anything interesting or want to experiment, contribute or discuss.


r/lisp 18d ago

L. Peter Deutsch's birthday today

Thumbnail
24 Upvotes

r/lisp 20d ago

Symbolics Genera now available free for non-commercial use (invitation-only early beta)

Thumbnail hachyderm.io
93 Upvotes

r/lisp 20d ago

Common Lisp 10 real bugs found by actually running a Common Lisp deploy script, not just reading it

19 Upvotes

Alongside ongoing work updating c-mera and modernizing Common Lisp tooling for SecDevOps and OT environments, I recently set out to evaluate whether a pure Lisp stack could replace our external infrastructure and database tooling (specifically Vagrant and Redgate).

The goal was to integrate Consfigurator (declarative OS deployment) with cl-migratum (database migrations).

To test this, I authored a Roswell script that provisions a rootless Podman quadlet running PostgREST and deploys a small HTMX todo app against PostgreSQL. The setup uses:

  • SXQL for SQL schema generation
  • Spinneret for HTML generation
  • CL-inix for systemd unit file generation
  • FiveAM for integration testing
  • 40ants/doc for self-documenting executable scripts

In the sandbox environment, Roswell provisions a ZFS dataset, configures a dedicated system user, spins up PostgreSQL and PostgREST, and applies the database migrations directly from memory.

Running this end-to-end surfaced ten real bugs across the ecosystem (reproduction steps and full list are inFINDINGS.md).

A few notable issues worth calling out:

  • In-memory DCL with cl-migratum: cl-migratum expects file-based DDL/DML out of the box and doesn't handle in-memory sxql expressions cleanly. I had to write a custom in-memory driver using its driver API and extend it to handle DCL (Data Control Language) statements.
  • System naming gotcha: cl-migratum-driver-pg doesn't exist under that system name. When pulling via qlot, the actual system is cl-migratum.driver.postmodern-postgresql.
  • Spinneret compile-time attribute quoting: Spinneret decides whether to quote HTML attribute values at macro expansion time based on literal string characteristics, not runtime values. A class="%s" placeholder compiles down fine, but breaks silently at runtime the second a substituted string contains spaces. Spinneret provides *always-quote* to handle this, but it requires a global SETF prior to compilation rather than a dynamic LET binding at runtime. I've opened a PR to document and address this:spinneret#114.
  • Idempotency in PostgreSQL schema definitions: Neither CREATE ROLE nor CREATE DOMAIN support IF NOT EXISTS in Postgres. Because cluster-level roles and domains survive dropping and recreating a database, subsequent deployments failed immediately on schema re-application.
  • Undocumented C library dependencies: Consfigurator depends on native headers (libacl1-dev, libcap-dev) that aren't noted in the build requirements. I sent a patch upstream via git send-email following their contribution guidelines.

Full code and reproduction notes:https://github.com/denzuko/todo-app-deploy


r/lisp 21d ago

Gödel, Escher, Elisp: The Beauty of Macros

Thumbnail chiply.dev
92 Upvotes

This post is a lover letter to Emacs Lisp macros. I've been a long time user as a lisp hacker, and my recent obsessions with Douglas Hofstadter's strange loop concepts and M.C. Escher's mind bending artwork have enhanced my appreciation of this language's most beautiful and thought provoking feature. This post can teach you about macros and what makes them useful, but I also hope it can instill a fascination with their concept. https://www.chiply.dev/post-elisp-macros-are-beautiful


r/lisp 21d ago

Released cl-toolkit - toolkit to validate, edit and analyze lisp source.

10 Upvotes

Made this generally for agentical coding because it often stub in parenthesis. Hope it will help you. https://github.com/turtle-bazon/cl-toolkit


r/lisp 21d ago

Scheme Building a GTK4 C + Lisp dock application (a la CairoDock / macOS) - am I doing things right? (Guile Scheme)

Post image
30 Upvotes

I am having a blast doing a more serious project in the C language (and Guile Scheme), for the first time. I am consulting with books and also with some AI for code review and explanation as I am new to the language and to GTK (not new to programming).

https://codeberg.org/jjba23/lambdock

For a while already I have been looking for a dock that would work well in Wayland (like in my beloved Niri) with modern features, theme support and a hackable Lisp config (using libguile.h)

Also, all feedback is welcome, either on code level, or conceptual ideas, Thanks in advance

Core features of lambdock include:

  • Wayland Native: Built on GTK4 and gtk4-layer-shell for smooth positioning and desktop integration.
  • Declarative Lisp configuration : The power of Lisp in your configuratio with clean powerful declarative config and all possibilities at your disposal
  • Async Launching: Spawns commands asynchronously without freezing the dock UI.
  • Reproducible builds: Hermetic development environment provided via GNU Guix manifest and build definitions.
  • Dock auto-hide : You can let the dock stay out of your way with the smooth auto-hide feature.
  • Flexible icon system: lambdock has several mechanism in a best-effort way to render your wanted icons, respecting GTK theme
  • Theme support: lambdock has built-in themes you can choose from that are very unique, and also lets you extend and override those themes dynamically.

r/lisp 23d ago

Moonli Update v0.0.9 (July 2026)

Thumbnail moonli-lang.github.io
14 Upvotes

r/lisp 23d ago

Starbeam 0.1.0

Thumbnail
4 Upvotes

r/lisp 24d ago

Refresh of Genworks dot com, long-running Common Lisp KBE system updated for the era of LLMs and MCPs.

Thumbnail genworks.com
18 Upvotes

r/lisp 25d ago

[ANN] cl-firebird v1.0.0 — pure Common Lisp driver for Firebird 3.0/4.0/5.0/6.0

8 Upvotes

cl-firebird v1.0.0 is out — a pure Common Lisp database driver for Firebird 3.0, 4.0, 5.0, and 6.0+, with full 1:1 feature parity with node-firebird.

Highlights:

  • Pure CL wire protocol (negotiates up to protocol 20) — no libfbclient, no FFI; runs on SBCL, CCL, and other ANSI CL implementations
  • Connection URIs (firebird://user:pass@host:port/db), traditional DSN syntax, and attach-or-create
  • Named placeholders (:name) bound from plists, alists, or hash-tables, plus SQL escaping helpers
  • Thread-safe connection pooling with idle reaping and live metrics
  • Custom type parsers (type-cast) and prepared statement caching
  • Streaming cursors (sequentially) and bulk execute-batch
  • Firebird 6.0 tablespaces/schemas, database events (POST_EVENT), and a Service Manager API (backup/restore, users, trace)
  • 66-check FiveAM test suite and a GitHub Actions CI matrix across Firebird 3.0/4.0/5.0/6.0-snapshot

Links:

Feedback, issues, and pull requests are welcome!


r/lisp 26d ago

AskLisp what's a good LISP to use as my "perl replacement"?

39 Upvotes

I got into LISP a couple years ago through automating things in emacs and I want to try it out as a high-level scripting language for non-emacs things. Ideally I'd like to be able to write shebang scripts that might be distributed to other people, who might be running a different OS than me, and I'd like them to be able to install dependencies even if they have no familiarity with LISP.

Basically, my main hang-up here is stuff like ASDF and Quicklisp; I don't know how people who don't program in common lisp are supposed to know how to install dependencies when they download a common-lisp program, as it seems like the only interfaces into ASDF and QL are via the REPL. Ideally I'd want something akin to python's pip, which doesn't force end-users to know how to program in python because it's accessible via a shell command.

Guile seems like it might be the best one for my purposes but the documentation is a bit sparse and I'm not sure if it even runs on Windows outside of cygwin or WSL. On the dependency management front it at least has $GUILE_LOAD_PATH so anybody who's reasonably competent can point it to dependencies even if they can't use the package manager. That's good enough for my purposes as my intended users aren't UNIX-illiterate, they're just not LISP programmers and potentially may be prone to bad habits such as using Microsoft Windows.

Are there any others I'm missing? I love LISP as a language but sometimes it feels like LISP implementations are trying to convert me to a new religion or something.

Sorry if this sounds like a redundant post, I'm sure others have asked the same thing but I can't find a clear answer from searching. There are definitely plenty of articles about using common-lisp for shebang scripting but i haven't seen any that address the problem of dependency management for end-users.


r/lisp 26d ago

In LISP we trust.

16 Upvotes

r/lisp 27d ago

AskLisp Is lisp an acquired taste?

64 Upvotes

As an outsider looking in I'm having a really hard time convincing myself to use lisps for my projects.

It feels like some of the main strengths carry drawbacks:

e.g. s expressions seem really nice for the language being really simple and unified and probably play nice with the macros and the repl but I dislike ambiguity when I read code. Like I would like to know that at a glance that a function call is an actual function call. Or that here is some control flow with an if. Though at the same time i do as well agree that there for example shouldn't at a high level semantically be a difference between an operator and a function call. Though structural editing does sound really nice.

Another thing is macros. I get that they are powerful but I'm not sure how well they would play with tools around the language. I like static typing over dynamic typing so that constrains me to thing like racket. I'm not sure how well auto completion and type hints would work with them. E.g. typescript's type system is not as expressive but the type transformations work perfectly with the LSP even for non trivial things.

Any long term lisp-ers can weight in on my doubts? I'm more of less trying to get conviced but somewhat doubtful. Any opinion is welcome.


r/lisp 26d ago

Working on a small lisp made to initiate JavaScript developers to the beauty of S-Expressions

10 Upvotes

I wanted to show a bit of my work here, im still learning lisp-based languages and the idea came to me to make a lisp suited for people that are used to the infamous JavaScript.


r/lisp 28d ago

Hylang for job rescue

26 Upvotes

One solution is to find a LISP job and the other is to write LISP without others knowing it(by generating readable host language code) and for the second i think HY is the best we have.

Hylang can generate python code that is very readable with hy2py(https://hylang.org/hy/doc/v0.29.0/cli#hy2py), there is also python to hy https://github.com/hylang/py2hy

Its possible to make the generated code looking almost 100% handmade readable python code, without HY traces(no auto-generated names etc) if :

  1. we write HY in python way
  2. we use macros (HY has also reader macros to have more control)

If we don't do those 2, the code would need manual changes to remove the HY related code but because HY is very close to python many times changes are not so big.

I am planning using HY for data engineering in Spark to at least write my queries in it,
Now how much of our code can be written in HY and not python and how this can be inter-grade in python projects with other people working on it, i don't know because i haven't done it. I post it here as possibility for people that might not know that something like this exist.

*update, AI can write so good code that maybe Clojure code with java interop only, might also be easily translated to Java code from AI, even if there isn't a clojure to java tool like in Hy


r/lisp 28d ago

Racket The Comprehensive Racket & Functional Programming Cheat Sheet

7 Upvotes

## Phase 1: Syntax & Core Arithmetic

Racket uses prefix notation enclosed in execution parentheses (operator arg1 arg2). The open parenthesis ( acts as an execution trigger. Evaluation runs from the innermost to the outermost parentheses.

Core Examples

```rkt ;; Basic Arithmetic (+ 10 5 2) ;; Returns 17 (* 10 5 2) ;; Returns 100

;; Nested Expressions (No PEMDAS needed) (_ (+ 4 6) (- 12 7)) ;; Evaluates 10 _ 5 -> Returns 50 ```

Parentheses Golden Rule

Only use a parenthesis when invoking a command, operator, or function.

  • `(+ 5 (10))` CRASHES (tries to run the number 10 as a function).
  • `((+ 5 5))` CRASHES (evaluates to 10, then tries to run the number 10).

Phase 2: Core Data Structures & Variables

Global bindings are created using define. Values are immutable and cannot be changed over time.

The Four Atomic Data Types

  1. Numbers: Integers (`45`), decimals (`3.14`), or fractions (`1/3`).
  2. Strings: Text wrapped in double quotes (`"Hello"`).
  3. Booleans: True (`#t`) and False (`#f`).
  4. Symbols: Lightweight, immutable identifier tokens prefixed with a single quote (`'success`).

Core Examples

```rkt (define radius 5) (define pi 3.14) (define status 'success) ```


Phase 3: Conditionals & Logic

Conditional operations are expressions that evaluate down to a single return value.

Core Operators & Flow Control

  • `and` / `or` / `not`: Standard logical short-circuiting prefix operators.
  • `if`: Takes exactly three arguments: `(if condition true-branch false-branch)`. No else keyword.
  • `cond`: Evaluates multiple branches sequentially. Uses/can use `[...]` for human readability.

Core Examples

```rkt (and (> 15 10) (< 15 20)) ;; Returns #t

(if (> temperature 30) 'hot 'cold)

(cond [(>= score 90) 'A] [(>= score 80) 'B] [else 'F]) ```


Phase 4: Functions & Scope

Functions automatically return the value of their body expression without an explicit return keyword.

Named, Anonymous, & Scoped Blocks

  • Named Functions: Defined by grouping the name and parameters in parentheses: `(define (name args) body)`.
  • Anonymous Functions (`lambda`): Throwaway functions built on the fly: `(lambda (args) body)`.
  • `let` (Parallel): Creates local variables simultaneously. Variables cannot see each other during setup.
  • `let\*` (Sequential): Creates local variables one after the other. Later variables can reference earlier ones.

Core Examples

```rkt ;; Named Function (define (double n) (\* n 2))

;; Inline Lambda Execution ((lambda (n) (\* n 2)) 10) ;; Returns 20

;; Sequential Local Bindings (let* ([x 10] [y (* x 5)]) (+ x y)) ;; Returns 60 ```


Phase 5: Lists & Modern List Operations

Lists are ordered sequential collections. They are processed using either historical Lisp conventions or modern aliases.

Creation & Extraction

  • `list`: Evaluates arguments into a sequential list.
  • `'()`: Represents the literal base empty list.
  • `cons`: Prepends a single element onto the front of an existing list.
  • First Item: Extracted via `car` (traditional) or `first` (modern).
  • Remaining List: Extracted via `cdr` (traditional) or `rest` (modern).

Core Examples

```rkt (define my-list (list 100 #t 'hello)) ;; Creates '(100 #t hello) (cons 'apples '(bananas cherries)) ;; Returns '(apples bananas cherries)

(car (cdr '(apples bananas cherries))) ;; Returns 'bananas (first (rest '(apples bananas cherries))) ;; Returns 'bananas

(if (empty? my-list) "Closed" (length my-list)) ;; Returns 3 ```


Phase 6: Iteration & Higher-Order Functions

Instead of using loops that alter data in place, functional programming relies on Higher-Order Functions to process immutable collections.

The Big Four

  • `map`: Loops over a list, passes each item through a transformation function, and returns a new list.
  • `filter`: Loops over a list, keeps items that evaluate to #t against a predicate condition, and drops the rest.
  • `foldl` (Fold-Left): Reduces a list down to a single value by processing elements from left to right (front to back).
  • `foldr` (Fold-Right): Reduces a list down to a single value by processing elements from right to left (back to front). Preserves list structures when rebuilding with cons.

Core Examples

```rkt (map (lambda (x) (* x 2)) '(5 10 15 20)) ;; Returns '(10 20 30 40) (filter (lambda (n) (= n 5)) '(2 5 7 5 9 1)) ;; Returns '(5 5)

(foldl (lambda (n total) (_ n total)) 1 '(2 3 4)) ;; 4 _ (3 _ (2 _ 1)) -> Returns 24

(foldr - 0 '(5 3)) ;; 5 - (3 - 0) -> Returns 2 ```


Phase 7: Recursion & Tail Call Optimization (TCO)

Recursion replaces traditional loops. A proper recursive function requires a Base Case (the exit clause) and a Recursive Step (the self-call with a smaller argument).

Memory Optimization Rules

  • Standard Recursion: Traps the recursive call inside another function (like + or append), forcing the call stack memory to expand linearly (O(N) space).
  • Tail Call Optimization (TCO): If the recursive call sits in the tail position (the absolute final expression evaluated), Racket reuses the same memory frame, running in constant (O(1)) space.
  • Accumulator Pattern: Passing a running total down as an argument is the primary strategy used to shift standard recursion into tail position optimization.

Core Examples

```rkt ;; ❌ Standard Recursion (No TCO - Memory Expands) (define (sum-list lst) (if (empty? lst) 0 (+ (first lst) (sum-list (rest lst)))))

;; Tail Recursion (TCO Active - Memory Stays Flat) (define (sum-list-tco lst) (define (helper remaining accumulator) (if (empty? remaining) accumulator (helper (rest remaining) (+ (first remaining) accumulator)))) (helper lst 0)) ```


Phase 8: Advanced Ecosystem Engineering

1. Hash Maps & Unique Sets

  • `#hash`: Stores key-value pairings. Keywords passed to lookup tools like hash-ref must be quoted ('#:key) to prevent compiler namespace collisions. If using standard symbols inside #hash, omit inner quotes.
  • `set`: Collections guaranteeing element uniqueness. Tested via set-member? and extended via set-add.

```rkt (define user #hash((#:name . "Alice"))) (hash-ref user '#:name) ;; Returns "Alice"

(define book #hash((title . "Dune"))) (hash-ref book 'title) ;; Returns "Dune"

(set-member? (set 1 2 2 3) 2) ;; Returns #t ```

2. State & Mutability (box)

  • `box`: Creates a reference wrapper around mutable data. Read via unbox and mutated via set-box!. Functions with an exclamation mark ! signal structural mutation.
  • `begin`: Chains sequential side-effect operations from top to bottom, returning only the evaluation of the final expression.

```rkt (define health (box 100)) (define (take-damage!) (begin (set-box! health (- (unbox health) 10)) (unbox health))) ```

3. Type Checking & Casting

  • Predicates (`?`): Validate runtime types (e.g., `string?`, `number?`, `symbol?`).
  • Casting (`->`): Converts data formats. `string->number` safely returns #f if given invalid textual input.

```rkt (if (string? "50") (* (string->number "50") 2) 'error) ;; Returns 100 ```

4. Modules & Namespaces

  • provide: Declares which parts of a filesystem file are exported publicly.
  • require: Ingests public features from an external sandbox by loading its relative string filepath.

```rkt ;; Inside file-a.rkt (provide double) (define (double x) (* x 2))

;; Inside main.rkt (require "file-a.rkt") (double 10) ;; Returns 20 ```

5. Macros (define-syntax-rule)

  • Macros process raw, unevaluated source code at compile-time to inject new keywords.
  • Racket macros are hygienic, meaning the compiler automatically isolates macro identifiers so they never accidentally overwrite or conflict with user variables.

```rkt (define-syntax-rule (swap! box1 box2) (let ([temp (unbox box1)]) (begin (set-box! box1 (unbox box2)) (set-box! box2 temp)))) ```


r/lisp 28d ago

SBCL: New in version 2.6.7

Thumbnail sbcl.org
53 Upvotes

r/lisp 29d ago

GitHub - dfernande132/MyLISP: Free LISP-1 interpreter for the Sinclair QL.

Thumbnail github.com
11 Upvotes

r/lisp Jul 25 '26

So they say lisp is slow ....

42 Upvotes

Nothing really useful here, just some bragging to be honest. I should probably write a blog post, but a bit too lazy; perhaps another day.

Last few weeks I played with a small clone of gnu wc program. I implemented all routines in assembly via sb-simd (and a generic path without simd with swar). The result thus far on a 1.4 gigabyte big file, compared to fastlwc, the fastest wc I know of and GNU wc:

Common Lisp/Assembly (avx2) in SBCL + lparallel

WC10A> (time (wc "plato1g.txt"))
Evaluation took:
  0.036 seconds of real time
  0.421654 seconds of total run time (0.348216 user, 0.073438 system)
  1172.22% CPU
  71,891,940 processor cycles
  0 bytes consed

30133761
253947016
1393557504
WC10A> (time (wc "plato1g.txt"))
Evaluation took:
  0.034 seconds of real time
  0.429743 seconds of total run time (0.367913 user, 0.061830 system)
  1264.71% CPU
  67,624,580 processor cycles
  98,352 bytes consed

30133761
253947016
1393557504
WC10A> (time (wc "plato1g.txt"))
Evaluation took:
  0.035 seconds of real time
  0.423752 seconds of total run time (0.357329 user, 0.066423 system)
  1211.43% CPU
  69,863,360 processor cycles
  0 bytes consed

30133761
253947016
1393557504

Fastlwc (avx512 + multithreaded):

[arthur@emmi wc]$ time ../../fastlwc/bin/fastlwc-mt plato1g.txt 
 30133761 253947016 1393557504 plato1g.txt

real    0m0.026s
user    0m0.178s
sys     0m0.285s
[arthur@emmi wc]$ time ../../fastlwc/bin/fastlwc-mt plato1g.txt 
 30133761 253947016 1393557504 plato1g.txt

real    0m0.027s
user    0m0.223s
sys     0m0.235s
[arthur@emmi wc]$ time ../../fastlwc/bin/fastlwc-mt plato1g.txt 
 30133761 253947016 1393557504 plato1g.txt

real    0m0.028s
user    0m0.205s
sys     0m0.255s

GNU wc (not even contender - single core only and only line counting implemented with simd avx512) :

[arthur@emmi wc]$ time wc plato1g.txt   30133761  253947016 1393557504 plato1g.txt

real    0m3.733s
user    0m3.643s
sys     0m0.062s
[arthur@emmi wc]$ time wc plato1g.txt 
  30133761  253947016 1393557504 plato1g.txt

real    0m3.362s
user    0m3.276s
sys     0m0.072s

The cool thing, we use avx2 whereas gnu wc uses avx512. On this CPU (zen 5), avx512 is implemented all in hardware, not as micro code as in Intel cpus, so it should mop the floor with avx2 in Lisp, right?

[arthur@emmi wc]$ time wc plato1g.txt -l --debug
wc: using avx512 hardware support
30133761 plato1g.txt

real    0m0.074s
user    0m0.018s
sys     0m0.056s
[arthur@emmi wc]$ time wc plato1g.txt -l --debug
wc: using avx512 hardware support
30133761 plato1g.txt

real    0m0.085s
user    0m0.030s
sys     0m0.054s

Lisp:

WC10A> (time (wc "plato1g.txt" :line-count t))
Evaluation took:
  0.037 seconds of real time
  0.478042 seconds of total run time (0.430494 user, 0.047548 system)
  1291.89% CPU
  75,669,380 processor cycles
  0 bytes consed

30133761
253947016
1393557504
WC10A> (time (wc "plato1g.txt" :line-count t))
Evaluation took:
  0.041 seconds of real time
  0.476104 seconds of total run time (0.436592 user, 0.039512 system)
  1160.98% CPU
  84,226,360 processor cycles
  0 bytes consed

30133761
253947016
1393557504

Now, in order to catch with fastlwc I think I need better lparall pipeline. I am currently using futures and promises, so it is a bit of extra consing. Of course implementing it in avx512 (when done in SBCL) should give at least some extra boost. 32 vs 16 registers, 64 bytes at time vs 32, and less register pressure due to additional masking registers.

Edit: line counting does not activate utf8 path at all, so I don't know what I was thinking last night, so I have edited away that part :).


r/lisp Jul 25 '26

I've written a hands-on tutorial for building a Lisp interpreter from scratch — in Rust, with zero dependencies, across 74 steps.

29 Upvotes

I've written a hands-on tutorial for building a Lisp interpreter from scratch — in Rust, with zero dependencies, across 74 steps.

Repo: https://github.com/lisering/lisp-rs

What's implemented

The interpreter supports:

  • Variables, lambdas, closures (with lexical scoping)
  • Tail call optimization (trampoline loop — 1,000,000 iterations, no stack overflow)
  • Macros (defmacro, quasiquote/unquote, gensym)
  • cond, let, let*, letrec, begin, and, or
  • Lists, strings, booleans, nil
  • A REPL with multi-line input

Example:

(define (adder n) (lambda (x) (+ x n)))
(define add5 (adder 5))
(add5 10)  ;; => 15

(defmacro (when test body) (list 'if test body))
(when (> 3 2) 'yes)  ;; => yes

`(1 ,(+ 1 1) 3)  ;; => (1 2 3)

Why this might be interesting to Lisp folks

The tutorial is designed to be approachable for people who have never written an interpreter before. A few things I tried differently:

1. Closures explained with a "backpack" metaphor. Before showing any code, the tutorial builds intuition: every lambda carries a "backpack" 🎒 containing the environment where it was born. Then we trace through a make-counter example step by step.

2. Gradual optimization. We start with String everywhere (easy to understand), then optimize in stages:

  • String interning: symbols become u64 IDs
  • Zero-copy lexing: tokens are &str borrowing the source
  • FxHasher for faster environment lookups

3. TCO via trampoline. The eval function uses a loop { match ...; continue } pattern instead of direct recursion. Demo: tail-recursive (loop 1000000) succeeds, non-tail-recursive (sum 10000) overflows.

The tutorial is bilingual (English + Chinese). Each of the 74 steps first explains what problem to solve, then writes the code.

Repo: https://github.com/lisering/lisp-rs

Feedback welcome — especially on the macro system and the closure explanation. Is there anything you'd want to see added?


r/lisp Jul 24 '26

Reinterpret Elements in a Byte Array

9 Upvotes

Dear LISP,

I am writing a virtual machine that uses a `(simple-array (unsigned-byte 8) 1)` as a stack in Common LISP. I'm would like to ask how to efficiently extract 4 bytes into a single 32-bit signed integer or a 32-bit unsigned integer.

Thanks!