8 ms·
Crunch – a Scheme compiler with a minimal runtime
- nudpiedo 2y agoso if I understand this right, it could be a way to run scheme on esp32 and similar microcontrollers, isn't it? Also its small size would make it a perfect target to compile to typescript/deno/wasm without rejecting the s-exp power and runtime possibilities in its full chicken code at the backend...
- f1shy 2y agoNot in the way I would like: you cannot have a REPL running. Seems only a transpiler for R7 Small.
- davexunit 2y agoIt's compiling a subset of Scheme that can be statically typed. It's not for full-blown live-hackable Scheme programs. You'd use Crunch or PreScheme to implement things that you can't implement in Scheme, like a garbage collector. I don't know if Crunch has this feature, but with PreScheme you can run your PreScheme programs at the Scheme REPL so you can have your comfy REPL-driven dev environment and then create a static executable when you're ready.
- soegaard 2y agoThere are specialized Scheme implementations that aim to be small. A recent paper (see also the presentation on YouTube): Leonard Oest O'Leary, Mathis Laroche, and Marc Feeley A R4RS Compliant REPL in 7 KB For systems with a C compiler: Vincent St-Amour and Marc Feeley. PICOBIT: A Compact Scheme System for Microcontrollers. (This one got a best paper award). Finally, there is also PICBIT available for PIC microcontrollers: PICBIT: A Scheme System for the PIC Microcontroller
- cardanome 2y agoNot a scheme, but for running a lisp on microcontrollers uLisp is pretty amazing. http://www.ulisp.com/ http://www.ulisp.com/ You even get a REPL and everything WHILE running on the hardware. Super easy to set up and get going. Though as it is interpreted so you will of course not have native performance. Still very useful for prototyping and hobbyist projects.
- retrac 2y agoAs a rule, interpreted code has a smaller memory footprint than natively compiled programs. Even interpreted on a several hundred MHz classic RISC microcontroller, Lisp will chew through a million cons cells a second or more - an order of magnitude or so faster than the old Lisp machines in the 80s were and they used to run giant CAD systems on those to design aircraft and stuff. (Albeit slowly...)
- int_19h 2y agoOTOH if you want something that gives you a REPL and everything directly on the hardware but is also not as slow as your typical interpreter, look at Forth.
- davexunit 2y agoI'm glad to see more projects exploring the statically compiled Scheme space. One difference from PreScheme listed is R7RS conformance, but the PreScheme restoration project is also targeting R7RS so that the compiler is portable to many Scheme implementations. The biggest difference I can see is manual memory management vs. reference counting. Though, one of the TODO items for the PreScheme restoration is to revisit memory management. Maybe PreScheme will end up with reference counting, as well.
- fouric 2y agoFor Common Lispers such as myself, who are vaguely aware of developments in the Scheme space: the most important difference between CRUNCH and Chicken appears to be that, while both compile down to C/object code, CRUNCH is additionally targeting a statically-typed subset of Scheme. Opinion: this is great. The aversion of Lispers to static types is historical rather than intrinsic and reflects the relative difference in expressiveness between program semantics and type semantics (and runtime vs tooling) for much of computing. Now that types and tools are advancing, static Lisps are feasible, and I love that.
- stefantalpalaru 2y ago[dead]
- diggan 2y ago> Now that types and tools are advancing, static Lisps are feasible, and I love that. Haven't that been feasible for a pretty long time already? Judging by how well-received (or not) they've been, it seems there isn't much demand for it. Things like clojure.spec and alike (compile-time + run-time typing) seems much more popular, but isn't static.
- nesarkvechnep 2y agoThere isn’t much demand for Lisps in general.
- stolen_biscuit 2y agoI think given the sheer amount of them that is demonstrably false
- cjaybo 2y agoMany have been created, but how many have significant usage?
- CyberDildonics 2y ago
- Imustaskforhelp 2y agoInteresting since this can compile down to C code , I was thinking maybe we can convert this to cosmopolitan c code as well?
- Imustaskforhelp 2y agothat is to make it so that a single executable can on everything
- kristjansson 2y agoYou would just need to (configure this tool to) compile the resulting C with cosmocc, no?
- VyseofArcadia 2y agoI believe the domain name is a reference to this anecdote https://www.catb.org/jargon/html/magic-story.html https://www.catb.org/jargon/html/magic-story.html
- sjamaan 2y agoYou believe correctly
- JonChesterfield 2y agoThe make && make install doesn't create the chicken-crunch executable which is used in the examples, nor do I see 'crunch' in any of the build scripts. Any guesses?
- dieggsy 2y agoThe installation bit mentions doing: > <install location>/bin/chicken-install -test crunch Edit: That's because this is an "egg", which is an external library/package not part of the core chicken install
- JonChesterfield 2y agoAh yes, the test runner leaves the new binary under bin. Thanks
- jxy 2y ago> No support for first class continuations I'm not sure about how people would feel about this. I have mixed feelings. It feels like a loss of many things. What are the gains from ditching continuations?
- mst 2y agoGiven the intent to have relatively straightforward C code and a tiny runtime, you pretty much have to ditch them or you're not going to get anywhere at all. Plus honestly most of the uses of continuations that would make sense in the sort of relatively low level code this is aimed at can be built out of a few special purpose macros (and possibly a small amount of crying) - scheme code tends to lean on first class continuations for a lot of things that don't really need them, Because It Can. e.g. Paul Graham's On Lisp shows how to build (a subset of) continuations out of macros, and getting something like clojure's 'recur' out of that would probably give you simpler macros than pg's code uses.
- soegaard 2y agoFrom the article: > What is needed is a small, portable compiler that generates more or less "natural" C code with minimal dependencies and runtime system that supports at least the basic constructs of the language and that puts an emphasis on producing efficient code, even if some of the more powerful features of Scheme are not available. Since C doesn't support continuations, it is not possible to have continuations and at the same time generate "natural" C code. Consider how you would implement first class continuations. It's not possible to do CPS transformation (given the goal of natural code generation) - since that's a whole program transformation.
- rollcat 2y agoThe interesting part is how few trade-offs had to be made to make GC-less (ref-counting) Scheme-to-C compilation attainable, and how closely CRUNCH adheres to R7RS. Notable is the lack of call/cc, but in my "armchair expert" opinion, it's the ugliest part of the language. Yes, continuations as a first-class object are elegant and succinct, but in order to do anything actually useful with them (like implementing exceptions), you need library code, which makes them much less composable. I think there's a much more pleasant and practical language lurking somewhere between R6RS "big" and traditional "small" Scheme, but I feel it would take a BDFL to flesh it out. (Meanwhile, back to fixing my init.el.)
- wbl 2y agoDelineated continuations might help
- michaelsbradley 2y agodelimited
- ta8645 2y agoThe very first rudimentary standalone example: (define (main) (display "Hello world\n")) Doesn't compile, but instead gives error: Error: main: global variable `scheme#display' has unknown type
- JonChesterfield 2y agoThe popcount example does compile, if you drop the "assume" form, (import (chicken bitwise) (chicken fixnum)) (define (popcount32 x) ; From "Hacker's Delight" ; (assume (let ((x (fx- x (bitwise-and (arithmetic-shift x -1) #x55555555)))) (let ((x (fx+ (bitwise-and x #x33333333) (bitwise-and (arithmetic-shift x -2) #x33333333)))) (let ((x (bitwise-and (fx+ x (arithmetic-shift x -4)) #x0F0F0F0F))) (let ((x (fx+ x (arithmetic-shift x -8)))) (let ((x (fx+ x (arithmetic-shift x -16)))) (bitwise-and x #x0000003F))))))) Turns into somewhat redundant C, looks much like transliterated bytecode, e.g. long v17 = 0; // ... // popcnt.scm:7 v17 = 0; // ... // popcnt.scm:7 v17 = (t37 & 252645135); // popcount32 // popcnt.scm:8 t40 = crunch_arithmetic_shift(v17, -8); Interesting find in the (small) crunch.h is #ifdef CRUNCH_FREESTANDING #include <inttypes.h> #include <stdarg.h> #include <complex.h> #include "crunch-environment.h" #else // loads of stuff though I haven't found crunch-environment.h in the source yet
- 2y ago
- soegaard 2y agoThe documentation for Crunch is here: https://wiki.call-cc.org/eggref/6/crunch https://wiki.call-cc.org/eggref/6/crunch
- iainctduncan 2y agoThis just made my day. I'm the author of Scheme for Max, an extension to the Max music programming environment that puts the s7 Scheme interpreter in it for scripting note-event level code (not dsp). It would be fantastic to also be able to use a subset of Scheme for generating DSP level code, where speed would be more important than dynamic typing or continuations/tco/etc. I will be watching this closely!
- jnxx 2y agowhat do you think about pre-scheme?
- iainctduncan 2y agoI haven't tried it, but I'm curious and interested!
- davidjade 2y agoFun fact: the DOS version of the Cakewalk music software in the late 80's had a scripting language (CAL) that was very loosely based on Lisp. The author (Greg Hendershott) later went on to write a lot about Lisp.
- iainctduncan 2y agoYes! This was the first "lisp" I ever used, back in the very early 90's. It was still part of Cakewalk in the windows releases at that time and was really Cakewalk's secret weapon. With the Ableton Live Notes API, enabling something similar is one of the things I plan on adding to Scheme for Max this year. Thanks for the tip about who wrote it, I will look him up!
- JonChesterfield 2y ago> Other targets are possible, like GPUs. I don't know anything about that, so if you are interested and think you can contribute, please don't hesitate to contact me. The freestanding macro suggests most of the heavy lifting is done. Stuff the GPU targets will struggle with in no particular order: - setjmp / longjmp - signals (if used?) - threads - fast alloc/free - stack will be smaller than chicken expects I don't know how to do signals. The rest are merely difficult.
- outworlder 2y ago> - setjmp / longjmp Isn't that mostly needed by call/cc, which is not supported by Crunch?
- JonChesterfield 2y agoI thought chicken used it to treat the C stack as an arena for the GC, with longjmp acting as part of garbage collection. I don't see how it would help for call/cc, that needs a reified stack to handle repeat invocations.
- sjamaan 2y agoCrunch doesn't have any of these. That's CHICKEN you're thinking of, but CRUNCH explicitly does not require CHICKEN.
- hassleblad23 2y agoThis looks useful for sure.