New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cyclejs vs mercuryjs #49
Comments
MVI is a unidirectional approach, there is arrows only in one direction and they form a Cycle. That's at the core of this framework. Otherwise I'm not really familiar with mercury to point out the differences. Its documentation is very scarce and I can't see an obvious MV* architecture there. |
Mercury is immutable DAG (Directed acyclic graph). videos
Blog post about unidirectional apps and mercury: https://gist.github.com/alexmingoia/4db967e5aeb31d84847c Feel free to ask questions here or in #virtualdom on freenode. I started playing with Mercury and don't have a real world experience with it. I am not familiar with Cycle or Mithril, all I know is that Cycle is using reactive approach (RxJS) whle Mithril is interactive (something similar to view.update() inside a model etc). I believe that Mercury is also interactive but I might be wrong. |
That's a good way to describe it. Mithril has a very simple MVC (interactive, specially through the Controller) API. Cycle is completely reactive, using MVI. I don't grok Mercury that well, it has too many parts. Maybe one clear difference is that architecture with Cycle is a directed cyclic graph, while Mercury has no graph cycles. |
Mercury is very component oriented at the root of it. Generally you write applications like For example your simple.js ( https://github.com/staltz/cycle/blob/master/examples/simple/simple.js ) example is implemented as var hg = require('mercury');
var h = require('mercury').h;
function Foo(initialState) {
return hg.state({
bars: hg.array(initialState.bars, createBar],
channels: {
addBar: Foo.addBar
}
});
function createBar(x) {
return hg.struct({
id: hg.value(x.id),
bar: hg.value(x.bar)
})
}
}
Foo.addBar = function addBar(state) {
state.bars.push({
id: 2,
bar: Math.round(Math.random() * 1000)
});
};
Foo.render = function render(state) {
return h('div', state.bars.map(renderBar))
function renderBar(bar) {
return h('div', {
'attributes': {
'data-foo-id': bar.id
},
'style': {
'margin': '10px',
'background': '#ececec',
'padding': '5px',
'cursor': 'pointer',
'display': 'inline-block'
},
'ev-click': hg.send(state.channels.addBar)
});
}
};
function main() {
hg.app(document.body, Foo({
bars: [{ id: 2, bar: 135 }]
}), Foo.render);
} Some of the core ideas are:
Mercury is unidirectional because:
See more about life cycles here ( https://github.com/Raynos/mercury/blob/master/docs/life-cycles.md ). Mercury is also a hybrid of functional and imperative, the rendering logic is functional but the updating logic has an imperative updating interface (backed by a stream of immutable objects under the hood). This gives you an FRP style application written in a way that still feels like its javascript |
I also moved that comment here ( https://github.com/Raynos/mercury/blob/master/docs/introduction.md ) so other people have an easier time and @staltz can redirect them there :) |
Thanks, overall good summary of Mercury. I wouldn't probably call it a DAG, because
That shows a difference between Mercury and Cycle. "View states" in Cycle are called Models, and you can have multiple of them, with interdependencies (even circular dependencies).
Cycle and Mercury are basically the same here, although recently Cycle added support for custom elements, which means React-like components with internal state. I would assume Mercury has the same, https://github.com/Raynos/mercury/blob/master/docs/mercury-component.md, is that correct @Raynos? In other words, both frameworks encourage pure rendering, but allow hidden impure rendering when necessary. |
Also, about this:
I could say, similarly, that Cycle is a functional and reactive hybrid, with some impure shortcuts sometimes. But, Erik Meijer doesn't recommend using the term "mostly functional". |
Its not cyclic. Because there are no mutable dependencies.
You must remember that a channel is just a plain data structure. The closing of the loop happens inside the framework. This is similar to how elm closes the loop inside the runtime. the virtual-dom and dom-delegator machinery will close the loop for you, but that is completely external to your application, you should see |
Mercury is pure. The virtual-dom module is pure. There is no hidden impure rendering. The only thing that exists is that multiple things can write to the DOM. It's not just Mercury does not encourage any kind of impure rendering. Mercury components themself are actually a way to compose models in a tree, the mercury component system really allows you to compose view state, not rendering. |
Ok, that explains a lot. So, yes, Mercury apps are a DAG.
I was referring to the transient state that you mentioned with
and
Isn't that contradictory? |
I meant that the only thing that mutates the DOM in your application is Where as the latter statement means that because of reasons multiple things write to the DOM including your application and the browser itself |
Yes, understood. And the same happens in Cycle, of course |
mercury components have nothing to do with custom elements. In cycle you mentioned you can multiple models. In mercury there is one big fat view state tree. The way to conceptually have the nice modular seperation of multiple models is to use mercury components. mercury components are a way of seperating your big fat view state tree into many smaller view state trees and then finally composing them into a big tree. Mercury components are a lot more about how do I logically seperate parts of my application and a lot less about how do i share re-usable units in a framework-agnostic way (custom elements).e That being said you can use a mercury component for something that is application specific like |
It seems mercury is a more functional approach, cycle (from a glance) implements MVI but is not unidirectional (M and I interact). Clarification is welcome as well as key differences.
The text was updated successfully, but these errors were encountered: