I thought it was written up in their docs, but this video is what comes up when I search for "user is a function":
https://www.youtube.com/watch?v=1zj7M1LnJV4
This framing, that user input and interfaces react to changes in each other, is a nice way to think about interaction design.
Ergonomically, I find virtual DOM composition in Cycle a bit too cumbersome. Stateless components are just functions that return virtual DOM, but stateful ones need the input/output streams woven in. In practice, this means you end up doing a lot of
const statefulComponent1$ = // compose input streams here
return {
DOM: combineLatest([
statefulComponent1$,
statefulComponent2$
]).map(
([ partial1, partial2 ]) => (
{ partial1 }
// ...
)
)
}To add state to a stateless component, you've got to do a bunch of refactoring to both the component and its callsite. Instead of passing props/function arguments inline to a stateless component, now you've got to make a variable to hold your stream, pass it into combineLatest, and put a slot in your returned virtual DOM to hold its latest emission. I understand why it's this way, but I also don't like having to think about if a component has state when I'm just trying to use it.
Cycle is a nice architecture for Chrome extensions though. They do a lot of message passing between JS contexts. Because everything in Cycle is a stream, you can wrap the extension messaging API in a stream, and your extension architecture looks like any other Cycle project:
https://github.com/appsforartists/midicast/blob/develop/pack...