Wednesday, May 14, 2014

Dangers of react and VirtualDom

This is a brain dump from a Twitter/IRC discussion with @panesofglass and @bryanedds.

So there is this brand-new thing called Facebook React and hype wave about Virtual DOM. I only skimmed this library, but here are some reasons why I remain sceptical:

  • Identity! Typical DOM trees are a lot more than the markup. They are full of pieces of state that are *opaque* - abstract types, and *mutable*. This is especially true if you use 3rd-party libraries, but even with vanilla DOM, input tag, once rendered, interacts with the user and updates its focus state, the position of the cursor, and so on. Can all of it be captured in a snapshot as a pure value? Does React do this? I will be interested to find out.
  • If the answer is yes, I would be interested in playing more with VDom. Taking this as a foundation for design, means you throw out all other UI libraries (Ext JS, Kendo, etc). It is like a campaign to rewrite the Internet, without mutable state. But who cares - still might be interesting.
  • WebSharper Formlets library we designed with Joel Bjornson a while back assumes the answer is NO, so it does work with third-party libraries. The cost is some care is taken to manage identity of things. As far as change propagation through a tree on *pure* values, hey, we have done that in Formlets too, there is nothing too magical there. There are some nasty things when you do higher-order combinators, such as "Formlet.Many", and we try to do a sensible thing but I am not entirely confident in the theory. Loic Denuziere can comment on Piglets better than I can, but I think is quite similar as far as VDom aspect is concerned.
  • Formlets do not have or need a Diff function. You only need a Diff function if you describe transformations from a Model type to your UI type (VDom or what have you) as functions. If you have combinators with more structure, this can be done implicitly. Check the source.
  • Before, managing identity made me feel really bad. Am I a functional programming or what? These days, I am slowly accepting the concurrent paradigm. This is a different worldview, where process calculi (Pi, CSP) play a foundation similar to lambda calculus in FP. The paradigm makes working with identity essential, natural, and effective. Excellent fit for the world of UI!
  • There is also the Dataflow/FRP paradigm. I tried a few times, but my brain is still to small to digest it. Things get quite crazy when you allow dynamic switching combinators Signal (Signal t) -> Signal t. So, in this space I most sympathize with the Elm language which, from my limited understanding, seems to take a stand and prohibit such combinators, or in fact even possibility of constructing a type Signal (Signal t) in its type system. Looks like a great design, cleaner implementation and many useful things you can build. Some Haskellers though claim that the more general design is a "solved problem". Perhaps.
  • Self-Adjusting Computation was recently pointed out to me. I am still working through the paper. Looks highly relevant.
  • What would I like for Formlets/Piglets vNext, given time? Mostly, I would like a solid *model*, one that even I can understand and explain, that gives a meaning to what is going on, and is reasonably cleanly mapped to the implementation. For that, looks like I still need to catch up on some studying.

Chat logs:

#websharper on Freenode

Friday, April 18, 2014

Does syntax matter? Or how I started progrmamming.

How I started programming: well there was some Basic, Pascal and PHP, but I started getting serious only after encountering and trying to understand Haskell, while doing grad school for an unrelated subject. Haskell challenged me, somehow. It looked like nothing I have seen before. And playing with it had that feeling of figuring out a puzzle.

How I found Haskell: going through the list of languages that Kate or some such editor supported highlighting for. Yeah, I know.. In alphabetic order.

F# was not on the radar then, but OCaml was. I looked at it (among with Python, Ruby, you name it). I remember thinking a couple of things:

1. Syntax looks so painful
2. How do I use these command-line tools?? (it is better these days with ocalmbuild)
3. It has objects - must be another PHP-like disaster of a language
4. Given 1-3, no point in learning it

Huge mistake. OCaml is a gem. But you can see how a beginner might miss the point.

So for all good languages out there - I guess syntax does not matter that much, but great documentation does. If the syntax is strange, but the documentation explains why the language is worth learning nonetheless, a beginner might stick with it.

Friday, March 14, 2014

Concurrent ML and HOPAC

One of these days I got a hold of a copy of Concurrent Programming in ML by John Reppy, an excellent book. One of the many virtues: it is the missing documentation piece for Concurrent ML (CML) system, explaining design motivations and giving helpful examples.

I wish it was in open domain. Why? Simply to push CML design further, bring more attention to it. It is so much better than what is being commonly used. This is not to say that there is no space for other concurrency abstractions. But the CML has the advantage of offering a small set of features from which all other useful abstractions are easily built. I cannot do a better job than the book for advocating CML, but I particularly like:

  • Simple to understand semantics - programs in PI or other process calculi map very closely to CML code
  • Makes it easy to build other abstractions - asynchronous communications, locks, buffers, reactive systems, you name it
  • Selective communication seems VERY important
  • Plays well with ML-style languages (my favorite)
  • Admits moderately efficient implementation - should frequently be good-enough for production, and definitely excellent for prototyping

In a tweet I mentioned that having the book in open domain would "help fight actor/reactive nonesense" and was asked to elaborate. So here are some statements I came to disagree with:

  • Concurrent software should be written exclusively with Erlang-style asynchronous message-passing
  • It should be written with reactive systems of RX/IObservable flavor
  • It should be written in the FRP paradigm
  • F# has excellent support for concurrency, it provides `async` and "actors"..

Obviously, Erlang-style message passing, reactivity, and carefully designed FRP systems (such as Elm language, AFRP) are all good for certain problems. RX/IObservable systems, IMHO, are a net liability. In general, take any of these paradigms as the default, and you will quickly find programs that you want to write fit the paradigm no better than a saddle would fit a cow. I think CML stands out as a much better foundational choice, subsuming the others.

Note to F# users - thanks to valiant effort by Vesa Karvonen, you can now use CML-style primitives in F#. See the Hopac project - it needs a bit more love!

Note to lovers of F# async. Async is a hack, but a good one. It is what you do when you want cheap by-the-million threads but do not have the time to rewrite the runtime (CLR). However, with a proper runtime, there is no need. See Racket or CML, where blocking syntax is used to orchestrate millions of lightweight threads.

Note on deadlock: CML-style channels use sync write, but async write is easy to write too. The book argues why sync writes are a better default. Yes you can program deadlock, but you can do the same within any sufficiently expressive concurrency paradigm. You definitely can in Erlang, try it as homework.

Tuesday, October 15, 2013

Last word in .NET build systems

Has not been said yet, I do not think.

In the F# world you may be looking at:


I am not going to do a detailed pro/con analysis of these just yet, but note that every one of them is currently missing abstractions relevant for this problem domain - building. A build system should allow you to do at least what veritable Makefile does - optimal rebuilds, but at an abstract level, as a library.

The best system I have seen so far that gives you these abstractions is Shake by Neil Mitchell (coded in Haskell). It goes beyond Makefiles by allowing dynamic dependencies. I did not study the specifics very closely, but the overall design is vastly useful, brilliant.

Do not have time at this moment to get it into the shape it deserves, but here is some work I have been drafting now and then to build a similar library in F#: fshake. If this scratches an itch, let me know, I would be interested in contributors - I have not put the license in yet, but this project will be under Apache license.

Friday, October 4, 2013

WebSharper vs FunScript

Got asked to compare WebSharper to TypeScript on StackOverflow, doing it here instead. Disclaimer: I work for IntelliFactory and in fact develop WebSharper, so I am obviously biased.

Good things to say about FunScript:

  • seems to be entirely unrestricted (I could not even locate a license file)
  • has some very talented people hacking on it (but not as the day job)
  • has this wonderful idea of using TypeScript definition files to provide typed API for JavaScript libraries (however, at this moment it does not work with latest TypeScript version so no luck there)

Why would you be interested in WebSharper instead? The quick answer is that it actually gets used a lot more, and is known to work quite well on large projects (I will cite FPish and CloudSharper as the ones we have been using it on at IntelliFactory), there is a team working on it day-to-day, and you can get actual support. It has been in use longer and it might have more issues ironed out, and it definitely supports a larger portion of F# standard library out-of-the-box.

NOTE: Tomas pointed me to a FunScript way of doing the following in the comments. Jon Harrop sites problems with using sqrt in FunScript. In WebSharper, it works. Suppose it did not, and you know how the function looks in JavaScript, you do:

[<Inline "Math.sqrt($x)">]
let sqrt (x: double) = sqrt x

And there you have it.. Also, rest assured that there is no string splicing going on - the inline is parsed as JavaScript, then a large subset of JS like the above is lifted to our Core form, which assures things like evaluation order are preserved, and lets optimizations work smoothly, including ones we have not written yet :)

That being said, I believe we have made quite a few mistakes in the past, including:

  • hiding sources (it is open-source now)
  • mismanaging the community - actually I am reading books now on how to facilitate an open-source project community better
  • making it too hard to get started and not giving enough documentation
    (presently we are writing manual chapters at our github repo) and preparing a website update
  • trying to provide all library bindings ourselves - TypeScript is definitely a great idea and we will add support for it (have a working prototype for 0.8 but need to upgrade to latest TS - same as FunScript
  • attempting to solve too many problems at once, and not focusing on important problems first. This leaving us with a large and somewhat difficult to change codebase
  • some engineering mistakes in organizing code or designing APIs

If you feel like making more suggestions, please do..

People also typically bring up licensing and how the output code looks like as problems. I do not think those are show-stopper issues:

  • License (AGPL) - it is actually free for open-source use. If you need to close your app, but cannot afford the listed license fees, just talk to us and we can work out a deal. Note that having this license might be annoying but it is essential for securing funding and commercial support for the project - for it to have a future.
  • Code output - we are working out a better optimizer with Andras Janko that will help a lot, in both shrinking output and improving performance, but really, how the code looks - this is not an issue. In months of programming with WebSharper I never remember looking at the JavaScript output. Look at Emscripten, can you read its output? Yet Emscripten is extremely useful. Once you get past a certain stability level, this does not matter anymore.

I also privately think both WebSharper and FunScript make this fundamental mistake - using F# quotations. I think the future is simply not there. There is exciting stuff going on with projects such as ASM.js and Emscripten, and I strongly suspect the future successful project in this area will provide a much more compatible CLR implementation on top of JS, plus perhaps some specialized optimizations for functional code as F# produces. I have seen a few CLR-to-JS compilers, but am not sure which is the best today. I tried writing one myself and hope to come back to it, it certainly was challenging and interesting. The key is to stop thinking of such projects as source-to-source compilers and start treating JS for what it is, portable assembly.


Thursday, June 6, 2013

Generic programming in F# - another take

Playing a bit more with generics, I stumbled upon some fairly compact combinators that can derive n-ary conjunctions from a binary conjunction. Here is a self-explanatory F# example (disregard the ugliness involved in F#'s lack of higher kinds, Haskell or OCaml code would not need this):



In case you are wondering about the Coq file in the gist: a good objection to this approach is efficiency. Instances computed in this way are not efficient at all. Just think of all the allocated tuples! It turns out, we can remedy the situation with automated program transformation. In F# it would involve computing over quotations or similar quoted forms. It is hard to get started since little support for optimizing those is available out of the box. In Coq there is more batteries. As you can see in the gist, Coq seems to tackle the above example trivially with the "compute" tactic, and derive an instance equivalent to a hand-written one.

Wednesday, April 3, 2013

Introducing FAKE boot workflow

FAKE is a tool to automate your builds with F# scripts. Use the newly available FAKE boot workflow to get started quickly, automatically reference packages, and plug in your own build logic from NuGet.