3

I'm developing a functional reactive programming app, in Sodium FRP and Scala, with heavy GUI-based interaction. The challenge is to program the construction of a complex graph with FRP nodes -- event Streams and state Cells. The construction proceeds in order-dependent steps, with the created objects passed on to next steps. Several domain and UI modules are involved. The process is fragile and not very functional.

It seems that the State Monad (SM) could be a good functional alternative. Indeed, several SM applications are not dissimilar to construction of object graphs, eg: https://channel9.msdn.com/Shows/Going+Deep/Brian-Beckman-The-Zen-of-Expressing-State-The-State-Monad, or Breadth-First Search using State monad in Haskell. And yet, my search hasn't produced any uses of SM for objects construction or configuration.

Specifically, I plan to split the FRP graph into subgraphs, and for each define something like

case class ConfigureSubGraph {
           inputA: Option[Stream[String]] = None
           inputB: Option[Stream[String]] = None 
           inputC: Option[Cell[String]] = None
...
           intermediateOutputs: Option[Cell[DomainEntities]] }

with the fields pre-initialised to None. (Here, Cell and Stream are from SodiumFRP.) This would be "loaded" into a State Monad and incrementally configured.

Could a State Monad work for this? If yes, is there any implementation advice? If not, are there other functional approaches to construction of object graphs (not necessarily FRP)?

schrödingcöder
  • 565
  • 1
  • 9
  • 18
  • 2
    I get the impression you're thinking in what I call [alloc-init mode](https://stackoverflow.com/a/41650746/1523776), which is not a very functional way of thinking. If you don't have a cycles in your dependency graph you can just compose the stuff directly. Adding mutable state into the system just increases the complexity. – Benjamin Hodgson Jan 11 '18 at 01:30
  • 1
    @BenjaminHodgson I need to remember that phrase :-) But how to deal with cycles? – Bergi Jan 11 '18 at 01:46
  • Absolutely. There's always the alloc-init siren to watch out for. My main concern is with tracking all the object references created in intermediate steps. It's been easy to end-up with nodes "falling-off" the FRP graph: a "reset" button not resetting, etc. I'll experiment more with direct arguments passing vs a State Monad, and update the question. – schrödingcöder Jan 11 '18 at 17:20
  • @bergi In a lazy language with mutual recursion (Haskell) you can [tie the knot](https://wiki.haskell.org/Tying_the_Knot). In a strict language you'd have to use a reference to a mutable cell. – Benjamin Hodgson Jan 12 '18 at 12:43
  • 1
    @BenjaminHodgson After refactoring and experimenting I found that a direct construction approach you suggested is indeed better. (In particular, it avoids the confusion of incompletely constructed object graphs.) Hopefully I'll be able to apply this all the way up as the app complexity grows. – schrödingcöder Jan 31 '18 at 13:22

0 Answers0