Interesting approach. Was it enough for your use case despite being quite cumbersome if you end up needing to save a bunch of different more complex instances? I mean, I imagine most dynamic objects that are the real state you'd care about will probably be allocated somewhere on the heap and be referenced from lists or pointer types. I guess this would work best for POD types like program settings and the like, so I'm curious about your setup there.
PhilipRoman|2 years ago
(rant incoming)
This is actually something that bothers me with contemporary programming languages - the huge amount of implicit state due to function calls on the stack and the way the heap is organized. I'm much more in favor of a data-oriented design where you don't get to freely allocate objects, but need to strictly organize them according to a model. I imagine this would also make formal verification a lot easier, since you have a single global coherent view of the program state, kind of like being forced to store all important program state in a database (except more efficient since it's just memory).
Ironically I've become a big fan of global variables. In my experience the classic criticism of "anything could modify anything" doesn't really hold - using globals enables me to statically analyze all usages, not to mention setting memory breakpoints becomes much easier as well - I always know what I want to watch, instead of it being some pointer that will be allocated at some unknown time, 20 stack frames away from the actual usage.
tsegratis|2 years ago
1) state machine esque predictable function stack
2) global rather than nested state
3) relational model rather than explicit memory objects
4) serialize to disk as builtin
I think
1) is a goal to aim for for the programmer, but when a stack is needed a stack is useful, so should be provided by the language
2) is a good point, encapsulation is a good support for programmers, but encapsulation in the debugger is unwanted; so hopefully the language provides easy support for this
3) Nice idea. Depends on the application domain. Maybe pointers, maybe relational is more useful depending on the situation. Formal verification, err... An excuse for pointers would be: code a solution close to the problem is best for verifying problem->solution->proof which may mean pointers, although verifying solution->proof is better for relational. A good idea to explore...
4) Unequivocal yes
gpderetta|2 years ago
It worked well with fixed size objects, although if I would do it again today I would still allow for a separate pool for variable size strings as updating the max string size was the most common change that both breaks the file compatibility and bloats the size.
The separate pool would make it more awkward to dereference the string as you can't neither use a dumb pointer nor the self offset trick but you have to pass the poll base offset explicitly (or implicitly with a global), but I think it would be worth it.
edit: thinking about it, interleaving fixed size string pools with the other objects might also work, in practice you get a persistent heap.