5 ms·
Web Embeddable Common Lisp
- tempodox 1y ago> Are we consing yet? > #'cons #<compiled-function CONS 0x43cee0> That's a definite yes :)
- jackdaniel 1y agoThis is just a test page. Today I've shared an information about an accepted grant proposal: https://functional.cafe/@jackdaniel/114742776265318353 https://functional.cafe/@jackdaniel/114742776265318353 The work will go towards improving browser integration and porting to WASI.
- remexre 1y agoWill this include some form of SLIME support?
- jackdaniel 1y agoI 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 1y agoIs 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 1y agoECL 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 1y agoIt 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://el-tramo.be/blog/waforth/ https://news.ycombinator.com/item?id=34374057 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-forth 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 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 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 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_wasmbased_ans_forth_supports_interactive/ 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_wasmbased_ans_forth_supports_interactive/ 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://el-tramo.be/blog/waforth/ https://news.ycombinator.com/item?id=34374057 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 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 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 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_wasmbased_ans_forth_supports_interactive/ 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_wasmbased_ans_forth_supports_interactive/ https://www.reddit.com/r/Forth/comments/zmb4eb/waforth_wasmb...
- runlaszlorun 1y agoI'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 1y ago"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 https://www.youtube.com/watch?v=oiJkANps0Qw
- ethan_smith 1y agoModern WASM implementations use JIT compilation with dynamic code generation capabilities that effectively bypass the Harvard architecture limitations, allowing for runtime code updates through module instantiation and function replacement.
- potholereseller 1y agoApparent source code, though last update is January 1, 2025: https://fossil.turtleware.eu/wecl/timeline https://fossil.turtleware.eu/wecl/timeline
- jinlisp 1y agoWhen 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 1y agoBytecodes 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 1y agoShould 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 1y agoWith enough code - yes. But not right now. You may precompile to native though.
- mishoo 1y agoIn SLip: https://lisperator.net/s/slip/ https://lisperator.net/s/slip/ SL-USER> (time (loop for i below (expt 10 8) count t)) Evaluation time: 19376ms 100000000 SL-USER> (time (loop for i below 1000000 count t)) Evaluation time: 272ms 1000000 SL-USER> (defun fib (n) (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2))))) #'FIB SL-USER> (time (fib 32)) Evaluation time: 1601ms 2178309 These timings are in Firefox; Chromium is almost 2x faster. Also, it doesn't completely freeze the browser in the mean time (we have green threads). I used to think it's quite slow, but somehow it's much faster than any other posted here. The only Lisp in browser I know to beat SLip (by a large margin) is JSCL, which compiles to JS.
- taway-20250404 1y ago[flagged]
- jackdaniel 1y agoWhat a bunch of fud.. If you want to make mcclim progress faster then chip in with actual expertise instead of unfunded snarks. ECL is a stable implementation with actual users, if you can point out existing problems then please report them.
- jinlisp 1y agoI 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 https://news.ycombinator.com/item?id=42853528
- mixedmath 1y agoDo you use maxima? Would you say it's still worth using and learning?
- jinlisp 1y agoIt 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 1y agoFor symbolic computation there is also Maple (*shudders at the thought*).
- johnisgood 1y agoYes, 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
- anthk 1y agoQalc from libqalculate it's a mini-maxima.
- jinlisp 1y agoThis 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 1y agoWhy 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 1y agoIt 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 https://webassemblyman.com/wat_webassembly_text_format.html
- bevr1337 1y agoDo 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.
- no_wizard 1y agoIt doesn’t have to very last trapping of a proper LISP if I recall correctly is why I say kinda. It’s an S expression language though with some similarities to LISP
- bevr1337 1y agoThanks for clarifying. I've been speculating on this for a while but haven't had the chops to know what to research. The details folks are providing are yielding much better search results.
- dmkolobov 1y agoIf 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.
- b0a04gl 1y ago[dead]
- jackdaniel 1y agoBtw, eval (ed "wecl.lisp") to see some interesting function definitions, like canvas or webgl access drafts.
- deosjr 1y agoI 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/ https://spritely.institute/hoot/ Latest on my project, in case you want to try it out: https://deosjr.github.io/dynamicland/whiskers.html https://deosjr.github.io/dynamicland/whiskers.html
- feeley 1y agoRelated: The Gambit Scheme REPL that comes with a tutorial, supports threads in the browser and has a JS FFI: https://try.gambitscheme.org https://try.gambitscheme.org Gambit in emacs in the browser: https://feeley.github.io/gambit-in-emacs-in-the-browser/ https://feeley.github.io/gambit-in-emacs-in-the-browser/
- mishoo 1y agoHey, nice to see Ymacs is still used somewhere else than on my website :) I don't know if you've been tracking it lately, but there was a big overhaul last year [1]. The version in your second link doesn't seem to work in current Firefox. If you'd like to update and need any help, please feel free to get in touch. (also, there's still some of your code in Ymacs :) although I kinda broke filename completion...) [1] https://lisperator.net/blog/ymacs-reloaded/ https://lisperator.net/blog/ymacs-reloaded/