RE: https://social.rust-lang.org/@rust/117605013073050966
I'm not sure whether I'm more excited about the stable never type, or DropGuard in std.
Which is a reminder that I'm kind of strange, since the word "allocator" didn't appear in that sentence. 🤪
@xentrac I have not worked with it but have been following it. It looks interesting.
@Moore I haven't tried installing seL4 either, but I mean, what do you think about its approach to resource management, in the abstract?
@xentrac I don't know enough to have an option but it looks interesting. The time accounting is interesting.
@Moore An interesting thing about that is that they only enable the time accounting for "mixed-criticality systems", where you're relying on the kernel to prevent your Linux virtual machine or whatever from causing glitches in your motor control waveforms or 802.11 acks.
But the main interesting thing about the kernel in this context is that it doesn't allocate memory at runtime. There's no heap.
@Moore How do you envision statically checked memory management working? Are you satisfied with Rust?
@xentrac the easiest way is to statically allocate everything but that can lead to more allocations then strictly necessary if there are two allocations that never overlap in use.
Another idea is to have an allocator as an explicit argument and add capacity to the type of the allocator and an API like:
let (value, allocator) = Box::new(allocator);
This way it would be a type error to over commit.
@xentrac Another idea is that if you have something like an event loop you can require all functions to be total and then use static analysis to compute the worst case allocation which would be easy if you used a bump allocator in the event loop. (Long lived allocations would need to be moved to statically allocated structures before returning out of the event loop.)
Really the root idea is no computer has infinite memory, so why do we write programs like they do.
@Moore perhaps by coincidence, last week I was working on a purely functional language called 5emel, which has an event loop and does its heap allocations initially with a bump allocator and then moves long-lived allocations out of the bump-allocated region. But it's the minor garbage collector that moves the surviving objects into the main heap, it features general recursion, and it's dynamically typed, so it's sort of the opposite direction from what you're talking about.
The 5emel event loop is there to make it possible to write purely functional programs that do things like read and write files. So I have programs that look like:
def main(:state, :ev) =
| Start { [:argv0, :infile, ...:args] } = ev;
Do { Open { infile, "r" },
Starting { infile, args } }
| Opened { :fd } = event;
Do { Read { fd } , Reading { state } }
and so on. The runtime invokes main() repeatedly with I/O events, and it's expected to return a Do with an action and a next state, a process which generally involves pattern-matching on the I/O event.
If it were a Total Functional Programming system, you could guarantee that it would periodically return to the event loop, and maybe do the worst-case allocation analysis there. But that would involve a static type system, and probably a dependent type system at that.
@xentrac I have built out some language experiments that make functions " trivially total" by removing recursion and unbounded iteration. So it has foreach but not for/while/ect.
The top level of a program is an explicit state machine. This means at the top level it is unbounded in scope but static in memory, which then call total event holders which are bounded in scope and memory. You can play with it here:
@Moore Ooh, this sounds really interesting!
@xentrac it is just garbage code to try out ideas.
@Moore I'll try it out!
@Moore The current version of 5emel (100% #AI output) is in https://canonical.org/~kragen/sw/5emel-m5d.1.tar.gz. Example 5emel programs include zero-dependency unzip, TrueType text rendering, PNG encodng, and the 5emel compiler.
The REPL is pretty bad; the in-browser notebook interface (build/notebook.html) and the native-code compiler are better. The build requires make, tsc, awk, node, and cc (to assemble the compiler's assembly output), and it's kind of annoyingly slow because it runs a lot of regression tests under the interpreter, which is slow partly because it's written in TypeScript. The test run is the default when you type `make`, and it takes about 15 minutes on my laptop.
The main question 5emel is trying to answer is whether automatic memoization can yield usable performance in a mutation-free eager pure functional language. This sort of presupposes a decent garbage collector and at least a basic native-code compiler, though, and those may actually matter more than the automatic memoization, and, so far, not in a good way! Programs written in 5emel are still several times slower than similarly-structured programs written in C and compiled with optimization, 8× on average, and sensibly written programs in C are typically 20× faster.
I still need to write this up properly. If you try it out, your feedback will be very valuable!
@xentrac I would be interested to look at it if you have anything to share.