What makes eBPF particularly well-suited for REPL-style development is the verifier. Every BPF program gets statically verified by the kernel before it runs -- no unbounded loops, no out-of-bounds memory access, no null dereferences. That safety guarantee is what makes "live" iteration safe: you can't panic the kernel, you just get a rejection and iterate. It's the closest thing to a systems-level sandbox that doesn't require a VM.
The interesting design space here is the feedback loop. bpftrace already gives you ad-hoc one-liners for tracing, but it's a separate language you have to context-switch into. Running eBPF programs directly from a Lisp REPL where you already have your analysis code means the kernel tracing and the result processing live in the same environment. You can define a probe, collect data, and immediately run your existing Lisp functions over it without serialization or context switching between tools.
The catch is that the verifier imposes constraints that don't map cleanly to Lisp's programming model -- no recursion, stack limit of 512 bytes, bounded loops only. Bridging that mismatch at the macro level seems like the harder problem than the basic REPL integration.
yacin•Mar 27, 2026
Common Lisp in particular is multi-paradigm. You can write a ton of code and never use recursion once. I doubt bridging this "gap" was in any way difficult.
erichocean•Mar 27, 2026
> Bridging that mismatch at the macro level seems like the harder problem than the basic REPL integration.
You can (and people do, core.async in Clojure works this way) put entire compilers in macros, macros are just functions that take and return code.
atgreen•Mar 27, 2026
The whistler code you inline with your common lisp is an s-expression based DSL. So you can use common lisp macros, but those macros are generating something that will look familiar to CL devs but is restricted based on the eBPF archictecture and validator requirements. eg. it only supports bounded `dotimes`, some basic progn/let/when/if/cond/eq/setf/incf/decf and math, and a simple array iterator. No lists, loops, tagbody/go, conditions, etc, etc. There's a manual in the docs directory.
fock•Mar 27, 2026
very cool and the person has the skills to do that. sad to see how the fully AI generated "why this matters" section in the blog gives a lingering vibe of slop.
sidkshatriya•Mar 27, 2026
> sad to see how the fully AI generated "why this matters" section in the blog gives a lingering vibe of slop.
I am quoting this verbatim from offending section:
Why this matters
The traditional eBPF workflow is: write C for the BPF side, compile with clang, then write Go or Rust or Python for the userspace side. Two languages, separate build steps, multiple processes.
With Whistler 1.0, the workflow is: write Lisp. The compiler, loader, and userspace application share a process. You can develop at the REPL — modify a probe, re-eval the form, see results immediately. The feedback loop is instant.
Seems like a reasonable paragraph. I sincerely feel we must stop tainting things with the "slop" pejorative unless it really seems egregious. Also in 2026 is it easy to be so confident about what was generated by a human, edited by a human or generated by an LLM ?
My main metric is: does the paragraph add value ? It does to me as a summary.
rjsw•Mar 27, 2026
The author has been using AI for other Lisp projects.
tmtvl•Mar 27, 2026
Yes, but it seems to me like atgreen takes care to ensure the result is decent, so I would hesitate before calling it slop. I may be wrong, though.
varjag•Mar 27, 2026
He's been also doing Lisp projects before GenAI, so…
kuschkufan•Mar 27, 2026
That dude just wanted everyone to know that he found the emdash, that he is so vigorously looking for in everything he reads these days.
Fellshard•Mar 27, 2026
It's more the repeated 'rule of three' that's getting me here.
That said, this is a relatively tame tack-on to a very meaty post, not worth harping on unless the project itself has similar issues.
runetech•Mar 27, 2026
Just recently discovered the author, Anthony Green. Floored and inspired by his productivity and scope of projects!
I enjoyed reading up on his fiber implementation and dabbling with the Java compiler/runtime integration.
Kudos Anthony - you make the world a more interesting place ;-)
atgreen•Mar 27, 2026
Thank you!
guenthert•Mar 27, 2026
While this is an interesting project, I found following grating:
"Permissions without root
You don’t need root. Grant capabilities to SBCL:
sudo setcap cap_bpf,cap_perfmon+ep /usr/bin/sbcl
Now sbcl --load my-bpf-program.lisp works as your regular user. Tracepoint format files need chmod a+r to allow non-root compilation with deftracepoint."
That's obviously not ideal. Better might be to create a purpose-built image. Unlike perl, sbcl doesn't even pretend to care about security. Taint mode extension for sbcl, anybody?
phoe-krk•Mar 27, 2026
> Unlike perl, sbcl doesn't even pretend to care about security.
Mind expanding? What particular stuff does Perl have in terms of security here?
I wonder if a taint mode for SBCL would mean ignoring SBCL_HOME... that'd be a bit annoying for running more up-to-date SBCL versions on distros shipping with older versions.
kuschkufan•Mar 27, 2026
Very impressive, good reason to get into Lisp, I reckon
6 Comments
I'm in danger of being nerd sniped.
The interesting design space here is the feedback loop. bpftrace already gives you ad-hoc one-liners for tracing, but it's a separate language you have to context-switch into. Running eBPF programs directly from a Lisp REPL where you already have your analysis code means the kernel tracing and the result processing live in the same environment. You can define a probe, collect data, and immediately run your existing Lisp functions over it without serialization or context switching between tools.
The catch is that the verifier imposes constraints that don't map cleanly to Lisp's programming model -- no recursion, stack limit of 512 bytes, bounded loops only. Bridging that mismatch at the macro level seems like the harder problem than the basic REPL integration.
You can (and people do, core.async in Clojure works this way) put entire compilers in macros, macros are just functions that take and return code.
I am quoting this verbatim from offending section:
Why this matters
The traditional eBPF workflow is: write C for the BPF side, compile with clang, then write Go or Rust or Python for the userspace side. Two languages, separate build steps, multiple processes.
With Whistler 1.0, the workflow is: write Lisp. The compiler, loader, and userspace application share a process. You can develop at the REPL — modify a probe, re-eval the form, see results immediately. The feedback loop is instant.
Seems like a reasonable paragraph. I sincerely feel we must stop tainting things with the "slop" pejorative unless it really seems egregious. Also in 2026 is it easy to be so confident about what was generated by a human, edited by a human or generated by an LLM ?
My main metric is: does the paragraph add value ? It does to me as a summary.
That said, this is a relatively tame tack-on to a very meaty post, not worth harping on unless the project itself has similar issues.
I enjoyed reading up on his fiber implementation and dabbling with the Java compiler/runtime integration.
https://atgreen.github.io/repl-yell/posts/sbcl-fibers/
https://github.com/atgreen/openldk
Kudos Anthony - you make the world a more interesting place ;-)
"Permissions without root
You don’t need root. Grant capabilities to SBCL:
sudo setcap cap_bpf,cap_perfmon+ep /usr/bin/sbcl
Now sbcl --load my-bpf-program.lisp works as your regular user. Tracepoint format files need chmod a+r to allow non-root compilation with deftracepoint."
That's obviously not ideal. Better might be to create a purpose-built image. Unlike perl, sbcl doesn't even pretend to care about security. Taint mode extension for sbcl, anybody?
Mind expanding? What particular stuff does Perl have in terms of security here?
I wonder if a taint mode for SBCL would mean ignoring SBCL_HOME... that'd be a bit annoying for running more up-to-date SBCL versions on distros shipping with older versions.