5 ms·
I still don't understand Guile. It makes sense as a stand-alone language implementation, but not as an embeddable one. Why isn't it re-entrant? What about multi
by oddthink 16y ago
I still don't understand Guile. It makes sense as a stand-alone language implementation, but not as an embeddable one. Why isn't it re-entrant? What about multiple interpreters? Why a C-level GC like Boehm, rather than just track your own garbage? Why scheme for an embeddable language, don't continuations make C interop hard?
Even back when they announced Guile, it seemed odd that they based it on SCM rather than on SIOD or TinyScheme.
Lua seems to be far superior for embedding. Guile seems big and invasive by comparison. It seems to be heading squarely for that awkward middle size between big/full-featured and small/light that hurt Tcl, as argued in http://journal.dedasys.com/2010/03/30/where-tcl-and-tk-went-wrong http://journal.dedasys.com/2010/03/30/where-tcl-and-tk-went-... .
- wingo 16y agoYou raise some interesting questions, and some misconceptions. It's an ugly format, but I'm going to respond point-by-point: > Why isn't it re-entrant? I'm not certain what you mean here; certainly you can call from C to Scheme to C to Scheme, and do so concurrently from multiple pthreads. > What about multiple interpreters? Like arenas? Guile doesn't do this, no. I've never understood the desire for this, either; if you want to isolate users, put them in different modules. > Why a C-level GC like Boehm, rather than just track your own garbage? Precisely for embeddability. Tracking your own garbage is hard in C. It's doable of course, but very error-prone. Guile's C API is pretty easy to use (IMO of course). > Why scheme for an embeddable language, don't continuations make C interop hard? We have continuation barriers, but it's true that our historical continuation implementation has been a stack-copying one. In 2.2 we are likely to move to a model where we just capture the Scheme stack. That said, delimited continuations are really the bee's knees. See "Prompts" in the manual for more. > Even back when they announced Guile, it seemed odd that they based it on SCM rather than on SIOD or TinyScheme. I think the thing was that folks wanted an implementation that could grow into something more substantial. Which leads to your next point: > Lua seems to be far superior for embedding. Guile seems big and invasive by comparison. The problem is that once you have a nice small language, you start to want to program more and more in it, and you end up with a nice medium-sized language. You can see that even now with Alex Shinn's Chibi. It seems to be a hump you have to grow over and then become a nice large language ;-) Lua is wonderful, and they are among the few groups I have heard of that manage to keep things small and lean. By all means, use it! But I think that in the end, most things tend towards something the size of Python, and for mostly good reasons.
- jmillikin 16y ago>> What about multiple interpreters? > > Like arenas? Guile doesn't do this, no. I've never > understood the desire for this, either; if you want to > isolate users, put them in different modules. I think he means running two interpreters in the same address space and/or thread. In Lua, a pointer to the entire interpreter state is passed around in a ``lua_State * ``, so it's easy to embed without worrying about one interpreter accidentally mucking with another. I believe Python does something similar with ``PyInterpreterState * ``. Based on the Guile API reference[1], it's not possible to safely run two Guile interpreters in the same pthread. This makes it difficult to embed in languages with alternative threading models. [1] http://www.gnu.org/software/guile/manual/html_node/Initialization.html#Initialization http://www.gnu.org/software/guile/manual/html_node/Initializ...
- oddthink 16y agoYes, that's it exactly. I've grown more and more averse to implicit state. I like that in Lua, all my interactions with the interpreter are mediated by the lua_State. If I want to run two at once, I can. If I want to store a Lua object for later use, I can stash it in there. If I want to have a globally-available state for my programs, I can implement it myself as a global. Nothing is mucking around with the call stack looking for things that "look like a pointer." A few years ago, I wanted to embed a scripting language into a monster of a multithreaded C++ application, which (oh joy) was using RogueWave threads rather than straight pthreads. I tried python, but couldn't figure out how to get the thread locking to work properly; python had its own ideas about how the threading should work. Then, I tried Lua. With Lua, I could just implement a pool of properly-initialized interpreters, then assign them out to each thread on need. It worked very well.
- gaius 16y agoTcl also does this I believe.
- oddthink 16y agoI tried to address the re-entrant/multiple-interpreters issue in my response to jmillikin, so I won't repeat it here. The GC thing is a similar distaste for "magic." I like Lua's solution of just outright forbidding anyone from having a handle on a Lua object from outside Lua. You keep a string, or a key, or something, and use that to look up the object. Yes, it's more work some times, but it simplifies the conceptual overhead. Continuations are similar. I don't want my embedded language mucking around with the C stack. If that means that I don't get continuations, that I only get escaping continuations, or that I can't jump to a continuation across a C stack boundary, then I'm fine with that. For both GC and continuations, if the abstraction were 100% seamless, that would be one thing, but if I have two libraries, both of which are playing games (either using a Boehm-like collector, or odd stack manipulation, or the like), my experience is that they won't play well together. Basically, I like embedded languages that know their place and don't get uppity and try to interfere too much with the host. Language size is hard. I understand why a language would get bigger. Scheme is good, in that it has a good solid core, and then the rest can be in optional packages and libraries. The small core + libraries combination seems like the best way to go, but I'd rather have just plain small over big. I'm embedding; most of the work is in the host program. I'd love to find a Scheme implementation that felt Lua-like, but I've not found one yet. I'll have to check out Chibi.