CHICKEN is a lovely, pragmatic Scheme, it has a ecosystem that IMHO beats other Schemes; you can easily compile executables, it has great package management, testing systems. In that regard, it feels modern and complete, like other contemporary languages. The only thing missing are lightweight green threads.
In a recent update, they added a debugger called feathers: it's a TCL script included in the default distro, and it's very nice, IMHO, especially for a debugger for compiled code: You can execute arbitrary code inside the current stack frame, and inspect both the source and the compiled code, among other things.
>The only thing missing are lightweight green threads.
...Ummm... Chicken already has that. It implements srfi-18 style pre-emptive coroutines which do qualify as green threads by the standard definition. They all run in a single thread, so you can parallelize without an explicit fork(2) like you can in Erlang and Go, but they are Green threads.
Or you can go with Gambit, which does superb job here and produces optimized code. Last releases added backends for Java, PHP, javascript and perl I think.
I dunno. Effectively, it's just a frontend for a TCP protocol that's used to communicate with the program being debugged: this allows for remote debugging and all manner of fun. They probably picked TCL because it's really good at GUIs, which is the brunt of the work feathers is doing, as most of the heavy lifting is done program-side, in scheme.
But that's just a guess, if you really want to know, I'd ask Felix: He's the lead developer on Chicken, and he's the one who actually wrote the thing and pushed the commit (see https://code.call-cc.org/cgi-bin/gitweb.cgi?p=chicken-core.g...). He's also pretty approachable.
As I wrote above, the brunt of the work is done inside of the program. The debugger proper is largely just the GUI and a client for the network protocol used to communicate with the program being debugged.
Chicken actually does have TK bindings, but they aren't very good. It's got bindings to lots of other toolkits, too, but TK is probably the easiest tookit out there to get working cross platform.
Chicken remains one of the most elegant and impressive implementations of any concept in any programming language you will find. A true marvel of engineering.
True, but that's not why I use it. If it was, I would have moved to Cyclone, which has improved Cheney on the MTA by adding threading support, and has a library system that doesn't suck (with chicken, you have to generate import files for every module in order for the system to compile or interpret your code, even if the modules get compiled into a single file: it's like .h files in C, but they're autogenerated. I usually use a make script to build them), and a macro system that (afaik) isn't O(n) if you evaluate in the macro environment by default.
But beyond the elegance of Chicken's internals, it's probably the most practical Scheme implementation for just getting stuff done fast. It has excellent C FFI, a good stdlib with solid POSIX bindings, an excellent package repository with all the libraries you might need, and it's very fast. It's not about the elegance, although it's there, it's about practicality: getting stuff done, efficiently, effectively, and now, not later.
If you want to get in-depth on Cheney on the MTA, I'd reccomend Peter Bex's article on the Chicken GC (http://www.more-magic.net/posts/internals-gc.html), and the original paper, "CONS should not CONS its arguments, part II: Cheney on the MTA". But I'll do my best to sum it up here.
Cheney on the MTA is a really neat hack that allows for cheap continuations, realtively efficient C compilation of Scheme code, and an effective garbage collection scheme.
Effectively, with CMTA, you have a generational GC, but the first generation is stack allocated. When the stack allocations run out of space, all the data is copied out to the heap, into the second generation of GC. This is super effective because most data is only allocated for a short time, so it never goes out to heap, and your accesses are closer together, and also on the stack, so there's less chance of a cache miss. But it gets better: In Scheme, a program's continuation (think basically its instruction pointer and stack state) can be reified as an actual data structure. However, since you're GCing the stack already, this doesn't causr any overheard, or at least not nearly as much as it does in, say, Guile, which has to copy the stack every single time a continuation is created.
The reason it's called Cheney on the MTA is because it uses Cheney's algorithm for GC, and because it's using the stack to hold data, popping the stack would invalidate program state, so it never returns.
What never returning has to do with the MTA is a cultural alusion that would take too long to explain here. But that's never stopped me before.
It's a reference to a song called "M.T.A", originally created for Walter O' Brian's campaign in 1949 (Boston's subway was known as the MTA at the time). It became a hit when recorded by The Kingston Trio in 1959. Looking up the song is left an excercise to the reader.
Unofficially, the song is known as "Charlie on the MTA," hence the title of the paper. And yes, this is where the CharlieCard gets its name.
The song is fairly entrenched in the area: I grew up in Connecticut, and know the lyrics from memory. And on one of several trips to Boston, I've seen at least one person expect to have to pay on their way out of the subway system because of the song :-).
Thanks for this. I've seen the "CONS should not CONS" paper somewhere, but skimming over it never really got me anywhere even close to this explanation. I always thought it was some in-jokey reference to US politics, but I couldn't connect the MTA concept.
Oh let me tell you a story about a function named *recursive* on a tragic and faithful time,
It was called with 3 long ints, popped the stack and set a jumpbuf, called itself on the SGI.
But did it ever return? No, it never returned, and its value is still unknown,
It may run forever on the SGI mainframe, it's the function that never returned.
Well that function ran a check to see when the stack would overflow, it ran almost past they say,
But when it got there the function called a longjump on the jumpbuf,
It just wasn't returning that day.
But did it ever return? No it never returned, and its value is still unlearned
It may run forever on the SGI mainframe, it's the function that never returned.
Man, GLS makes this look so easy. It's actually kind of hard.
Chicken Scheme is a great Scheme implementation. For a beginner, however, there is a lack of IDE e.g. a good guide how to get EMACS running for Chicken Scheme. I used Sublime Text at the beginning, but I showed performance problems when using the REPL.
Actually, there's a really good setup for Chicken in Emacs: paredit and scheme-mode provide the basics. But the crown jewel, as it were, is geiser: it supports most of the big schemes, including chicken, very well, and it has excellent docs: http://www.nongnu.org/geiser/
Geiser+scheme-mode+paredit, and maybe scheme-complete and flycheck, are the way to go for all schemes. And geiser is great. It can just about give SLIME a run for its money, which isn't something you can say about most modes.
Does this compile to a binary? I'd love to see some sort of similar live-compiler like https://gcc.godbolt.org/ for this language.
I've wanted to port my operating system attempts to some LISP-Like system but I've not found a good Scheme implementation that generated nice and clean assembly code.
It actually generates C, which can then be pushed through the $CC of your choice. Usually GCC. You can examine the generated C by passing a flag to the compiler, telling it not to compile it beyond that stage. However, reading the generated code isn't a task for the feint of heart: It generates CPS code, and it uses Cheney on the MTA (a really bizarre hack thought up by Henry Baker, and describe in his paper "CONS should not CONS its arguments, Part II: Cheney on the MTA," which is essentially required reading if you want to even have a hope of understanding what's going on.)
However, it makes heavy use of ELF and dynamic linking by default (although you can link statically), and libchicken, the runtime system, depends upon libc by default.
So yes, you probably could make use of it for OS work, but it's not ideal for that context.