Reactive TodoMVC

1,140 views
Skip to first unread message

Haoyi Li

unread,
Feb 22, 2014, 12:14:27 PM2/22/14
to scal...@googlegroups.com
Every time someone brings up reactive programming in the browser, I've been sure to annoyingly interject with some words about Scala.Rx, Scalatags, mumble mumble blah blah and how it could in theory be awesome. In order to prove my sanity, I have implemented a version of TodoMVC using Scala.js, Scalatags and Scala.Rx as a branch of my workbench-example-app. The relevant app code lives here, along with some glue code stitching the three libraries together, and of course a live demo.

One nice thing I think about the application code is that it looks exactly how you would write a one-off batch rendering application, and all the tracking of dependencies and splicing re-rendered things back into the DOM is done automatically.

If anyone's interested in playing with it, the project (along with the other workbench-example-app project-branches dodge-the-dots and space-invaders) is all set up for live-reloading development, so you just need to clone the repo, "~packageJS" and you're off to the races =)

Haoyi Li

unread,
Feb 22, 2014, 12:39:58 PM2/22/14
to scal...@googlegroups.com
Just for comparison (because that's what TodoMVC is all about) at 120 lines of application code in one file, this "framework" is much more concise than the bulk of TodoMVC examples. For example the BackboneJS example comprises 440 LOC spread out between 7 different files. The closest I could find is the Angular.js example which clocks in at 230 lines of code spread over 5 files. 

The loser is probably GWT, weighing in at *950* LOC spread over *14*  separate files, which answers quite nicely the question of "why do we need ScalaJS when we already have GWT"

Yann Simon

unread,
Feb 22, 2014, 2:55:03 PM2/22/14
to Haoyi Li, scal...@googlegroups.com
Hi!

there is very interesting (and it was on my personal Todo... ;)
One problem with the application: when I try to add one Todo, it
disappears immediately.

Thanks for sharing your work!
Yann
> --
> You received this message because you are subscribed to the Google Groups
> "Scala.js" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to scala-js+u...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

Haoyi Li

unread,
Feb 22, 2014, 3:27:01 PM2/22/14
to Yann Simon, scal...@googlegroups.com
Nice catch, it should be fixed now =)

Sébastien Doeraene

unread,
Feb 22, 2014, 4:29:31 PM2/22/14
to Haoyi Li, Yann Simon, scal...@googlegroups.com
This is quite remarkable. Well done!

Sébastien

olivierbl...@gmail.com

unread,
Feb 22, 2014, 8:38:07 PM2/22/14
to scal...@googlegroups.com
This is really exciting! On React's doc (<http://facebook.github.io/react/docs/reconciliation.html>) they explain that their core diff tree algo is O(n)... Here it seams that you are doing the same in O(1)!

I refactored a bit the code to make it "MVC" like: <https://github.com/OlivierBlanvillain/workbench-example-app/blob/todomvc/src/main/scala/example/ScalaJSExample.scala>. It's splitted into 4 top level objects, somewhat similarly to what is done in React: 

Model: Definitions, likely to be shared with the server.
State: All the `Var`s, the mutable state.
Components: All the `Rx`s, html components that are autoupdated when the state changes.
Controller: User actions, modify the state.

This improves a bit the readability, and could allow to test things separately. (I have no idea if anyone does that, but it is a selling point of Angular/React...)

After playing around with the code (the livereload + sbt output in the console makes it better that any IDE I've used), I have a few questions:

- On L80, why is `task.txt()` inside a Rx? (And why not, for instance, `if(task.done()) `class`:="completed"...` L70?)
- Regarding the `Rx{ for(task <- tasks()) yield Rx{` construct (L62, L65), does it leaks memory?
- Any idea why things get rendered a lot of time with the "toggle-done" button? If you add some tasks (say up to 20), this action takes a really long time to complete.

Cheers,
Olivier

Haoyi Li

unread,
Feb 22, 2014, 8:53:52 PM2/22/14
to olivierbl...@gmail.com, scal...@googlegroups.com
I'm not super familiar with how react works, but my impression is that they diff two states and make changes based on the diff. What Scala.Rx does is that it propagates changes into the DOM, so the parts which don't change aren't even considered. 

I don't feel strongly about splitting it into 4 objects to make it MVC like. It's just shuffling things around =) I rather like the way that as it stands, it basically mirrors exactly how a batch renderer would look like.

On L8, task.txt() is inside an Rx() because when a Rx (such as task.txt) changes, it gets caught and bound by the closest enclosing Rx. As it stands, only that label of text would update, whereas without the enclosing Rx the entire Todo including the X button and tick buttons would re-render. Although Rx{task.txt()} could probably be refactored into simply task.txt, since it would be the same thing.

If you wanted to, you could remove all the "internal" Rxs in the Scalatags snippet and put one big Rx{} around the whole thing, and then the whole page would re-render when something (anything) inside changes.

L62-L65 shouldn't leak memory, AFAICT. I set it such that the Rxs embedded in the Scalatags fragment get killed when the fragment is removed from the DOM, and the outer Rx at line 62 is top-level and only gets created once.

Someone else has reported (and I have repro-ed) it slowing down massively when it gets to 20-30 TODOs, which is probably a bug somewhere rather than a fundamental limitation of the system. It looks like I'm re-rendering every Todo unnecessarily even when they don't change. Definitely fixable.


--

Haoyi Li

unread,
Feb 22, 2014, 8:57:50 PM2/22/14
to olivierblanvillain, scal...@googlegroups.com
If you're interested in the subtleties of how Rxs work and their execution/memory/GC model, my Scala.Rx page has a really nice writeup (https://github.com/lihaoyi/scala.rx#execution-model). Apart from that, there's the kinda-tricky stuff in Framework.scala, and that's it. Scalatags is dead simple to understand. 

Haoyi Li

unread,
Feb 22, 2014, 9:06:02 PM2/22/14
to olivierblanvillain, scal...@googlegroups.com
Actually, it looks like you're right: it does seem to leak memory, not to mention CPU usage, since the inner Rx gets re-created and although I kill the Obs here, the Rx still hangs around. Killing it too would probably stop the leakage of both these things.

Haoyi Li

unread,
Feb 22, 2014, 10:06:55 PM2/22/14
to olivierblanvillain, scal...@googlegroups.com
It turns out that the perf problems on the "mark all as completed" button was O(n^2) behavior due to setting each thing complete individually. I have since fixed that, and removed all nested Rxs for now until I can better think through how to avoid memory leaks in ScalaJS (in ScalaJVM it's all solved by weakrefs). AFAICT, all perf problems have vanished. 

I'll probably push some of the utility methods (e.g. multi-set, and the UnitModifier) upstream to their respective libraries at some point.

olivierbl...@gmail.com

unread,
Feb 23, 2014, 4:30:32 AM2/23/14
to scal...@googlegroups.com, olivierblanvillain
Thanks for the explanations!

>> I'm not super familiar with how react works, but my impression is that they
>> diff two states and make changes based on the diff. What Scala.Rx does is
>> that it propagates changes into the DOM, so the parts which don't change
>> aren't even considered.

This is also what I've understood, instead of tracking dependencies between
components and state like you do with Vars and Rxs, it more "let's do the
changes and see what appends". But I like the way of they formulate/organize
things: the application is organized in components, functions taking as input
the application state and producing HTML. Every change on the state triggers
the generation of a virtual copy of the entire page (I guess it's optimized so
not all components are regenerated, but that's the idea) which is then diffed
with the actual page to find changes that need to be propagated to the DOM.

>> I don't feel strongly about splitting it into 4 objects to make it MVC
>> like. It's just shuffling things around =) I rather like the way that as it
>> stands, it basically mirrors exactly how a batch renderer would look like.

I see how this conciseness can be appealing, and this might be solved with
naming convention (I've found the filters/filter variables confusing at first),
but I think that mixing in Scala, Scala.Rx, ScalaTags into a single block of
code makes it scary for people that have not designed 2 of the 3 ;). Also it
defeats one of the purpose of the TodoMVC exercise, which is to show how code
can be organized on a simple example in way that is suitable for a large
complex application (I don't claim that my split does this but it was the
intention...).

Regarding memory management, do you think the JS WeakMap could be of any use?
It's at experimental stage, but apparently back-portable to IE9+

Haoyi Li

unread,
Feb 23, 2014, 4:41:03 AM2/23/14
to olivierblanvillain, scal...@googlegroups.com
Also it defeats one of the purpose of the TodoMVC exercise, which is to show how code can be organized on a simple example in way that is suitable for a large complex application (I don't claim that my split does this but it was the intention...).

I dispute the fact that shuffling things around and adding indirection makes things simpler =P. Instead of variables rendering a page which auto-updates, after splitting now people need to care about things like "models" and "views" and "controllers" and draw arrows between them, and all that. In reality, all you want to do is take some data and render the page and keep it in sync, and I think semantically my layout matches that idea the most closely. 

I've worked with this style up to about 3kLOC before and it scales reasonably nicely, so I'm guessing its just unfamiliarity with the ScalaTags syntax more than the structure. After all, this top-to-bottom rendering of pages has been how PHP pages have been rendered since forever.

Regarding memory management, do you think the JS WeakMap could be of any use? It's at experimental stage, but apparently back-portable to IE9+

No, it is of no use, as it is not iterable, so cannot be used for the forward references I need to propagate changes. We need real weak references, otherwise we have to basically fall back to manual memory management with .kill. So much for 50 years of technical progress.

Marcus Heese

unread,
Feb 23, 2014, 8:41:20 AM2/23/14
to scal...@googlegroups.com
This is a perfect nice example, and I also just recently worked through the Angular.js one (which I thought is already pretty cool), but I have to admit that this one is far superior! And it really explains well, why we need Scala.js and not some other bloated Java library. Good example for advertising for Scala.js! Big thumbs up from me!

Anton Kulaga

unread,
Feb 23, 2014, 2:20:32 PM2/23/14
to scal...@googlegroups.com
> I also just recently worked through the Angular.js one 

I personally prefer Batmanjs as (in my opinion) it is better designed and less verbose (it has only 91 lines of code for TODO app https://github.com/tastejs/todomvc/blob/gh-pages/labs/architecture-examples/batman/app.coffee ) than Angular. But I would switch to ScalaJS when there will be nice data-finding framework there, and I think some ideas can be borrowed from Batmanjs, for instance I like how they did databinding http://batmanjs.org/docs/api/batman.view_bindings.html ( I mean data-propertyName="value" like syntax) and how they abstracted models from storage adapters.

Haoyi Li

unread,
Feb 23, 2014, 8:15:55 PM2/23/14
to Anton Kulaga, scal...@googlegroups.com
Don't forget to add the +80 lines of HTML into the batman.js example's count, since that's part of the complexity of the application that in ScalaJS is counted as part of the code. That said, batman.js does look quite nice and there could be some good ideas to steal from it.


--

che...@alpinenow.com

unread,
Feb 24, 2014, 12:07:41 PM2/24/14
to scal...@googlegroups.com
This is really cool. 

I am starting to experimenting with this. The more I read, the more I like it, I can see it shows a lot of potentials for different types works. 

Well done. 

Chester

Alexandru Nedelcu

unread,
Feb 25, 2014, 5:40:28 AM2/25/14
to scal...@googlegroups.com
Hi Li Haoyi,

This sample is awesome and got me really excited about Scala.js.

I do think I found a bug happening in both Chrome and Firefox.  After you remove all tasks from the list, the "What needs to be done?" field becomes unclickable.

I do worry a little about the size of the compiled code. The optimized version of this app is 404K, or 88K. I guess that's OK, given that it uses a lot of libraries under the hood, but do you know if there are more aggressive optimizations planned?

Sébastien Doeraene

unread,
Feb 25, 2014, 7:36:16 AM2/25/14
to Alexandru Nedelcu, scal...@googlegroups.com
Hello,

I'm working on more aggressive optimizations: https://github.com/scala-js/scala-js/issues/292

Cheers,
Sébastien


--

Alexandru Nedelcu

unread,
Feb 25, 2014, 7:41:34 AM2/25/14
to Sébastien Doeraene, scal...@googlegroups.com
On Tue, Feb 25, 2014 at 2:36 PM, Sébastien Doeraene <sjrdo...@gmail.com> wrote:
I'm working on more aggressive optimizations: https://github.com/scala-js/scala-js/issues/292

That's awesome Sébastien.

Cheers,


--
Alexandru Nedelcu
www.bionicspirit.com

PGP Public Key:
https://bionicspirit.com/key.aexpk

Haoyi Li

unread,
Feb 25, 2014, 10:43:09 AM2/25/14
to Alexandru Nedelcu, scal...@googlegroups.com
Yeah, I found that bug too. It's something wrong with the CSS causing the thing to get covered; nothing to do with the scala/javascript =P

The compiled code is a bit large, but when you consider many famous websites have payloads 3-5x that, paying a large chunk for a solid language/standard library isn't *too* terrible, especially since the rest can be super-minified by the closure compiler. @sjrd says he has ideas for better DCE which I await eagerly =P


--

André Luiz Carvalho

unread,
Feb 25, 2014, 7:39:50 PM2/25/14
to Haoyi Li, Alexandru Nedelcu, scal...@googlegroups.com
Hi Li Haoyi,

What IDE do you use for development? This example won't import on IntelliJ 13 CE as it is.

I've found out that scala-js-workbench sbt plugin does not play nice with IntelliJ. By removing it I can import the project successfully in IntelliJ.

Since IntelliJ's Scala and SBT support is still in development, I don't know who's fault is it.


André Luiz Carvalho
CTO | Pinuts

Anton Kulaga

unread,
Feb 25, 2014, 7:44:18 PM2/25/14
to André Luiz Carvalho, Haoyi Li, Alexandru Nedelcu, scal...@googlegroups.com
It would be great if you create an issue in IDEA bugtracker ( http://youtrack.jetbrains.com/dashboard ) and we will vote for it. According to my experience ( I reported about 10 bugs there) they fix >50% of the issues reported


--
You received this message because you are subscribed to a topic in the Google Groups "Scala.js" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/scala-js/DtRyjfD6qqA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to scala-js+u...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.



--
Best regards,
Anton Kulaga

Haoyi Li

unread,
Feb 25, 2014, 7:52:24 PM2/25/14
to Anton Kulaga, André Luiz Carvalho, Alexandru Nedelcu, scal...@googlegroups.com
I've been using the sbt-idea plugin, which generates the IntelliJ project definition for you and in my experience is pretty good. The intellij importer's made some progress, but isn't quite there yet.

Alexandru Nedelcu

unread,
Feb 26, 2014, 1:19:36 AM2/26/14
to André Luiz Carvalho, Haoyi Li, scal...@googlegroups.com
On Wed, Feb 26, 2014 at 2:39 AM, André Luiz Carvalho <an...@pinuts.com.br> wrote:
What IDE do you use for development? This example won't import on IntelliJ 13 CE as it is.

I also noticed that, but generating the project with sbt-idea from a sbt console works fine. IDEA's integration with SBT is still beta quality, since it just happened in version 13.

André Luiz Carvalho

unread,
Feb 26, 2014, 9:41:46 AM2/26/14
to Alexandru Nedelcu, Haoyi Li, scal...@googlegroups.com
Great! Thanks!

André Luiz Carvalho
CTO | Pinuts



André Luiz Carvalho

unread,
Feb 26, 2014, 5:00:24 PM2/26/14
to Alexandru Nedelcu, Haoyi Li, scal...@googlegroups.com
I'm trying to make use of this example to build another application. I have the following code, which is supposed to render my sections and highlight the current one:

    navbar.innerHTML = Seq(
      div(`class` := "navbar-collapse collapse")(
        Rx{
          ul(`class` := "nav navbar-nav navbar-left")(
            for (sect <- availableSections) yield {
              li(if (currentSection() == sect) `class` := "active" else (),
                a(href := "#", sectionNames(sect))
              )
            }
          )
        }
      )
    ).mkString

But I get this compilation error:
type mismatch;
[error]  found   : Array[scalatags.HtmlTag]
[error]  required: scalatags.Modifier
[error]             for (sect <- availableSections) yield {
[error]                       ^
[error] one error found

Could someone, please, help me identify what I'm doing wrong?

Haoyi Li

unread,
Feb 26, 2014, 5:05:46 PM2/26/14
to André Luiz Carvalho, Alexandru Nedelcu, scal...@googlegroups.com
Looks like the problem is implicit conversions not stacking; what id you do availableSections.toSeq?

André Luiz Carvalho

unread,
Feb 26, 2014, 5:17:44 PM2/26/14
to Haoyi Li, Alexandru Nedelcu, scal...@googlegroups.com
That was it! Thank you very much!

Egon Nijns

unread,
Feb 27, 2014, 2:35:10 PM2/27/14
to scal...@googlegroups.com, Haoyi Li
Hi,

I'm running into a couple of issues when trying to play around with this.
Since I'm on windows the first roadblock was https://github.com/sbt/sbt/issues/895
But after creating some of these directories myself I got a bit further, but now I'm running into the following compilation error from sbt:
"\workbench-example-app\build.sbt:4: error: object lihaoyi is not a member of package com
import com.lihaoyi.workbench.Plugin._"

So it seems as if sbt didn't compile the required workbench sbt plugin first.

Any ideas on how to resolve this issue?

egon.

Haoyi Li

unread,
Feb 27, 2014, 2:36:43 PM2/27/14
to Egon Nijns, scal...@googlegroups.com
Looks like SBT pulled down and cached an old version of the github repo, and doesn't update it automatically when it changes. Try killing all the cached repos in ~/.sbt/0.13/staging and see if that solves the problem

Egon Nijns

unread,
Feb 28, 2014, 7:17:34 AM2/28/14
to scal...@googlegroups.com, Egon Nijns
Hi,

after some twiddling I got everything up and running.
I think I'm now running into a usability issue with the way the code is structured.

             val inputRef: DomRef[dom.HTMLInputElement] = new DomRef[dom.HTMLInputElement](
                  input(
                    `type`:="text",
                    value:=task.storyPoints().toString,
                    style:="display: inlne",
                    onchange <~ {
                      task.storyPoints() = inputRef.value.toInt
                    }
                  )
                )


makes the compiler complain about forward references.

What's the best workaround? I don't really like how you depend on form submit to workaround this issue elsewhere...

egon.

Haoyi Li

unread,
Feb 28, 2014, 10:47:29 AM2/28/14
to Egon Nijns, scal...@googlegroups.com
Making it a lazy val should work


Anton Kulaga

unread,
Mar 2, 2014, 6:29:46 PM3/2/14
to scal...@googlegroups.com, Egon Nijns
I think if several ideas will be connected together there can be cool fronted scala framework that will beat Angularjs, Batmanjs and all current MVC frameworks in terms of expressiveness and ease of use (I only started dealing with scalajs so I apologize beforehand if I get some basic things wrong here)

In my opinion they are:
1) Front-end data-binding (+front end dataflow). I think batman-like conventions can be useful there, in other words something like <div data-bind-attribute="property.subProperty" data-view="ViewClass"> may look natural in html code as it looks like ordinary HTML5 property
2) Rx Var's as accessors to bind to. So, html bindings bind to some scalajs Rx variables and whenever they change, html also changes. Some internals of data-binding can also be done with Rx.
3) ScalaJs actors can be used to move the data to and back to the client in a natural ask/tell way (as well as between clients in case of shared webworkers or webrtc if it will be implemented). In case where websocket connection has not been established yet, ajax requests can be used to deliver messages in a similar way as actor.ask and return Futures as results. Maybe kind of "ajax-like protocol" can be used where routings like PUT /actorName/:message routings will be used by scalajsactor when websocket connections has not been established and ajax is used instead? /* I am sorry but I have not learned scalajs actors yet, maybe something like this is already supported).
4) Dynamic view fetching (mostly for widgets that are dynamically loaded by users). You define something like <div data-view="/pathTo/myView" and scalajs will fetch the view via websocket or ajax.
5) Models. 
6) ViewModels ( design pattern http://en.wikipedia.org/wiki/Model_View_ViewModel ). I have some doubts about relying much on controllers in their traditional way where there is one main controller for the page that controls everything. I think that in many usecases there can be a lot of widgets often loaded dynamically by user via ajax/websocket, so viewmodel pattern (esp. taking into considerations usage of RX for databinding) can provide better flexibility.

P.S. Probably my proposals is too much inspired by Batman,

Li Haoyi

unread,
Mar 3, 2014, 4:32:11 PM3/3/14
to scal...@googlegroups.com, Egon Nijns
Lots of cool ideas; I'd love to see what you can come up with =) There's a ton of unexplored design space that's just opening up now the Scala.js is maturing. 

Michael Donkhin

unread,
Mar 4, 2014, 3:55:10 AM3/4/14
to scal...@googlegroups.com, Egon Nijns
I believe Scala provides an opportunity to make the things differently. The MVC and MVVM patterns, data binding in its classic form are good for the conservative approaches, probably here something completely different is required.
Actors on both client and server could result in a truly distributed application, where the whole concept of client/server separation becomes less significant and maybe even configuration-dependent. More in line with Meteor, but backed with the power of JVM?

Now, I'm not a web developer, but my wild dream is to program for web as you would for the desktop, and I think Scala.js is something which can result in such an outcome :)

Alexandru Nedelcu

unread,
Mar 4, 2014, 11:27:26 AM3/4/14
to Michael Donkhin, scal...@googlegroups.com, Egon Nijns
On Tue, Mar 4, 2014 at 10:55 AM, Michael Donkhin <michael...@gmail.com> wrote:
Actors on both client and server could result in a truly distributed application, where the whole concept of client/server separation becomes less significant and maybe even configuration-dependent. More in line with Meteor, but backed with the power of JVM?

Is it just me, or does anybody else hate actors? I mean, they are fine as light threads with attached queues, but modeling stuff around actors becomes so painful and dirty. I would be excited about using actors in Scala.js for dealing with web workers. That would be sweet.

Haoyi Li

unread,
Mar 4, 2014, 11:30:20 AM3/4/14
to Alexandru Nedelcu, Michael Donkhin, scal...@googlegroups.com, Egon Nijns
On the large they're pretty nice. They basically reify the 

/** THESE METHODS SHOULD ONLY BE CALLED ON THE UI THREAD */ 
/** THESE METHODS SHOULD NEVER BE CALLED ON THE UI THREAD */ 

pattern that you see everywhere. They're basically locks that you can't get wrong, i.e. you can't "forget" to take the mutex when doing something since the actor will mutex for you.

On the other hand they're a pain in the ass when working in the small. Fork-join concurrency using futures is a million times easier to use. And better typed too.




--

Anton Kulaga

unread,
Mar 4, 2014, 1:25:40 PM3/4/14
to Haoyi Li, Alexandru Nedelcu, Michael Donkhin, scal...@googlegroups.com, Egon Nijns
>, data binding in its classic form are good for the conservative approaches, probably here something completely different is required.

It would be nice to know your opinion which approaches should be used instead of databinding. In my opinion databinding is rather convenient as its separates representation from business logic. You can even ask an ordinary webdesigner to design html templates for you with databindings (as they look like ordinary html props, nothing to learn) and you will concentrate more on underlying logic.

Today it is common to do databindings in a reactive way, for instance in C# with ReactiveExtensions people define Drag & Drop like  "var q = from start in mousedown from pos in mousemove.StartWith( start  ) .TakeUntil( mouseup ) select pos;"  There is a port of Reactive extensions to Java/Scala but I think that Scala.Rx is much better and much more powerful. If html binding will create rx.Vars to subscribe to, developers will be able to do a lot with them.


--
You received this message because you are subscribed to a topic in the Google Groups "Scala.js" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/scala-js/DtRyjfD6qqA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to scala-js+u...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.

Anton Kulaga

unread,
Mar 4, 2014, 1:34:16 PM3/4/14
to Alexandru Nedelcu, Michael Donkhin, scal...@googlegroups.com, Egon Nijns
>I mean, they are fine as light threads with attached queues, but modeling stuff around actors becomes so painful and dirty. 

With actors you can just  connect via websocket and then send messages without carrying about annoying HTML routing.

>I would be excited about using actors in Scala.js for dealing with web workers. That would be sweet.

I think WebRTC actors would be much sweeter


--
You received this message because you are subscribed to a topic in the Google Groups "Scala.js" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/scala-js/DtRyjfD6qqA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to scala-js+u...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.

Haoyi Li

unread,
Mar 4, 2014, 1:36:51 PM3/4/14
to Anton Kulaga, Alexandru Nedelcu, Michael Donkhin, scal...@googlegroups.com, Egon Nijns
With actors you can just  connect via websocket and then send messages without carrying about annoying HTML routing.

That's not unique to actors though =P You could easily set up Futures or Async to do function calls without worrying about annoying routing too.


You received this message because you are subscribed to the Google Groups "Scala.js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-js+u...@googlegroups.com.

Michael Donkhin

unread,
Mar 4, 2014, 2:22:18 PM3/4/14
to anton...@gmail.com, Haoyi Li, scal...@googlegroups.com, Alexandru Nedelcu, Egon Nijns

Data binding is a fine idea... for stateful frameworks. You usually have a view-model and a coupled view, sharing the state. However, I don't think that something else, but view, should hold a state in a reactive framework. Because of that, the concept of data binding, in its current meaning, has less appeal. I don't argue that view should not be separated from its BL, but some other mechanism could provide the means to communicate the rendering change requests to the view.
Of course, it's just my opinion, and anybody has the right to disagree :-)
And, BTW, the Drag&Drop example, IMHO, is completely view logic, not BL. In this case I would like to see some pluggable mechanism, similar to WPF attached behaviors, but less verbose. QML solves the verbosity nice with pieces of JS, embedded into a markup, but it isn't designer-friendly.

Anton Kulaga

unread,
Mar 4, 2014, 2:52:01 PM3/4/14
to Michael Donkhin, Haoyi Li, scal...@googlegroups.com, Alexandru Nedelcu, Egon Nijns
Taking into consideration that moving data between frontend and backend takes time and bandwidth I think it is ok for the front-end of interactive app to be stateful and cache some changes in the LocalStorage (of course if states are managed property with FiniteStateMachines or something similar).

Michael Donkhin

unread,
Mar 4, 2014, 2:59:07 PM3/4/14
to anton...@gmail.com, Haoyi Li, Alexandru Nedelcu, scal...@googlegroups.com, Egon Nijns

Still, I don't consider cache to be a part of the business logic. :-)

Alexandru Nedelcu

unread,
Mar 4, 2014, 4:26:13 PM3/4/14
to Michael Donkhin, anton...@gmail.com, Haoyi Li, scal...@googlegroups.com, Egon Nijns
On Tue, Mar 4, 2014 at 9:22 PM, Michael Donkhin <michael...@gmail.com> wrote:

Data binding is a fine idea... for stateful frameworks. You usually have a view-model and a coupled view, sharing the state. However, I don't think that something else, but view, should hold a state in a reactive framework. Because of that, the concept of data binding, in its current meaning, has less appeal. I don't argue that view should not be separated from its BL, but some other mechanism could provide the means to communicate the rendering change requests to the view. 

Btw, Rx in general (and I'm talking about Rx.NET, RxJava, RxJS) is all about dealing with streams of events asynchronously. It's not about persisting state, although you can do that in response to triggered events, but about piping, transforming and reacting to events. If a reaction to an event is setting some state or transforming some DOM element, that's another thing entirely, but the concept of Rx is more general than that and data binding between a model and a view is just one use case.

You wrote about actors in another message, however I don't like the flow of messages that usually happens between actors. Usually there's an actor that wants to trigger some sort of event, but it has to send it somewhere, as in, the destination for that message must be known. It's a push model, rather than a pull one that leads to tight coupling and things that don't compose well. And lately, after getting sick about dealing with a very complex actors system, I've began to think that in many instances what I really want is a channel on which events are flowing with subscribers that can tap into that channel and react. That's a less coupled model, because instead of sending a message from A to B, the alternative is if A sends a message to a channel and B listens on that channel filtering for A's messages. If done right, the result is a more composable, less coupled system.

Michael Donkhin

unread,
Mar 4, 2014, 6:10:12 PM3/4/14
to Alexandru Nedelcu, Haoyi Li, scal...@googlegroups.com, anton...@gmail.com, Egon Nijns

So, vert.x instead of akka?

Ngoc Dao

unread,
Jan 23, 2015, 4:02:20 AM1/23/15
to scal...@googlegroups.com
This demo is impressive!
I'm learning Meteor.js and I'm wondering how to implement something similar in Scala.

I have thought about using actors on both client and server,
but something like this demo is much easier to write for app developers.

Is there already a way to do the below feature?

val a = Var(1);
val b = Var(2)
val c = Rx{ a() + b() }

Where:
* "a" is on client side
* "b" is on server side
* "c" is on client side?

That is, changes can be pushed seamlessly between client and server.

I'm the creator of the web framework Xitrum (http://xitrum-framework.github.io/)
and I'd like to implement feature like this to Xitrum.

I'm new to Scala.rx.
Can you give some instruction about what should I do to implement the feature?
I guess I should use Scala.rx observers to catch the change and send it between client and server.

Xitrum already has SockJS feature,
It can be used to implement the data sending.

Justin du coeur

unread,
Jan 23, 2015, 8:26:22 AM1/23/15
to Ngoc Dao, scal...@googlegroups.com
At this point I don't think it would be crazy-difficult to implement client/server reactivity like that, but I don't believe anyone's formally put the pieces together into a single framework yet.

How you'd do it kind of depends on how plug-and-play you want it to be.  The thing about a general framework like you're talking about is that it always constrains the problem space, but how *much* is somewhat up to the designer.  For instance, there are multiple different web frameworks for Scala, and I suspect you'd build this differently depending on whether you wanted it to work with any of them, or wanted something that would Just Work in, eg, Spray.

Also, serialization is a non-trivial question.  A lot of us are using upickle to serialize our client/server APIs, but that requires having a well-defined API that is known at the point of serialization.  That might or might not be good enough for your purposes, depending on your overall vision of the thing.  One way or another, you need a serialization strategy at both ends, and which serializer you work with would depend on how you want the applications to work.

Overall, I'm pretty sure it *can* be done, but I don't think there's a single most-obvious architecture -- the details of how you build it depend a lot on how you want the application code to look.  I'd recommend working some use cases in more detail, and come up with a clearer idea of what you'd like to see here, to help drive the technical decisions...

--
You received this message because you are subscribed to the Google Groups "Scala.js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-js+u...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages