5 ms·
I've used cycle.js on a small commercial project. I'm drawn to novel non-mainstream approaches, and am happy to put up with teething pains with new technology.
by pickle-ts 8y ago
I've used cycle.js on a small commercial project. I'm drawn to novel non-mainstream approaches, and am happy to put up with teething pains with new technology. However, my experience with cycle.js was such that I couldn't recommend the framework to others.
Central to the understanding of cycle.js is the concept of observables. An observable is powerful abstraction, as it allows event streams to be programmable. However, an overreached abstraction can be even worse than a lack of abstraction. Cycle.js gratuitously applies the observable abstraction to its component model.
The cycle.js notion of a component is a object that takes multiple observable sources, and emits multiple observable sinks. I have to admit, at first I didn't see this as problematic: to the contrary - it actually struck me as elegant. What I didn't realize, before building a real-world project with cycle, was that this meant all interactions between components were asynchronous. So each component cannot even access the state of another component without communication via observables. This introduces enormous needless complexity into an application. Not only do you have to pay an up front mandatory boilerplate tax to minimally wire together your components, you'll tie yourself in knots readjusting that wiring to get those components to communicate with each other in the way you need.
We actually ended up re-writing the project with our own framework, pickle: https://github.com/pickle-ts/pickle https://github.com/pickle-ts/pickle For us, this substantially increased maintainability / reduced the code size of our application compared with cycle.js, or the prototype we wrote with react/redux. The code reduction came from realizing the appropriate abstraction: the entire application should be composed of an object-oriented hierarchy of stateful components, where on each update, these mutable components render themselves as immutable v-dom trees. Anyway, to counteract any pluggishness (our framework is obviously super new so is only of interest to ultra early-adopters), the conservative sensible choice for a web framework right now is to use react or vue /w a state manager. Not cycle.js.
- Tade0 8y agoWhat I didn't realize, before building a real-world project with cycle, was that this meant all interactions between components were asynchronous. [...] This introduces enormous needless complexity into an application. This hits the nail on the head. I spent a year using the author's other project - Rx.js - and while I understand the benefits of using it I don't think they outweigh the costs. And asynchronicity is especially expensive.
- staltz 8y agoTwo corrections: RxJS is not my project, I only helped as a contributor (sometimes voluntary; sometimes core). And second: stream chains are not necessarily asynchronous, in fact they are synchronous by default. I don't know what the commenter above meant with that asynchrony comment.
- pickle-ts 8y agoIt's misleading to say observables are not asynchronous. The raison d'etre of obserables is to support asynchronous operations, and it's this capability that constrains the programming model. To quote Erik Meijer - the godfather of observables - in this article https://queue.acm.org/detail.cfm?id=2169076 https://queue.acm.org/detail.cfm?id=2169076 There are many ways to derive Rx, some involving category theory and appealing to mathematical duality, but this article shows how every developer could have invented Rx by crossing the standard JDK (Java Development Kit) Future<T> interface with the GWT (Google Web Toolkit) AsyncCallBack<T> interface to create the pair of interfaces IObservable<T> and IObserver<T> that model asynchronous data streams with values of type T.
- staltz 8y agoI didn't say "observables are not asynchronous", I was referring to the comment "interactions between components are asynchronous" which to me sounds like "event emission and propagation". Propagation is often synchronous when using RxJS 6 which uses by default the recursive scheduler, and with xstream, which is similar. For instance, event emissions along the chain a$.map (f).filter(g).take(10) are synchronous. But I suppose the confusion here is what people mean with "asynchronous". To me it means a set of computations that are allowed to happen sparsely, with other computations potentially happening in between. A lot of people assume that callback-driven code in JS is necessarily async (and maybe that's what you meant with the use of the word), but it's common in the JS reactive programming community to recognize that callbacks can also be executed synchronously, for instance array.forEach(cb) is synchronous although it's callback-based and as such could have been asynchronous through the same cb API.
- staltz 8y agoI suppose you were using Cycle.js before Cycle State was released. There are a few other projects in production like yours, some of them successfully applying the framework, and others that found difficulties with state management and wiring between components. For anyone out there looking to evaluate Cycle.js for production, I recommend looking at the source code of an open source app I'm actively building: https://github.com/staltz/manyverse https://github.com/staltz/manyverse I am happy with the architecture, specially how well it manages React Native's many native APIs in a well organized way. I also need to emphasize that Cycle.js is more of an architectural framework, not much of a rendering framework, so it's not a competitor to React, you can use both together. React for rendering, and Cycle.js for architecture and orchestration.
- pickle-ts 8y agoI suppose you were using Cycle.js before Cycle State was released No, I was using cycle state/onionify. [cycle-js] is not a competitor to React That's not the impression you give in this article: https://staltz.com/some-problems-with-react-redux.html https://staltz.com/some-problems-with-react-redux.html React may be superior in ecosystem, or with feature coverage, but not so as a paradigm [compared to cycle-js]... Once you learn Elm or Cycle, getting things done will be more productive, less indirect, less verbose, more organized. Am I quoting you fairly? Have you changed your position?
- staltz 8y agoThat article was written many months/years before Cycle-React interop was built. I still maintain some of those positions because of Redux, but when you take React without Redux, it's just a rendering library, and as such could be theoretically used with Cycle.js. Now that React has good APIs like Context, ForwardRef, and function components, the interop with Cycle.js is easy and well done.
- pickle-ts 8y agoFWIW I agree with you I'm not enamoured by react/redux.
- tanilama 8y agoMobx does just that
- cageface 8y agoEvery framework or tool will go out of its way to demonstrate the things it makes easy. They usually don't mention at all the things it makes hard. Often you don't discover what those are until you've tried building something non-trivial with it, but there are always tradeoffs.
- algesten 8y agoWhat do you mean that all interactions between components are asynchronous? I've built and am maintaining a rather large chrome extension for video recording using xstream/cyclejs. I find that the thing xstream get exactly right is that stream is an abstraction of Values Over Time and not a queue of messages. It's a subtle but important distinction. xstream and by consequence cyclejs is synchronous. When a value goes into the stream, all interconnected streams ar executed synchronously.