I’m busy writing my FRP book, but when I have some time again, there are FIVE issues that I want to address in Sodium:
- [Already done in the Java version.] Get rid of the sampleNow infrastructure and replace it with something much simpler. The way it was done was problematic, and we only actually need something very simple.
- Finish the renaming of Behavior -> Cell and Event -> Stream. This was urged by the publisher because of utterly different OOP meanings that ‘behavior’ and ‘event’ have.
- We need to be able to say (Java syntax):
LazyValue<Integer> x = bx.sampleLazy(); LazyValue<Integer> newX = x.map(x_ => x_ + 1); // Also applicative lift operations Cell<Integer> by = ey.holdLazy(newX);
This gives us the complete ability to use sample() with looped values where the loop hasn’t been closed yet.
- [EDIT: I probably won't do this. See below.] I would like to make it possible to have a Cell type that has no updates() or value() method, so we can make it so changes in Cells are not observable. This makes it possible to simulate continuous time without any possibility of leaks in the abstraction. Here’s what I’m thinking:
- Make it so hold() returns a subclass of Cell, called StreamCell.
- updates() and value() are defined on StreamCell only.
- We’ll also need StreamCellSink and StreamCellLoop, liftSC and mapSC methods.
- Is there a better name?
Then we get the best of both worlds: Semantic purity and convenience.
- I want to make a multi-language test case system, so that each test case is written in each language next to each other so they are easy to maintain. Run it and you’ll get a big table of language vs. test case, with a tick/cross in each square. It should be possible to use it on systems with only some of the languages installed.
If I can make these changes, then I’ll be happy that Sodium is finished. Then people can write code on a solid foundation, and in parallel people can work on performance and parallelism. We should always keep the reference implementations in each language separate from the performance/parallel implementations. Then it’s possible to easily test whether bugs are in the performance/parallel Sodium or in the application.
EDIT: updates() is needed in certain practical circumstances for normal work in non-lazy languages. An example of this is the Zombicus example described in chapter 7 of the book. The problem is that without doing this, others is a hard cyclic reference during start-up and this breaks it. StreamCell complicates the interface somewhat. Is it worth it for the benefit (waterproof continuous cells/behaviors)? I am trying to “sell” Sodium on the simplicity and practicality of its interface. I’d appreciate your thoughts.