[HN Gopher] Web Embeddable Common Lisp
       ___________________________________________________________________
        
       Web Embeddable Common Lisp
        
       Author : todsacerdoti
       Score  : 90 points
       Date   : 2025-06-25 15:33 UTC (7 hours ago)
        
 (HTM) web link (turtleware.eu)
 (TXT) w3m dump (turtleware.eu)
        
       | tempodox wrote:
       | > Are we consing yet?                 > #'cons       #<compiled-
       | function CONS 0x43cee0>
       | 
       | That's a definite yes :)
        
       | jackdaniel wrote:
       | This is just a test page. Today I've shared an information about
       | an accepted grant proposal:
       | 
       | https://functional.cafe/@jackdaniel/114742776265318353
       | 
       | The work will go towards improving browser integration and
       | porting to WASI.
        
         | remexre wrote:
         | Will this include some form of SLIME support?
        
           | jackdaniel wrote:
           | I didn't plan explicitly for SLIME, but loading swank
           | shouldn't be much of a problem. The missing piece would be a
           | bridge between a websocket and tcp I think.
        
       | HexDecOctBin wrote:
       | Is WASM a good target for REPL-driven programming? I haven't
       | studied it in detail, but I do remember that it was Harvard
       | architecture. Would that mean that code can't be updated at
       | runtime in real implementations?
        
         | jackdaniel wrote:
         | ECL features native code and bytecodes vm for targets without
         | incremental compilation support - both native and bytecode can
         | be freely mixed at runtime.
         | 
         | That means that you may interactively use repl to call
         | functions that were compiled ahead of time and to add new
         | functions even on uncooperative targets.
         | 
         | After you've finished prototyping you may compile the finished
         | library to native ahead of time.
        
         | DonHopkins wrote:
         | It is, actually! I didn't realize that until I read the
         | handwritten WASM s-expression source code of WAForth.
         | 
         | Languages like Lisp or Forth that run on WASM -- or even
         | handwritten s-expression-style WASM code like in the WAForth
         | kernel -- can dynamically compile and assemble new WASM
         | bytecode and data. They can then call back to the JavaScript
         | host to create and link entirely new WASM modules on the fly,
         | and immediately call into them from the current module or
         | others. A single WASM context can juggle many dynamic modules,
         | large and small, all generated and linked at runtime!
         | 
         | So you can compile new code in Forth or Lisp and immediately
         | link and call it using indirect cross-module calls. It's not
         | the fastest way to call into WASM, but a metacompiler -- like
         | Mitch Bradley's ForthMacs / OpenFirmware -- could recompile the
         | whole system into one efficient, monolithic WASM module that
         | uses direct calls.
         | 
         | Here's the author's blog post about WAForth:
         | 
         | A Dynamic Forth Compiler for WebAssembly
         | 
         | https://el-tramo.be/blog/waforth/
         | 
         | https://news.ycombinator.com/item?id=34374057
         | 
         | DonHopkins on Jan 13, 2023 | parent | context | favorite | on:
         | What the hell is Forth? (2019)
         | 
         | This is a great article! I love his description of Forth as "a
         | weird backwards lisp with no parentheses".
         | 
         | https://blog.information-superhighway.net/what-the-hell-is-f...
         | 
         | Reading the source code of "WAForth" (Forth for WebAssembly)
         | really helped me learn about how WebAssembly works deep down,
         | from the ground up.
         | 
         | It demonstrates the first step of what the article says about
         | bootstrapping a Forth system, and it has some beautiful hand
         | written WebAssembly code implementing the primitives and even
         | the compiler and JavaScript interop plumbing. We discussed the
         | possibility of developing a metacompiler in the reddit
         | discussion.
         | 
         | I posted this stuff about WAForth and a link to a reddit
         | discussion with its author in the hn discussion of "Ten
         | influential programming languages (2020)":
         | 
         | https://news.ycombinator.com/item?id=34056735
         | 
         | Yes, I agree FORTH should be probably be on the list, at least
         | if the list was a few languages longer, for as influential as
         | it's been.
         | 
         | WAForth for WebAssembly is beautiful and modern!
         | 
         | https://github.com/remko/waforth
         | 
         | It's a lovingly crafted and hand written in well commented
         | WebAssembly code, using Racket as a WebAssembly macro pre-
         | processor.
         | 
         | I learned so much about WebAssembly by reading this and the
         | supporting JavaScript plumbing.
         | 
         | The amazing thing is that the FORTH compiler dynamically
         | compiles FORTH words into WebAssembly byte codes, and creates
         | lots of tiny little WebAssembly modules dynamically that can
         | call each other, by calling back to JavaScript to dynamically
         | create and link modules, which it links together in the same
         | memory and symbol address space on the fly! A real eye opener
         | to me that it was possible to do that kind of stuff with
         | dynamically generated WebAssembly code! It has many exciting
         | and useful applications in other languages than FORTH, too.
         | 
         | Lots more discussion and links in the reddit article.
         | 
         | But here's the beef, jump right in:
         | 
         | https://github.com/remko/waforth/blob/master/src/waforth.wat
         | 
         | Reddit /r/Forth discussion of WAForth:
         | 
         | https://www.reddit.com/r/Forth/comments/zmb4eb/waforth_wasmb...
         | 
         | remko:
         | 
         | Author here
         | 
         | If you can't be bothered to install VS Code, you can have a
         | look at a standalone version of the example notebook (in a 26kB
         | self-contained page).
         | 
         | And if you're planning to go to FOSDEM 2023, come say hi: I'll
         | be giving a talk there on WebAssembly and Forth in the
         | Declarative and Minimalistic Computing devroom.
         | 
         | DonHopkins:
         | 
         | I really love your tour-de-force design and implementation of
         | WAForth, and I have learned a lot about WebAssembly by reading
         | it. Never before have I seen such beautiful meticulously hand
         | written and commented WebAssembly code.
         | 
         | Especially the compiler and runtime plumbing you've implemented
         | that dynamically assembles bytecode and creates WebAssembly
         | modules for every FORTH word definition, by calling back to
         | JavaScript code that pulls the binary bytecode of compiled
         | FORTH words out of memory and creates a new module with it
         | pointing to the same function table and memory.
         | 
         | WebAssembly is a well designed open standard that's taking over
         | the world in a good way, and it also runs efficiently not just
         | in most browsers and mobile smartphones and pads, but also on
         | the desktop, servers, cloud edge nodes, and embedded devices.
         | And those are perfect target environments for FORTH!
         | 
         | What you've done with FORTH and WebAssembly is original,
         | brilliant, audacious, and eye-opening!
         | 
         | I'd read the WebAssembly spec before, and used and studied the
         | Unity3D WebAssembly runtime and compiler to integrate Unity3D
         | with JavaScript, and I also studied the AssemblyScript subset
         | of TypeScript targeting WebAssembly and its runtime, and also
         | Aaron Turner's awesome wasmboy WebAssembly GameBoy emulator .
         | 
         | I first saw your project a few years ago and linked to it in
         | this Hacker News discussion about Thoughts on Forth Programming
         | because I thought it was cool, but it's come a long way in
         | three years, and I'm glad I finally took the time to read some
         | of your code, which was well worth the investment of time.
         | 
         | Until reading your code, I didn't grasp that it was possible to
         | integrate WebAssembly with JavaScript like that, and use it to
         | dynamically generate code the way you have!
         | 
         | Also, the way you used Racket as a macro assembler for
         | WebAssembly was a practical and beautiful solution to the
         | difficult problem of writing maintainable WebAssembly code by
         | hand.
         | 
         | Even for people not planning on using FORTH, WAForth is an
         | enlightening and useful example for learning about WebAssembly
         | and its runtime, and a solid proof of concept that it's
         | possible to dynamically generate and run WebAssembly code on
         | the fly, and integrate a whole bunch of tiny little WebAssembly
         | modules together.
         | 
         | Playing with and reading through your well commented code has
         | really helped me understand WebAssembly and TypeScript and the
         | surface between them at a much deeper level. Thank you for
         | implementing and sharing it, and continuing to improve it too!
         | 
         | remco:
         | 
         | Wow, thanks a lot, I really appreciate that! It makes me very
         | happy that I was able to get someone to learn something about
         | WebAssembly by reading the source code, which is exactly what I
         | was going for.
         | 
         | [More links and discussion of WAForth, WebAssembly, and Forth
         | Metacompilers:]
         | 
         | https://www.reddit.com/r/Forth/comments/zmb4eb/waforth_wasmb...
         | 
         | Here's the author's blog post about WAForth: A Dynamic Forth
         | Compiler for WebAssembly
         | 
         | https://el-tramo.be/blog/waforth/
         | 
         | https://news.ycombinator.com/item?id=34374057
         | 
         | DonHopkins on Jan 13, 2023 | parent | context | favorite | on:
         | What the hell is Forth? (2019)
         | 
         | This is a great article! I love his description of Forth as "a
         | weird backwards lisp with no parentheses".
         | 
         | Reading the source code of "WAForth" (Forth for WebAssembly)
         | really helped me learn about how WebAssembly works deep down,
         | from the ground up.
         | 
         | It demonstrates the first step of what the article says about
         | bootstrapping a Forth system, and it has some beautiful hand
         | written WebAssembly code implementing the primitives and even
         | the compiler and JavaScript interop plumbing. We discussed the
         | possibility of developing a metacompiler in the reddit
         | discussion.
         | 
         | I posted this stuff about WAForth and a link to a reddit
         | discussion with its author in the hn discussion of "Ten
         | influential programming languages (2020)":
         | 
         | https://news.ycombinator.com/item?id=34056735
         | 
         | Yes, I agree FORTH should be probably be on the list, at least
         | if the list was a few languages longer, for as influential as
         | it's been.
         | 
         | WAForth for WebAssembly is beautiful and modern!
         | 
         | https://github.com/remko/waforth
         | 
         | It's a lovingly crafted and hand written in well commented
         | WebAssembly code, using Racket as a WebAssembly macro pre-
         | processor.
         | 
         | I learned so much about WebAssembly by reading this and the
         | supporting JavaScript plumbing.
         | 
         | The amazing thing is that the FORTH compiler dynamically
         | compiles FORTH words into WebAssembly byte codes, and creates
         | lots of tiny little WebAssembly modules dynamically that can
         | call each other, by calling back to JavaScript to dynamically
         | create and link modules, which it links together in the same
         | memory and symbol address space on the fly! A real eye opener
         | to me that it was possible to do that kind of stuff with
         | dynamically generated WebAssembly code! It has many exciting
         | and useful applications in other languages than FORTH, too.
         | 
         | Lots more discussion and links in the reddit article.
         | 
         | But here's the beef, jump right in:
         | 
         | https://github.com/remko/waforth/blob/master/src/waforth.wat
         | 
         | Reddit /r/Forth discussion of WAForth:
         | 
         | https://www.reddit.com/r/Forth/comments/zmb4eb/waforth_wasmb...
         | 
         | remko:
         | 
         | Author here
         | 
         | If you can't be bothered to install VS Code, you can have a
         | look at a standalone version of the example notebook (in a 26kB
         | self-contained page).
         | 
         | And if you're planning to go to FOSDEM 2023, come say hi: I'll
         | be giving a talk there on WebAssembly and Forth in the
         | Declarative and Minimalistic Computing devroom.
         | 
         | DonHopkins:
         | 
         | I really love your tour-de-force design and implementation of
         | WAForth, and I have learned a lot about WebAssembly by reading
         | it. Never before have I seen such beautiful meticulously hand
         | written and commented WebAssembly code.
         | 
         | Especially the compiler and runtime plumbing you've implemented
         | that dynamically assembles bytecode and creates WebAssembly
         | modules for every FORTH word definition, by calling back to
         | JavaScript code that pulls the binary bytecode of compiled
         | FORTH words out of memory and creates a new module with it
         | pointing to the same function table and memory.
         | 
         | WebAssembly is a well designed open standard that's taking over
         | the world in a good way, and it also runs efficiently not just
         | in most browsers and mobile smartphones and pads, but also on
         | the desktop, servers, cloud edge nodes, and embedded devices.
         | And those are perfect target environments for FORTH!
         | 
         | What you've done with FORTH and WebAssembly is original,
         | brilliant, audacious, and eye-opening!
         | 
         | I'd read the WebAssembly spec before, and used and studied the
         | Unity3D WebAssembly runtime and compiler to integrate Unity3D
         | with JavaScript, and I also studied the AssemblyScript subset
         | of TypeScript targeting WebAssembly and its runtime, and also
         | Aaron Turner's awesome wasmboy WebAssembly GameBoy emulator .
         | 
         | I first saw your project a few years ago and linked to it in
         | this Hacker News discussion about Thoughts on Forth Programming
         | because I thought it was cool, but it's come a long way in
         | three years, and I'm glad I finally took the time to read some
         | of your code, which was well worth the investment of time.
         | 
         | Until reading your code, I didn't grasp that it was possible to
         | integrate WebAssembly with JavaScript like that, and use it to
         | dynamically generate code the way you have!
         | 
         | Also, the way you used Racket as a macro assembler for
         | WebAssembly was a practical and beautiful solution to the
         | difficult problem of writing maintainable WebAssembly code by
         | hand.
         | 
         | Even for people not planning on using FORTH, WAForth is an
         | enlightening and useful example for learning about WebAssembly
         | and its runtime, and a solid proof of concept that it's
         | possible to dynamically generate and run WebAssembly code on
         | the fly, and integrate a whole bunch of tiny little WebAssembly
         | modules together.
         | 
         | Playing with and reading through your well commented code has
         | really helped me understand WebAssembly and TypeScript and the
         | surface between them at a much deeper level. Thank you for
         | implementing and sharing it, and continuing to improve it too!
         | 
         | remco:
         | 
         | Wow, thanks a lot, I really appreciate that! It makes me very
         | happy that I was able to get someone to learn something about
         | WebAssembly by reading the source code, which is exactly what I
         | was going for.
         | 
         | [More links and discussion of WAForth, WebAssembly, and Forth
         | Metacompilers:]
         | 
         | https://www.reddit.com/r/Forth/comments/zmb4eb/waforth_wasmb...
        
         | runlaszlorun wrote:
         | I'd use the analogy of current dynamic language VMs being
         | written C. You're not modifying structs at runtime or creating
         | C functions as a user of the dynamic language. But the creators
         | of the VM are providing as thin a layer as possible on top of
         | that to give the runtime behavior it's dynamism.
         | 
         | There's an often repeated line that WebAssembly isn't really
         | "assembly" and it's not "web". There's a lot of truth to that.
         | I dove in hoping for a cross platform, web enabled assembly. It
         | looks a lot like an assembly but I find it's relatively few
         | restrictions like lack of a true jump command rippling out more
         | than one would have expected. It's also sortuva stack machine
         | and sortuva register machine at the same time.
         | 
         | It does share a lot with the internal VMs in many places like
         | the JVM, Python's VM, .net, etc.
        
           | DonHopkins wrote:
           | "I'm a little verklempt. Talk amongst yourselves. I'll give
           | you a topic: WebAssembly is neither Web nor Assembly.
           | Discuss." -Your Host, Linda Richman
           | 
           | https://www.youtube.com/watch?v=oiJkANps0Qw
        
       | potholereseller wrote:
       | Apparent source code, though last update is January 1, 2025:
       | https://fossil.turtleware.eu/wecl/timeline
        
       | jinlisp wrote:
       | When executing (time (loop for i below (expt 10 8) count t)) it
       | takes a long time, sbcl takes less than a second on this. So not
       | useful when speed is required. More: (time (loop for i below
       | 1000000 count t) takes 7 seconds on my computer, so counting to
       | (exp 10 8) would take 700 seconds, and sbcl do that in 0.1
       | seconds, so in this example the ratio is 7000 times slower than
       | sbcl.
        
         | jackdaniel wrote:
         | Bytecodes compiler used in this build from repl is one-pass
         | with very little optimizations, so it is not surprising.
         | Natively compiled code is much faster.
        
           | jinlisp wrote:
           | Should it be possible to implement an optimization compiler?
           | so that compiling the code in the web page produces results
           | similar to ECL or sbcl?
        
             | jackdaniel wrote:
             | With enough code - yes. But not right now. You may
             | precompile to native though.
        
       | jinlisp wrote:
       | I was going to ask if maxima (a symbolic computation system) can
       | be implemented in the browser, but it was answered four months
       | ago [1]
       | 
       | [1] https://news.ycombinator.com/item?id=42853528
        
         | mixedmath wrote:
         | Do you use maxima? Would you say it's still worth using and
         | learning?
        
           | jinlisp wrote:
           | It depends of what you need, but for example for calculus is
           | a nice program. There is also sympy and Wolfram Mathematica.
           | For symbolic computation I think that Mathematica is the
           | strongest then maxima and then sympy, but sympy is based on
           | python and I think it will get stronger. If you need
           | numerical computation then there is octave or matlab or
           | julia.
        
             | mrbungie wrote:
             | For symbolic computation there is also Maple (*shudders at
             | the thought*).
        
           | johnisgood wrote:
           | Yes, I think it is worth learning. GNU units is worth
           | learning, too. You know these math riddles? You can solve it
           | using GNU units alone. :D
        
       | jinlisp wrote:
       | This is another comment of the author about maxima in the browser
       | from four months ago: I'm experimenting with WASI and the GC
       | extension for WASM, but that's months from today if we speak
       | about complete port (given my time capacity at the moment). Don't
       | know if the gc extension is used in this example.
        
       | bevr1337 wrote:
       | Why was LISP not one of the first languages able to compile to
       | WASM? I've been curious ever since the awesome WASM project
       | started tracking different projects. They use emojis for progress
       | and LISP has been a hatching egg.
        
         | no_wizard wrote:
         | It sorta has been. As a language design it is already native
         | via the WAT[0] which compiles to web assembly.
         | 
         | [0]:
         | https://webassemblyman.com/wat_webassembly_text_format.html
        
           | bevr1337 wrote:
           | Do you know why only sorta? My understanding is that only toy
           | implementations exist right now but nothing production ready.
           | I'm poking around Google and GitHub and not finding any new
           | information.
           | 
           | > Implementing Lisp onto WebAssembly is so obvious that you
           | may wonder why somebody did not have this idea long ago.
           | 
           | I did find this on the Femto GitHub and got a chuckle. Yes,
           | dear author, that is exactly the piece of information I want
           | explained. Too funny.
        
         | dmkolobov wrote:
         | If I had to guess:
         | 
         | 1. lack of native GC, you had to roll your own by providing a
         | runtime.
         | 
         | 2. lack of tail-call elimination in V1 of the spec. This
         | essentially forces you to trampoline everything.
        
           | stassats wrote:
           | > lack of tail-call elimination
           | 
           | But lisp doesn't need TCO.
        
       | b0a04gl wrote:
       | tbh imo the slowness isn't the bottleneck. browser bytecode's
       | always gonna trail native, that's a given. what matters is you're
       | feeding live eval into static pages. lisp as a runtime inside the
       | web, not around it.
       | 
       | if wasm interop clicks, even at shared memory level, lisp can
       | directly drive ui updates. state changes, you eval, dom shifts.
       | pure control flow without detour
        
       | jackdaniel wrote:
       | Btw, eval (ed "wecl.lisp") to see some interesting function
       | definitions, like canvas or webgl access drafts.
        
       | deosjr wrote:
       | I recently shared a project I did using Hoot, by Spritely
       | institute. It's Guile Scheme compiling to WASM, and it works
       | really well! See https://spritely.institute/hoot/
       | 
       | Latest on my project, in case you want to try it out:
       | https://deosjr.github.io/dynamicland/whiskers.html
        
       | feeley wrote:
       | Related:
       | 
       | The Gambit Scheme REPL that comes with a tutorial, supports
       | threads in the browser and has a JS FFI:
       | https://try.gambitscheme.org
       | 
       | Gambit in emacs in the browser: https://feeley.github.io/gambit-
       | in-emacs-in-the-browser/
        
       ___________________________________________________________________
       (page generated 2025-06-25 23:00 UTC)