s7 – Scheme implementation intended as extension language for other applications
ccrma.stanford.edu
ccrma.stanford.edu
The best part of S7 in my opinion is how easy to embed and extend it is. The C FFI is really easy to use, and all of S7 fits s7.c and s7.h, making building very easy. You can see some S7 in action in Max/MSP here: https://www.youtube.com/watch?v=ErirIFCTdjg&t=2s&ab_channel=...
It will be seeing new releases this semester as it's now my Masters in Music Tech thesis project at the University of Victoria, working with Dr Andrew Schloss. I plan to have full support for running the Common Music algorithmic composition toolkit in Max/MSP this year.
I have also used S7 in a Juce applications, which is what the normal version of Common Music does in its "Grace" host and Christos Vagias has been using it in iPlug 2 for VST plugin development.
My personal take on Scheme is that call/cc is elegant and powerful in the same way that assembly language is elegant and powerful—and just like it’s hard to reason about programs that make creative use of assembly language constructs, it’s hard to reason about programs that make creative use of call/cc. Just like you can implement nearly any control structure in assembly, you can implement many with call/cc. I was once working on a Scheme compiler but abandoned the efforts once I realized the enormous negative impact that call/cc has on writing compilers, interpreters, and library code.
Do you want to write a reasonably fast and general mapcar? Do you want to do some basic escape analysis to see if you can allocate a value on the stack? Better have a good, long think about things. The withering gaze of call/cc will make your face melt.
So, years ago, I was hopeful that there would be an officially sanctioned Scheme without call/cc. Call it what you will. It never materialized.
You can think of it as two sides of the same coin—just like objects are a poor substitute for closures and closures are a poor substitute for objects, call/cc is a poor substitute for exception handling, and exception handling is a poor substitute for call/cc. R7RS adds SRFI-34, but you still see stuff like with-baffle and call-with-exit precisely because call/cc is like a stick of dynamite that you can put in your code, and there’s no way it can work across any kind of FFI boundary without severe restrictions.
Normally, you just want functions, but sometimes, you want coroutines. Normally, one-shot coroutines are fine, but sometimes you want multi-shot. I have never once felt like a full-blown continuation was the construct I was missing.
Isn't implementing call/cc trivial if you have CPS?
The other criticisms are common and valid. Racket uses delimited continuations instead because of the pitfalls of call/cc.
You’re right that call/cc itself can be trivial. The problem is that everything else becomes way more complicated because call/cc exists.
The critical thing to remember is that if you have call/cc, ANY user-supplied function can return multiple times. In general people expect library functions to “just deal with it” and in practice that means that (1) half your library functions might just be broken but you don’t know it because they fail some weird test case involving call/cc that you didn’t cover (1) you can’t do anything clever to speed up your library functions and (2) your compiler won’t be capable of doing the escape analysis to fix the performance issues in your library functions.
The thing is, you can conceptualize of call/cc as being just “free” if you think of the language as a way to program a continuation-passing machine, but when you do that, you’re basically one step away from some weird garbage-collected assembly language with unlimited goto.
In order to reason about programs more effectively we largely abandoned goto except for the few cases where it’s the right tool. Most of the time we like our control structures to match the stack—you go IN to a function exactly once, and then OUT of the function exactly once.
Introducing weaker language constructs and claiming that they are easier to reason about seems spurious, because there still may be full fledged continuations coming with CPS. I guess this so called reasoning will only work for a limited subset of all programs.
I actually think that call/cc has the advantage of forcing people to realise what the ramifications of proper tail recursion are.
Given enough time they will replace call/cc entirely.
Buy, hey, don't take my word for it. I will appeal to authority and post this: http://okmij.org/ftp/continuations/against-callcc.html
There is a lecture by Matthew Flatt held at Microsoft research about delimited continuations where he uses a web server to show the differences of delimited vs undelimited continuations somewhere in YouTube.
Edit: btw the speed difference with regards to overhead between call/cc and call-with-prompt was something like an order of magnitude for simple things like generators and the rather well known fibcc benchmark.
https://github.com/rain-1/continuations-study-group/wiki/Rea...
Nevertheless, having some form of continuation mechanism is more in line with Scheme being a small but powerful core upon which any programming construct can be built. Sure, most programmers out there would rather express things in terms of try/catch. But the idea is not to have continuations replace try/catch, but to have try/catch expressible in terms of continuations. Then it becomes a library you load and depend on, and theoretically runnable in any Scheme implementation that supports the continuation mechanism the try/catch library uses.
* S9fes: https://github.com/bakul/s9fes
* Chibi: https://github.com/ashinn/chibi-scheme
Both are just a couple of files to add to your project, and easily extended with good built-in features.
I've also had a lot of luck embedding Chicken. It's quite straightforward to do, and with the boon of being able to compile Scheme to C to include directly.
My copy has a few plan9 specific extensions. Though more is is needed for anything like building a user level filesystem. I track Nils' original version on the t3x.org git branch.
Guile has has a very great deal of new development in recent years, including truly massive optimization.
I am curious what people who know Schemes think about how it now compares to other efforts.
So um. Yeah. Good luck wrapping your head around that. Eesh.
Out here in the real world, nobody will touch Lisp or anything remotely like it with a 10-foot pole. The real world embeds Python or Lua.
I've done 50+ diligences in the last two years, ranging from $2M to $1.5B transactions. Only two had embedded DSLs, one in lisp and one in their own language that wrote an interpreter for in C. I don't think Python gets embedded much these days to be honest, I've done it and the experience was not pleasant compared to using S7. Though I do know Lua gets used in the game industry.