but this is no good, since the call stack will grow indefinitely as the game progresses.
Next attempt is to have the current state of the game represented by a function pointer, and each function returns the next function pointer - like so:
This feels workable, except that I can't get the right return types for the functions. They just grow forever - fn(), fn() -> fn(), fn() -> fn() -> fn(), etc.!
(Changing to boxed closures doesn't help - the same problem emerges.)
It feels like this approach should work, since each function is ultimately just returning a thin pointer. But perhaps the type system won't allow it.
Is there a way that this approach can work?
I'm not the best Rust expert here, but wouldn't this be a case where making use of closures and trait bounds make more sense ? Something like this (please correct my code if you notice a mistake):
That said, I don't exactly understand your design decision. What is the incentive to represent your pages as function pointers ? Correct me if I am wrong, but doesn't a Choose-Your-Own-Adventure game/visual novel work just like a state machine ? Wouldn't it be easier to implement your pages as the different cases of an Enum or with Structs and using functions to transition between pages (states) ?
This is a general solution (in many programming languages, even) to an infinitely recursive type: adding a nominal type makes it workable, because recursive data structures are a feature in almost any language that has data structures, so the compiler has to support them, and adding a function instead of a direct value doesn't especially complicate the matter.
The current simple design (functions returning function pointers) is almost certainly not what I'll end up with. I know it's going to get much more complicated - most likely the pages will be stored externally, for example. I just wanted to see if it could work.
RFC 2300 stabilized in Rust 1.32... but it just seemed natural to me for whatever reason. [1] Sorta funny, there's a lot of other pre-NLL-or-so habits I haven't kicked.
I thought maybe I picked it up from "too many lists", but a skim suggests not. ↩︎