SXML became the de facto standard in the Scheme community after Oleg and others developed some powerful libraries for it, starting with Oleg's SSAX parser. SXML is also better-suited to efficient manipulation of large HTML/XML when using immutable lists.
Also, if you're looking at code examples in TFA, and thinking that, even when composing HTML using lists rather than strings, it's still susceptible to injection programming errors, then one SXML-ish improvement is:
I had an xml problem to solve at work, and used sxml to prototype solutions in CL and Guile. The CL solution was much (much) faster, but I ended up using Guile because the libraries are built in. Maybe I should try a Racket version.
It's hard to beat a skilled CL person who invests in making something fast.
But Scheme code can often be made faster, especially if you know the performance characteristics of the particular implementation.
Besides generally using good performance practices, know that Racket has some profilers that can be immensely helpful. (I once rigged up Racket's statistical profiler at the time to capture the data for each instance of certain kinds of very complicated Web requests in a production system, and used the reports to optimize the heck out of it.)
Great question. Not that I know of. (The SRFIs unfortunately aren't necessarily this.)
How it worked in the past was that people would ask or Web search as-needed, and then others would answer.
Unfortunately, with the demise of Usenet, there was fragmenting in where you had to go to ask, as a lot of people gravitated towards implementation-specific forums. For Racket (nee PLT Scheme), there was a wealth of good advise in the email lists, but at some point after hosting was moved to Google Groups, Google searches themselves seemed to stop finding many of the articles that were in Google's own archive, even when you explicitly directed the search.
I suppose the thing to do is to just ask on demand, in one of the forum for whatever implementation you're using. (The Racket community, for one, was exceedingly good at this, when I was more involved. And I suspect some of the other popular Scheme implementations are, as well.)
Almost 20 years ago I worked at company that developed a commercial product on top of MzScheme (prior to DrScheme and Racket). There was an article about it in Russian, unfortunately now only available via web archive https://web.archive.org/web/20210506123442/http://fprog.ru/2...
I've been working on porting golang's net/http and gorilla/websocket libs to Racket for the past few months (I don't like the servelet model.) Does anyone have insight into how that model might not be optimal in a Scheme enviroment or how to better optimize it?
I'm using the Racket webserver, but each page is it own rkt file. I'm using no continuations, just storing and reading everything in the hard disk. (I'm not sure it's optimal, but I prefer that approach.)
Sorry, but it's a internal website for the T.A. in the university where they can choose the building and hour to teach next semester (~500 persons).
I have a shared module for the common parts of the webpage (like footer or header), parameters for the info of the user (like name or email), some macros like for/user to iterate through the whole list of users updating the parameters, and a macro to hide all the boilerplate at the top (it probably should be a #lang, but a macro is easier to write).
Guile is absolutely amazing these days: it has a JIT for speed, superb POSIX support, plus you can dynamic-link in any functionality you need from a C library.
Racket is kind of its own ecosystem. Guile is much more intended to integrate well with a POSIX-like environment, and the GNU system in particular. I've used it for 25 years or so as a scripting language, where other people might've used Perl or Python.
It's also more easily embeddable than Racket. Many GNU programs, including GNU Make, gdb, and GNU TeXmacs, are scriptable with an embedded Guile runtime.
Where is the community and how is it? I've honestly found vanishingly small community for anything lisp. Generally I find 10 year old comments everywhere.
While I understand any of the relevant scheme communities will generally work/be the same, it does feel lonely. On the other hand, perhaps that's a good thing and can enable a (personal) return to the days of a single programmer.
Do you use your Guile scripts in production, alongside other engineers or is it mostly for small personal projects at home?
Realistically, how much data is it practical to stash inside these continuations? It seems like it could get out of hand quite quickly for non-toy examples.
If you were propagating e.g. game state, you'd still want to stick that in a db, so the continuation would just be a session id?
A continuation is a function that, when called, jumps back to a specific part of the program that was frozen (meaning current memory, the call stack, the line number). So it can't really be stored. If your game state was stored in a db, you'd still have to load it memory to perform operations on it. Those operations, if using continuations, would then stick around in memory while waiting the continuation to be resumed. If it's a multi-player game, then you'd be in real trouble as your continuation could end up with stale data.
Game state has to be propagated from the server to the client so the player knows what is happening where-as continuations as used in this article are more about avoiding this propagation (the hidden field in the example is replaced by dispatch-table tag which acts as a session id / location in the dispatch-table for finding the continuation function)
Just to clarify, continuations don't have a snapshot of the whole heap, and they can be thought of as being a snapshot of just the interpreter state for a particular execution thread (roughly the call stack and source position). If heap objects are modified between creating a continuation and calling it, then the continuation will see the modified versions of all those objects. When it comes to garbage collection, continuations keep any objects referred to in their saved call stack alive. This is similar to any other closure, but instead of keeping things alive according to lexical scope, this is more of a dynamic scope thing (it's based on whatever functions happened to call this one).
Persisting a continuation seems like it's similarly as challenging as persisting an arbitrary closure. Like usual there are things you can't really persist, for example in your call stack you might have some unwind handlers for closing files -- how do you persist file handles?
It’s certainly possible to store continuations. You just store the program counter and a copy of the stack at the point where the continuation was captured. (There may be more efficient representations - I’m just talking conceptually here.)
If you google ‘serializable continuations’ you’ll find a reasonable amount of prior art (e.g. http://wiki.call-cc.org/eggref/5/s11n). I think there has never been a good solution to versioning then against changes to the code.
https://docs.racket-lang.org/sxml-intro/
SXML became the de facto standard in the Scheme community after Oleg and others developed some powerful libraries for it, starting with Oleg's SSAX parser. SXML is also better-suited to efficient manipulation of large HTML/XML when using immutable lists.
Also, if you're looking at code examples in TFA, and thinking that, even when composing HTML using lists rather than strings, it's still susceptible to injection programming errors, then one SXML-ish improvement is:
https://docs.racket-lang.org/html-template/
https://docs.racket-lang.org/rws-html-template/