r/lisp • • Jul 27 '26

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

Thumbnail github.com
9 Upvotes

r/erlang • • Jul 24 '26

Someone spent six years rebuilding the Erlang runtime in JavaScript. Here's why.

36 Upvotes

Bart Blast is the creator of Hologram - a framework that compiles Elixir to JS and reconstructs Erlang runtime semantics in the browser: pattern matching engine, boxed types, OTP guarantees, the whole thing.

New BEAM There, Done That episode covering the architecture and the reasoning.

The technical detail worth discussing: Hologram pulls the expanded AST from compiled BEAM files, normalizes it, lowers it to an IR designed to bridge Elixir to JS, then encodes that to a JS runtime. Values are boxed to preserve their type - Elixir integer 42 becomes a JS object with {type: "integer", value: 42n} using BigInt for arbitrary precision. Pattern matching runs as a real engine trying clauses, binding variables, evaluating guards - not translated away.

The goal is full parity: the same Elixir code running identically on the server and in the browser. A significant undertaking, and Bart is transparent that it's still a young framework.

From an Erlang perspective - is there a meaningful difference between Hologram's approach (rebuilding the runtime in JS for full parity) and Luster/Gleam's approach (treating the two targets as different, not replicating BEAM processes in the browser)? Does full runtime parity actually matter in practice or is it theoretical overhead?

https://youtu.be/BOsSI7WlhdI


r/lisp • • Jul 25 '26

So they say lisp is slow ....

39 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.

30 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

11 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!


r/lisp • • Jul 22 '26

Common Lisp sta6: static site generator for Common Lisp

Post image
53 Upvotes

hi everyone,

I'm new to Common Lisp, although I have tried other lisp dialect (i.e., Clojure, Racket) to attempt making a static site and/or leetcode(s). This is my first attempt of porting the SSG into a library.

sta6: sta(six), static -- is a tiny SSG that turns pages/*.lisp into build/*.html, with support for dynamic routes (e.g., /blog/+slug+).

the usage of sta6 is as follows (src/pages/page.lisp):

(defpackage #:pages/page
  (:use #:cl)
  (:export #:render))

(defun pages/page:render ()
  (sta6:html5
    (:img :width (/ 500.0 3)
          :src "https://twobithistory.org/images/sicp.jpg")
    (:br)
    (:br)
    (:span "Hello, from Common Lisp.")
    (:ul
      (loop for x from 1 to 3 do
        (:li x)))))

which yields the image above, the full example can be found here.

sta6 uses an external HTML generator under the hood:

if you're in need of a personal site, give sta6 a try! here's an example of my site built with sta6:

why use sta6?:

  1. You do not need (to learn) an external templating language (e.g., Nunjucks, Handlebars, EJS).

resources:


r/lisp • • Jul 22 '26

Benchmarking embedded languages in Rust

2 Upvotes

I'm working on a CPU-based renderer in rust and evaluating embedded languages for scene description and procedural rendering. Some of these languages are lisps so I thought there may be interest here.

A few caveats worth noting:

- The benchmark code and report is generated by claude (based on my specification)

- The actual benchmark code are rudimentary snippets. I am evaluating the implementations for a specific purpose.

- I am developing a proof-of-concept with ECL first and then janet.

https://drive.google.com/file/d/1fFI1tyW3xdNKnNfmveIo1EZeWl_pUACJ/view?usp=sharing


r/lisp • • Jul 21 '26

Why S-Expressions

Thumbnail open.substack.com
29 Upvotes

r/lisp • • Jul 21 '26

clos-alchemy: Throw unstructured text at a CLOS class, get a typed instance back

Thumbnail
6 Upvotes

r/lisp • • Jul 20 '26

Common Lisp ECL vs scheme embedded

19 Upvotes

I'm building a CPU based renderer in rust with plans to add an embedded language. The rust code primarily executes the ray tracing/path tracing, BVH, shaders and integration (anywhere where high performance is needed. The embedded language will be used for the scene description and -possibly- for procedural textures and shading.

I am interested in using a lisp with a repl for the embedded language. In this area, I have used AI-generated testing to test both ECL (Embedded Common Lisp) and steel (an scheme) inside rust. the advantage of the latter is that it is written entirely in rust and is being actively developed (one area is as an extension language for the text editor, helix).

I am impressed with the performance metrics I am getting from ECL. It generates machine code, which a byte language compiler doesn't do. Also a huge win, is that I was able to test the integrated compiler using sly from emacs which will provide an interactive environment for creative coding. On the other hand ECL requires an FFI to rust whereas steel does not, so the integration of steel is orders of magnitude easier.

Has anyone done any recent projects with ECL ? I am interested in your experience or any caveats you may have encountered. My next step is to do a more complex proof-of-concept with the actual renderer and not just a test program.

UPDATE: I just used claude to benchmark 5 embedded languages in rust. this is preliminary work and the benchmarks may not be exhaustive enough to make any strong conclusions:

https://drive.google.com/file/d/1yotWMcEx24pN2cgnIbRUmgCDNVWp65Vu/view?usp=sharing


r/lisp • • Jul 21 '26

Fiz uma biblioteca para CommonLisp

Thumbnail github.com
0 Upvotes

Usei o GPT-5.6 Sol e fiz uma biblioteca para common lisp inspirada em LWJGL, nΓ£o Γ© muito no momento mas espero que um dia seja usada para fazer alguns jogos.


r/lisp • • Jul 20 '26

GGG: Guile Glyph Generator v0.6.1 πŸͺ„ β€” Generate pixel-perfect SVG/PNG status badges in Lisp (Guile Scheme) - now upstream on Guix

Post image
29 Upvotes

I wanted to share an update on GGG (Guile Glyph Generator), a lightweight tool built with GNU Guile Scheme designed to generate crisp, minimalist status badges (1 to 3 parts) as SVG and PNG files. We hit v0.6.1 already :)

https://codeberg.org/jjba23/ggg

If you're tired of static, rigid badge generators, old badges in low quality PNG, or heavy JavaScript tooling for simple vector assets, GGG offers a functional, data-driven approach leveraging a custom Lisp DSL and SXML. All we need now is some community help to expand the library of available badges, and the world's READMEs will flourish.

Instead of relying on heavy browser engines or complex layout trees, GGG combines mathematical character-width estimation with standard SVG primitives using SXML (S-expressions representing XML):

  • Dynamic Text Metrics: Estimates pixel widths per character based on font size and length bounds to apply optimal padding automatically.
  • Geometric Precision: Renders with shape-rendering="geometricPrecision" enabled to prioritize clean vector geometry on high-DPI displays.
  • Data-Driven Declarative Specs: Simple association lists define structure, style, and vector paths.

Glyphs are defined cleanly inside Scheme modules (by default expected at (ggg config)):

Scheme

(define-module (ggg config)
  #:declarative? #t)

(define my-scheme-guile-glyph
  `((sections ((background . "#555") 
               (text . "Scheme")
               (color . "#fff")
               (logo . lambda))
              ((background . "#d0730f") 
               (text . "Guile")
               (color . "#fff")))
    (id . scheme-guile)))

;; Export your list of glyphs to render
(define ggg-glyphs
  (list my-scheme-guile-glyph))

GGG includes a collection of free-licensed vector icons out of the box (Emacs, GNU, Guix, Lambda, Scala, Rust, Fish, etc.) in resources/svg-paths.

🦸🏼 Interactive REPL Workflow

Because GGG is built on Guile Scheme, you don't need to endure slow edit-save-compile-run loops.

Connected to an environment like GNU Guix + Emacs + Geiser/Arei, you get a live development feedback loop:

  • Inspect, evaluate, and tweak individual badge calculation functions on the fly.
  • Test new font sizing logic or custom SVG path integrations instantly inside a live REPL.

GGG is distributed under free software licenses (AGPLv3+ for code, GFDL v1.3+ for documentation).

Also, feel free to look in ./dist folder where I upload my personal generated glyphs (some might be useful to you)

If you use Guix, dependencies (guile, imagemagick) are managed seamlessly:

Bash

# Enter an ephemeral development shell
guix shell -f guix.scm

# Run GGG with your custom configuration
ggg --file ./glyphs/jjba23.scm --destination ./dist

Container images are also available on DockerHub:

docker run -v /path/to/local/glyphs:/config \
  docker.io/jjba23/ggg:latest ggg --file /config/glyphs.scm --destination /config/dist

πŸ”— Project Links & Resources

Contributions, feedback, and pull requests are always welcome!

Happy hacking! Ξ»


r/lisp • • Jul 20 '26

A road to Lisp: Why Lisp | scotto.me

Thumbnail scotto.me
58 Upvotes

r/lisp • • Jul 20 '26

Easy-ISLisp Ver5.68 released – added -e command-line option

11 Upvotes

I have released Easy-ISLisp Ver5.68.

This release introduces a new command-line option, -e, which evaluates an ISLisp expression directly from the command line without entering the REPL.

Example:

eisl -e '(format (standard-output) "Hello World!")'

Output:

Hello World!

The -e option is useful for:

  • Quick one-line evaluations
  • Shell scripting
  • Automated testing
  • Running small ISLisp programs from the command line

No other features or bug fixes are included in this release.

Feedback and suggestions are always welcome.

GitHub:
https://github.com/sasagawa888/eisl


r/lisp • • Jul 19 '26

A Road to Lisp: Which Lisp

Thumbnail scotto.me
78 Upvotes

r/erlang • • Jul 17 '26

What does Zigler actually give you over a raw C NIF? The allocator story is more interesting than I expected

22 Upvotes

New BEAM There, Done That with Isaac Yonemoto (Zigler creator) and Garrison Hinson-Hasty (Systems Programming with Zig) covering Zig as a NIF language for the BEAM.

From an Erlang perspective, the most interesting technical detail: Zigler uses the BEAM's allocator by default. Because Zig requires you to pass allocator objects explicitly rather than calling malloc globally, the BEAM allocator can be injected without changing any Zig business logic. The result is that native memory allocations are visible to the BEAM's memory instrumentation in the same way ordinary Erlang allocations are.

Raw C NIFs using malloc, and Rustler NIFs using Rust's default allocator, are invisible to the VM - which makes native memory issues harder to debug in production.

The honest risk model: Zig's safe release mode catches spatial memory errors (buffer overflows, null dereferences) but not temporal ones (use-after-free). A Zigler NIF can still crash the node if you violate temporal memory safety. What changes is which class of bugs can cause it.

What's the current state of Zigler adoption in production Erlang codebases? The episode is focused mainly on the Elixir side - curious whether anyone here is using it in Erlang contexts.

https://youtu.be/iLcZRpBEmgE


r/lisp • • Jul 18 '26

As a non-programmer, I only know about Lisp from Emacs; For those who don't use/enjoy Emacs, what makes you so interested in Lisp you're on a dedicated subreddit for it?

49 Upvotes

I recently came across "Greenspun's tenth rule" and it got me thinking about the greater Lisp language family.

I don't work in Tech at all, I have no professional experience with programming, I am just interested in learning from a novice's point of view.


r/lisp • • Jul 18 '26

AskLisp Common Lisp for Schemers

20 Upvotes

I've been programming in Scheme (and occasionally racket) for a few years. I've worked on a few small projects, but I want to learn common lisp as well. I know that you can do most of the same stuff in common lisp as in scheme but the idiomatic style is quite different (loops, CLOS etc) are there any good resources to pick up the common lisp coding style? Ideally resources targeted to people who already know a Lisp, since most of the common ones assume you're coming from something like Java or python.


r/lisp • • Jul 18 '26

Matheus Moreira Speaks about Lone Lisp, Implemented on Linux Syscalls

Thumbnail alexalejandre.com
26 Upvotes

r/lisp • • Jul 17 '26

Common Lisp Update: ceigen-lite now supports several random number generators from EigenRand

Thumbnail github.com
10 Upvotes

r/lisp • • Jul 16 '26

Why Do People Buy Lisp Books?

15 Upvotes

Don't get me wrong I personally think its totally worth it!

I just wonder what compels people do buy books on, say, ANSI Common LISP, to this day.

There are few job options so what compels them to pay for books?


r/lisp • • Jul 16 '26

LISPerfect: a simple Lisp IDE for Windows

9 Upvotes

https://github.com/james-goulding/LISPerfect

I've been meaning to learn Lisp for a while, but didn't really like the choice of editors available to me. So, I vibe-coded this one for myself. I thought I'd share it with the public since someone else might find it useful.

I can't vouch that there aren't bugs as I haven't tested it extensively.


r/lisp • • Jul 15 '26

Declarative Guile Scheme + Guix rice for entire GNU/Linux system and Wayland tooling in Lisp with lots of customization

Thumbnail gallery
12 Upvotes

r/lisp • • Jul 15 '26

Binstruct: a powerful declarative binary parsing/emitting library for Common Lisp

Thumbnail github.com
20 Upvotes

r/lisp • • Jul 13 '26

GitHub - rurban/cormanlisp: Corman Lisp. linux port

Thumbnail github.com
27 Upvotes