

BBS, Lua, Coroutines: Part 2 - helium
http://sheddingbikes.com/posts/1287476854.html

======
yxhuvud
Regarding FSM's, remember that you often can split them into several FSM's if
they get too big. That reduces complexity immensily if possible.

------
pmjordan
With regard to scaling coroutines, I guess this is basically the problem that
Erlang tackles. Having zero shared state obviously solves the migration
problem. (but raises other challenges)

~~~
stcredzero
How would one do a generic copy-on-write mechanism in Lua to automatically
enforce zero shared state? (But only create copies once state has been
changed.)

~~~
pmjordan
I'm not sure you'd want to do that. Here's why:

It would surely require some fairly severe changes in the Lua runtime. It's
been 3-4 years since I touched Lua, but assuming they haven't changed that
much, the data structures themselves are a fairly simple mix of tagged C
unions with pointers to structs for arrays, objects etc.

You'd need to either run through all references in the current context and
replace them with references to a mutable copy, possibly copying whatever is
holding them as a result. This is horrible, and why you tend to use immutable,
persistent data structures for this type of thing.

Alternatively, you'd need to somehow detach identity from memory location.
Initially, object #123 is at the same position in all contexts, but if you
mutate it, it'll be copied elsewhere. When you dereference #123 in that
particular context, you will now be directed to the new location. This avoids
the dependency update chain but adds an extra layer of indirection, which will
presumably be a hashtable or so, which could impact performance quite severely
and take up a lot of memory.

You'd also need to somehow tag and track objects which are shared (and need
COW) or which can just be mutated directly.

In short, Erlang is probably the way it is for a reason. Trying to graft its
model onto another language may well produce something hideous. Don't build
your app on the assumption you'll be able to scale it later if your contexts
share mutable state.

I don't think there's a silver scalability bullet in our future. You either
start by assuming the worst case you can think of and restrict yourself to
"safe" techniques, which possibly cause you to do a lot of mental contortion
and work you wouldn't need to if you weren't going to scale. (this approach
isn't infallible either - emphasis on the worst case _you_ or the maker of
your tools _can think of_ ) Or you take the approach of ignoring scalability
for as long as you can get away with it, risking a complete rewrite when your
design falls over. Or start somewhere in between, depending on your
(predicted) needs and preferences.

Disclaimer: my dealings with Lua are some years back and weren't all that
extensive. (I most vividly remember debugging a crash that was caused by the
allocator running a GC pass under out-of-memory conditions, a feature someone
had evidently added without checking it was safe) My knowledge of Erlang is
passing at best.

~~~
stcredzero
_I'm not sure you'd want to do that. Here's why: It would surely require some
fairly severe changes in the Lua runtime._

In VisualWorks Smalltalk, I'd just start off by setting objects immutable and
using a top-level exception handler on the mutation exception. Alternatively,
one could also use forwarder proxies.

 _This avoids the dependency update chain but adds an extra layer of
indirection, which will presumably be a hashtable or so, which could impact
performance quite severely and take up a lot of memory._

For building application servers, there should be a mechanism to handle this
sort of eventuality efficiently. Such mechanisms are also very useful when
building things like Object Relational frameworks. This may be counter to
Lua's design goals towards being small and highly embeddable.

------
netghost
Lua and BBSs? Awesome. We ran a great, well, we thought it was great BBS back
in the day :)

