Open wilzbach opened 10 years ago
The advantage of Object.observe
is that it does not require the library to be set up in any particular way. It is (will be) just a part of Javascript.
That being said: I don't believe people will ever agree on a common model. This problem has plagued developers for decades.
Unfortunately while the motivation and problem statement are correct the solution is not so easy. Trying to set up a data exchange model in biology is a monumental challenge that many have been and are working on. It is best if we (BioJS) stay away from it.
On Sep 24, 2014, at 11:44 AM, Michiel Helvensteijn notifications@github.com wrote:
The advantage of Object.observe is that it does not require the library to be set up in any particular way. It is (will be) just a part of Javascript.
That being said: I don't believe people will ever agree on a common model. This problem has plagued developers for decades.
— Reply to this email directly or view it on GitHub.
I think the described problem is a bit lower level than setting up a data exchange model for biology. This is about the basic mechanism for subscribing to any data from one module by another. If we agree on a common mechanism (and it's a big if), which format that data should have is yet another problem, likely even harder to solve.
As each component is displaying a different type of data, which different properties , I don't think an enforced object type will work. However, I would suggest to use duck typing. I would have the event receiving a single object and the receiver should validate that it contains the attributes to do the action. In that way, related components should be able to provide a minimum common set of properties to communicate. Between my components , I use a seqregion object, that has the entry , start and end encapsulated (https://github.com/homonecloco/biojs-alg-seqregion/blob/master/lib/biojsalgseqregion.js). What we could give is a guidance on standard names to be expected for common names that developers should follow if they want better compatibility. A solution for file formats that have different standard names would be to make aliases to the natural name in the file, to a standard.
Ricardo H. Ramirez G.
On 24 Sep 2014, at 10:14, Michiel Helvensteijn notifications@github.com<mailto:notifications@github.com> wrote:
I think the described problem is a bit lower level than setting up a data exchange model for biology. This is about the basic mechanism for subscribing to any data from one module by another. If we agree on a common mechanism (and it's a big if), which format that data should have is yet another problem, likely even harder to solve.
— Reply to this email directly or view it on GitHubhttps://github.com/biojs/biojs/issues/95#issuecomment-56644321.
As stated before, this is a lower level (or technical) problem. During the Munich hackathon, we agreed to use a common event structure among biojs 2.0 components and there are two main advantages from doing so :
With that said, it is also very difficult to enforce (or suggest) a developer which tools to use or how to use them so I really doubt the current approach will be adopted by the community. Perhaps Object.observe
is the way to go but it is not part of JavaScript yet and I probably won't be supported by legacy browsers.
Wow thank you all for this active discussion :)
I don't believe people will ever agree on a common model. This is about the basic mechanism for subscribing to any data from one module by another (@mhelvens) It is best if we (BioJS) stay away from it. (@gyachdav)
I know this is a very difficult topic, but in my opinion one of the key ideas behind of BioJS is that a user can combine different visualization components easily. Otherwise BioJS would be only a awesome registry with a great community and "getting started with JS + NPM" docs.
If we really don't manage to agree on a common model, we could provide a small lib that does something like my suggestion for artificial models (more sophisticated, of course).
Currently the only (well hidden) guide (see Step 4) we have have is sending one event (one-way) to another component. So whatever the outcome of this discussion will be, we would should provide better documentation (and make it easier to find).
A common model allows developers to connect components easily almost without duct tape code (@jmVillaveces)
Yep exactly that is what I try to suggest here, because only with an event system you will have this annoying glue code.
However, I would suggest to use duck typing (@homonecloco)
I created a common place (biojs-model) for those definitions. We could collect minimal schemes we agreed on there?
The main problem here would be to prevent ping-pong loops. This approach here depends on the component to send the origin encapsulated with the event.
// for simplicity every components has the same event name (without any translation)
msa.on("selection", function(data){
if(data.origin !== "commonModel"){
commonModel.set("selection", data.seqs);
}
}
tree.on("selection", function(data){
if(data.origin !== "commonModel"){
commonModel.set("selection", data.seqs);
}
}
seqLogo.on("selection", function(data){
if(data.origin !== "commonModel"){
commonModel.set("selection", data.seqs);
}
}
commonModel.on("change", function(data){
// one might translate the event here for different components
msa.setSelection({data: selection.seqs, origin: "commonModel"});
tree.setSelection({data: selection.seqs, origin: "commonModel"});
seqLogo.setSelection({data: selection.seqs, origin: "commonModel"});
});
On 24/09/14 12:10, José Villaveces wrote:
Perhaps |Object.observe| is the way to go but it is not part of JavaScript yet
For me, this only is enough to leave this option out. M;
For me, this only is enough to leave this option out.
No event system is part of Javascript right now, i.e., they all require a library of some sort.
In the case of Object.observe
, the functionality can be imported with a polyfill library. The difference is that Object.observe
will be a part of JavaScript. And as browsers start to support it natively, the application will automatically become faster (and the polyfill will become redundant).
The main question is which model we want to use. Subscribing to events or observing values.
I think Object.observe()
may not be viable in general for the reason that you're not always going to have access to model objects from other libraries. If you don't have a stable (i.e. documented) object definition, you've got nothing to reliably observe. Object.observe()
also has the limitation that you can't listen to events that don't change an observed object.
You could work around these limitations by separating the model from the third-party libraries --- in other words, creating a BioJS-centric model. Depending on what type of biological information you want to model, you may be able to reuse languages like BioPAX so that Object.observe()
makes sense to use.
A common event system is useful, but it requires the developer to define intercomponent relationships. For rich applications, this is almost always required anyway.
If you want flexibility, you'll almost certainly need to use an event system instead of Object.observe()
.
If you want to make it easier (but possibly less flexible) for developers, you need a full BioJS model that manages everything -- and this could potentially use Object.observe()
or an event system. In this case, it may make sense to reuse an existing MVC framework/lib rather than reinventing the wheel. Since it looks like you're targeting beginners, I don't think they'll care too much about your choice of framework as long as things work.
You should also consider using tools like Yeoman. That way, a dev can just specify the components he wants to use in his app and the initial app is built for him (sans business logic etc).
I've been exploring the concept of Functional Reactive Programming (FRP). It's a paradigm where 'observable events or values' become first-class citizens. This includes ways to pass, return, merge, zip, combine, fold, etc. event-streams. It's quite elegant.
Possibly the best known JavaScript FRP library is Bacon.js. We're now using it for ApiNATOMY, and it's cut down code-size, solved a few bugs and improved readability.
One way we could communicate between components is to put Bacon.js based EventStream
s and Bus
s in our public APIs. Then it's a simple matter to plug them together the way you want. There is also Property
s, which have the concept of a 'current value'. This is kind of like Object.observe
, except the interface publishing the property needs to use Bacon.js to do it.
It's quite trivial to maintain support the traditional on
, trigger
, off
, etc. with Bacon.js as the backend.
I think this is an interesting idea. However, I am worried about the learning curve in using FRP (I think it is quite an uncommon concept - especially when you are not used to FP). Furthermore, we still need people to document and list all of their EventStreams. Any than that, I am happy to discuss the Event System in the next BioJS Call.
+1 for FRP
Though there is a learning curve, I think it is relatively small compared to other concepts in compsci -- and the benefits can be substantial. Perhaps a system of rules for translating library events into Bacon.js events (or similar) could be used such that you could defer to each individual library's documentation for details. Just a thought.
Definitively interoperability between components was an aim that BioJS 2.0 should aspire to even if it is at a low level.
@Michiel @Max it would be great to see FRP in action with some BioJS 2.0 components as a proof of concept to see its feasibility.
Cheers Manny
Dr Manuel Corpas Project Leader The Genome Analysis Centre Norwich Research Park Norwich, UK
Tel: +44 1603 450 095 Fax: +44 1603 450 021 Web: http://goo.gl/ELtV4 Blog: http://manuelcorpas.com/
http://www.facebook.com/corpasgenome https://twitter.com/#!/manuelcorpas http://www.linkedin.com/profile/view?id=5414661 https://plus.google.com/u/0/101146878928866340609/
On 29 November 2014 at 17:40, Max Franz notifications@github.com wrote:
+1 for FRP
Though there is a learning curve, I think it is relatively small compared to other concepts in compsci -- and the benefits can be substantial. Perhaps a system of rules for translating library events into Bacon.js events (or similar) could be used such that you could defer to each individual library's documentation for details. Just a thought.
Reply to this email directly or view it on GitHub https://github.com/biojs/biojs/issues/95#issuecomment-64959221.
@Michiel @Max it would be great to see FRP in action with some BioJS 2.0 components as a proof of concept to see its feasibility.
You got it! ApiNATOMY is now all about the Bacon. :-)
would you like to tell us about it and perhaps show us a short demo on Thursday? Manny
Dr Manuel Corpas Project Leader The Genome Analysis Centre Norwich Research Park Norwich, UK
Tel: +44 1603 450 095 Fax: +44 1603 450 021 Web: http://goo.gl/ELtV4 Blog: http://manuelcorpas.com/
http://www.facebook.com/corpasgenome https://twitter.com/#!/manuelcorpas http://www.linkedin.com/profile/view?id=5414661 https://plus.google.com/u/0/101146878928866340609/
On 29 November 2014 at 18:35, Michiel Helvensteijn <notifications@github.com
wrote:
On Sat, Nov 29, 2014 at 7:34 PM, manuelcorpas notifications@github.com wrote:
Definitively interoperability between components was an aim that BioJS 2.0 should aspire to even if it is at a low level.
@Michiel @Max it would be great to see FRP in action with some BioJS 2.0 components as a proof of concept to see its feasibility.
You got it! ApiNATOMY is now all about the Bacon.
www.mhelvens.net
Reply to this email directly or view it on GitHub https://github.com/biojs/biojs/issues/95#issuecomment-64960958.
would you like to tell us about it and perhaps show us a short demo on Thursday?
Sure. I have to point out though, that I am by no means an expert at FRP.
Probably you also put some thoughts into using bacon.js instead of other FRP JS libraries like Kefir.js or [RX.js](http://reactive-extensions.github.io/RxJS/#Getting Started). It would be nice if you also point out why you choose bacon.js :)
@daviddao: I did put some thought into that. And here it is:
RX.js comes from Microsoft, ported from .net. I admit this already leaves a bad taste in my mouth, but that's subjective. Bacon.js was written from the ground up with JavaScript in mind, and makes up for a number of deficiencies in RX.js. Additionally, it is already a more starred library on GitHub.
Kefir.js was a serious contender. It's apparently more performant, and we might switch to it someday. However, for now it feels too new to me, and doesn't support error propagation.
There are also a number of promising extensions to Bacon.js, in the form of bacon.model, bacon.jquery and bacon.matchers.
Still, I haven't looked at the alternatives as closely as I might have. But at some point you have to make a choice and go with it. I'd certainly be happy to be convinced to switch for good reasons.
would you like to tell us about it and perhaps show us a short demo on Thursday?
It occurs to me that the way these calls take place, I can't really show anything?
Do you have a link? Otherwise you could copy screenshots into the Google Doc..
Neh. I was just going to show some code examples. I now just explained FRP and Bacon with... words. :-)
Was really nice though! :)
This is an open discussion issue. Feel free to share your opinion with us.
Problem
If one wants to combine two BioJS components that is moderately easy with events. However this glue layer doesn't scale (in my eyes).
-> imho there should be only one model for the same data so that it is very easy to combine those components and the views only update itself on changes of the model.
Technical aspects
Object.observe
allows to listen to changes of any JS object. It is native in Chrome > 36 + part of the ES 6 (with a polyfill for older browsers).set
method for every change operation. On thisset
method all events are executed.In the examples below you can see that whether the
on
method is provided by an model framework (e.g. Backbone) or one usesObject.observe(selection)
isn't so important as long as there is a common model.A list of more approaches to data binding can be found on Wikipedia.
Tricky (open): finding/agreeing on a common model
-> share you opinion/experience with us.
Example depicting the different approaches
1. using events
(for simplicity we assume the existence of
setSelection
method).2. Using a common model
a) with a JS model framework (e.g. backbone)
b) with
Object.observe