The fatal attraction of FRP Core team

For about a year or so, I have made Functional Reactive Programming (FRP) taboo. I cringed at every mention of it. I think this was a mental self-defense reaction, my extended immune system was sending me a signal that I spent too much time thinking about this subject without any tangible results. The fatal attraction of FRP is its simplicity. Semantics are beautiful and clear. There are Behaviors, functions of time, Events, timed occurrences, and they all dance together. You write causal tra[...]
>> Read the full article on t0yv0.blogspot.com

Structuring Web Applications with WebSharper.UI.Next Community

Structuring Single-Page Applications with WebSharper.UI.Next


Since our last post, we have been hard at work extending the basic functionality of WebSharper.UI.Next to include some higher-level things, in particular support for animation, and some functional abstractions which make creating single-page applications (SPAs) safer, easier, and more intuitive. In this post, we'll talk a bit about some of the web abstractions we've added; Anton has written about the animation functionality here.

For the uninitiated, WebSharper.UI.Next is our upcoming framework for creating rich single-page applications. By creating reactive variables, and views which allow these variables to be observed as and when they change, it is possible to create highly-reactive applications backed by a purely-functional model. You can see some examples of this framework at work here, and the GitHub repository showing the source code for the website here.

A key advantage of using WebSharper to develop applications is the use of F#'s type system not only to provide better safety guarantees --- that is, fewer runtime errors and less JavaScript debugging --- but also to help better structure applications. To this end, IntelliFactory have made use of approaches such as Formlets to better structure handling user input, and developed our own such as Flowlets and Piglets. This past week, we've been working on seeing how some of these fit with SPA applications, and showing how they can be used within UI.Next. In particular, this past week we have looked at Flowlets, which help with structuring parts of an application which have a linear control flow, and how UI.Next can help to structure sites without such a control flow. Additionally, we've looked at how it's possible to synchronise the current position in a single-page application with the URL bar, to make sharing pages easier.

Flowlets

Flowlets are built to make it easier to structure applications (or indeed segments of an application: everything is composable) which have a linear control flow. By way of example, think for example of a registration form which has multiple pages, each getting different pieces of information, where each page may depend on information provided by a previous page.

In our small example, we first ask the user for some common information: in this case, a name and address. After this information is provided, we then ask the user whether they wish to specify a name or a phone number. Depending on which option is selected, we then display a different form to retreive the required information, before displaying the results on a final page. You can find this live here, and the source code here. The source code contains a bit of extra markup, but we'll concentrate on the main specifics here instead.

Firstly, we define our model, containing the data which we wish to retrieve. A key advantage of using F# for this kind of thing is that we can work directly with a model we have created in F#, without having to think about JavaScript objects and such.

1
2
3
4
5
6
7
8
9
10
11
12
type Person =
    {
        Name : string
        Address : string
    }

type ContactType = | EmailTy | PhoneTy

type ContactDetails =
    | Email of string
    | PhoneNumber of string

The Person type consists of a name and address. The ContactType type specifies whether the user has opted to specify an e-mail address or a phone number, and the ContactDetails discriminated union specifies the data which has been submitted.

Now, with the model created, we can look at how everything fits together.

To create a flowlet, we use the Define function.
1
2
val Define : (('A -> unit) -> Doc) -> Flow<'A> 

Here, (('A -> unit) -> Doc) is a function which takes a callback of type ('A -> unit), which is used to progress to the next stage of the flowlet, and produces a Doc. For readers unfamiliar with Doc, this is our monoidally-defined representation of a fragment of a reactive DOM tree, used in this case to render the flowlet. This in turn produces a value of type Flow<'A>, where 'A is the type of data returned by that flowlet page.

Now, we create some pages. As I say, I've stripped out the markup, concentrating on the bits of the code we care about.

Firstly, here's the first page which grabs the name and address from the user.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let personFlowlet =
    Flow.Define (fun cont ->
        let rvName = Var.Create ""
        let rvAddress = Var.Create ""

        Doc.Input [] rvName 
        Doc.Input [] rvAddress 
        Doc.Button "Next" [cls "btn" ; cls "btn-default"] (fun () ->
            let name = Var.Get rvName
            let addr = Var.Get rvAddress
            // We use the continuation function to return the
            // data we retrieved from the form.
            cont ({Name = name ; Address = addr})
        )
    )

The personFlowlet function is of type Flow<Person>: a flowlet segment returning a value of type Person. We begin the function with Flow.Define, which takes a continuation function cont. The next thing to do is specify reactive variables for the name and address fields, initialised with the empty string.

Once we have the variables, we can use these with the Doc.Input function to create a form control which populates the variables. The submission button is then created using a function which gets the current calues of the name and address fields, and then passes a Person value to the continuation function.

Using the same technique, we can then make three further pages: contactTypeFlowlet, which returns a value of type ContactType; contactFlowlet, which takes a ContactType and returns a ContactDetails value, and finally a static page which displays the details.

After this is complete, all that is left is to tie everything together. Making use of the fact that flowlets have a monadic interface, we can construct flowlets using a computation expression. By doing this, we specify the order in which the pages appear, and how the data collected from one page may be used in another.

1
2
3
4
5
6
7
8
9
let PersonContactFlowlet =
    Flow.Do {
        let! person = personFlowlet
        let! ct = contactTypeFlowlet
        let! contactDetails = contactFlowlet ct
        return! Flow.Static (finalPage person contactDetails)
    }
    |> Flow.Embed

In this computation expression, preson is of type Person, ct is of type contactTypeFlowlet, and contactDetails is of type ContactDetails. It's also clear that the contactFlowlet flowlet depends on the value retrieved from the contactTypeFlowlet flowlet page. Finally, we return a static page displaying the details, and then use the Flow.Embed combinator to embed the flowlet into a reactive DOM fragment of type Doc, which can be composed as normal.

Structuring Non-Linear Sites

Flowlets are great for specifying parts of an application which have a linear control flow. They don't work so well when we want to jump around freely between different parts, however.

Using UI.Next, it's also easy to construct SPA applications consisting of multiple 'pages', which are loaded in a structured manner. In particular, by using UI.Next, everything can be specified without thinking about URLs at all, but purely passing the page we want to load as a continuation function. It's best to hop straight in with an example. Let's make a small, silly website.

To start with, we need to create a discriminated union representing each page in the site.

1
2
3
4
5
6
type Page =
    | BobsleighHome
    | BobsleighHistory
    | BobsleighGovernance
    | BobsleighTeam

By creating the Page type, we'll then be able to create a Var<Page> which specifies the current page we're on. We'll consider two different types of navigation: global navigation performed by a navigation bar, and local navigation, performed by links on individual pages.

Now, we'll make implementations of each page. Each page will take a record, Context containing a continuation function, which can be used to change the current page. For example, here is the source for the home page:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    type Context = {
        Go : Page -> unit
    }

    let HomePage ctx =
        Doc.Concat [
            el "div" [
                el "h1" [txt "Welcome!"]
                el "p" [
                    txt "Welcome to the IntelliFactory Bobsleigh MiniSite! Here you can find out about the "
                    link "history" [] (fun () -> ctx.Go BobsleighHistory)
                    txt " of bobsleighs, the "
                    link "International Bobsleigh and Skeleton Federation" [] (fun () -> ctx.Go BobsleighGovernance)
                    txt ", which serve as the governing body for the sport, and finally the world-famous "
                    link "IntelliFactory Bobsleigh Team." [] (fun () -> ctx.Go BobsleighTeam)
                ]
            ]
        ]

You'll notice here that each link is associated with a callback, which executes the ctx.Go function, providing the next page to show.

Tying this all together, we get a main function which looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 let Main () =
    let m = Var.Create BobsleighHome

    let withNavbar =
        Doc.Append (NavBar m)

    let ctx = {Go = Var.Set m}
    View.FromVar m
    |> View.Map (fun pg ->
        match pg with
        | BobsleighHome -> HomePage ctx |> withNavbar
        | BobsleighHistory -> History ctx |> withNavbar
        | BobsleighGovernance -> Governance ctx |> withNavbar
        | BobsleighTeam -> Team ctx |> withNavbar)
    |> Doc.EmbedView

Here, we create a context instance with Var.Set m as the continuation function. We then create a view of the page variable, which we can use to update the display of the page whenever it changes. In particular, through the use of View.Map, we change a View<Page> and create a View<Doc>. This can then be embedded into the reactive DOM using the Doc.EmbedView : View<Doc> -> Doc combinator.

Global actions, for example if we have a shared component such as a navigation bar, can be created by passing the page variable as a parameter. To change the current page, it's just necessary to set the variable.

URL Routing

Finally, SPA applications often lose the ability to do such things as using the 'back' button to go back in the application, or use the URL to share the current point in the application. We've worked on this to create a "Site" abstraction to allow different parts of the site to be responsible for different parts of the URL: the key here is that these sites are composable, meaning that it is possible to have different sub-sites.

The key idea behind this is the Router<'T> type, which essentially specifies a bijection between fragments of the URL, and page representations such as Page in the site above. If we were to want to extend the bobsleigh mini-site with some kind of URL routing, a router could be created as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    let TheRouter =
        Router.Create
            (function
                | BobsleighHome -> Route.Create []
                | BobsleighHistory -> Route.Create [RouteFrag.Create "history"]
                | BobsleighGovernance -> Route.Create [RouteFrag.Create "governance"]
                | BobsleighTeam -> Route.Create [RouteFrag.Create "team"])
            (fun route ->
                match Route.ToStringList route with
                | [] -> BobsleighHome
                | ["history"] -> BobsleighHistory
                | ["governance"] -> BobsleighGovernance
                | ["team"] -> BobsleighTeam
                | xs -> BobsleighHome)

We could then use the resulting router to create a Site, which is then merged with other Sites, to create a routing trie. If you want to see this in action, check out the live example, and you can also take a look at the source here. Indeed we use this technique on our main samples site itself!

The Future

Our goals now are to get some more functional abstractions added in, particularly those used for handling user input such as forms. In particular, it would be nice to see how we can integrate Loic Denuziere's work on Piglets to make use of the reactive backend, instead of using the stream abstraction. Additionally, we're adding features and examples all the time, so keep checking back!

WebSharper.UI.Next: Declarative Animation Core team

I have joined the legion of Mike Bostock fans, admiring his work on D3.js. You should, too. Check out the beautiful data visualizations, and be amazed how much your browser can do.

We are now hard at work with Simon Fowler to match this functionality in WebSharper. The improvements we are seeking are in the area of code clarity. The holy grail is finding a way to write visualizations that look just as beautiful as their D3 counterparts, but are also easier to read and modify to suit your needs.

Here is how our current efforts look like.

ObjectConstancy sample

We looked closely at how D3 examples are built. In a nutshell:

1. D3 uses SVG to do the graphics

2. It provides a wealth of coordinate transformation functions

3. There is the idea of "joining" elements to data

4. Animation is done by interpolating between two values and this is scheduled imperatively

The basic ideas are excellent. The rougher parts are that D3 manipulates DOM in imperative JQuery style, and leaves the user to specify control flow, often even relying on a manual event loop.

It works great when it does. When it does not, it is a mine field of things that can go wrong, wrong element sets being selected, wrong effect ordering, wrong function context. Not a problem for simple examples, but cost me hours trying to tinker. Perhaps that is just a beginner's fate, but I wonder if a better approach is possible.

In WebSharper.UI.Next we already have a better way to deal with control flow and DOM manipulation - reactive documents. There is an all-powerful Doc type and a reactive layer that work together:

1
2
val EmbedDoc : View<Doc> -> Doc

There are reactive attributes too, attributes that are implicilty time-varying.

So how about animation? Our basic idea was this: instead of scheduling animation directly, we allow specifying animated attributes:

1
2
Attr.Animated : name: string -> Trans<'T> -> View<'T> -> ('T -> string) -> Attr

An animated attribute is an extension of a time-varying attribute that animates any change in the underlying value. Trans (transition) value specifies how to construct an animation for a change between two levels, and also, optionally, for adding or removing elements to the document.

While not as flexible as the more general imperative approach, we find declarative animated attributes quite freeing, as animation scheduling is entirely implicit and does what you mean automatically.

You can see this functionality in action in our on-going transcription of an interesting D3 example.

Another good aspect of animation systems we found advocated by D3 is managing object identity. There is the basic principle of "object constancy" that dictates that identical logical elements should be mapped to identical visual elements, and this identity visually preserved, to help the viewer perceive the relationship.

On a lower level, in terms of code in a reactive dataflow system, this if often discussed in terms of "key" functions. At first I prematurely dismissed this concept, thinking it is just another way of saying we care about equality on a given type, and specify it by projecting to a different type. However, it turns out there is a little more to it, specifically, it is a nice way to recover fine-grain object changes from coarse-grain collection changes.

Our current understanding of the "key" function lore is expressed in this combinator:

1
2
3
4
5
6
    View.ConvertSeqBy<'A,'B,'K when 'K : equality> :
        key: ('A -> 'K) ->
        conv: (View<'A> -> 'B) ->
        view: View<seq<'A>> ->
        View<seq<'B>>

Suppose you have a geometric point type, Point; then a collection of them, of type seq<Point>. An object of type View<seq<Point>> is a time-varying collection, however it is not terribly useful as it does not discriminate macro and micro change: points might be added or removed, but also individual points might change coordinates. When mapping these logical points to graphical representations, we might have some trouble with object constancy.

Without a combinator such as ConvertSeqBy, we could change our design to propagate micro and macro change separately, which would be reflected in the types, for example like this:

1
2
3
type Point = { X: View<double>; Y: View<double> }
val Points : View<seq<Point>>

While working, this approach frequently feels heavy-handed. Luckily, once we have a key function Point -> int (and associated identity on Point), we can distinguish macro and micro changes while keeping a simple immutable Point type. ConvertSeqBy does that, and propagates the changes to the given "conv" function in a nice way. Whenever a Point is added, "conv" is called to obtain a new graphical representation. When the same point has changed, the function is not called, but the change is propagated via the associated View. In this manner, the range of our "conv" function is permitted to use identity and some hidden state to enhance the visual presentation. Object constancy is taken care of by the combinator.

You might wonder why object identity matters for just drawing some circles for every point, what if we just draw from scratch? But it does matter with declarative animation! To interpolate between two positions of the circle, we need to know it is the same circle.

In the end we were very pleased when the two fairly orthogonal features, declarative animations and ConvertSeqBy worked together as-expected in our example. Compared to the D3 original, we are still lacking some features, but our code eliminated imperative scheduling, and composes easily. A little victory.

This we will be working with Simon specifically to improve documentation and examples. We are finally putting a lid on feature creep. Our big hope is to significantly lower the bar for animating UI. This is essential to making sure animation is done more often, and the end users, on average, are happier.

WebSharper.UI.Next: An Introduction Community

WebSharper.UI.Next: An Introduction

Here at IntelliFactory, we've been working on a new way of constructing single-page applications.

We're using WebSharper, which is a framework for writing web applications entirely in F#, without the need to write separate JavaScript, PHP and SQL code: if you haven't used it before, I encourage you to have a play around!

The main idea behind this library is centered around data sources. These data sources, which we call Vars or reactive variables, can be linked to form components, or set by remote server calls, for example. We then have views, which provide a way of observing these changing variables, which then can be embedded directly into the DOM in such a way that they automatically update whenever the data source changes. On top of this, we use a functional style, and take steps in the dataflow layer to ensure that memory leaks don't occur.

Firstly, if you want to see everything in action, you can find a live examples site (itself written using the framework, of course!), along with the source code for the examples, on GitHub.

Briefly, WebSharper.UI.Next consists of two layers: a dataflow layer, made up of variables and views, and a reactive DOM layer making use of this, allowing time-varying elements to be embedded in the DOM. In the simplest case, it's possible to create a reactive variable (which can be thought of as a data source), bind this to a DOM element, and have the DOM element update automatically whenever the data changes. This removes the need to write separate DOM handling code for whenever the data changes: you just specify the view once, and the updates happen automatically.

In this sense, the library is a bit like libraries such as Facebook React. Firstly though, everything's in F#, so we get all of the advantages of a strong, static type system, including the ability to catch errors sooner and make use of such a type system for structuring applications. It's also easier for us to make use of traditional, powerful functional abstractions when writing code. React is built on a virtual DOM system, which efficiently propagates updates via a diff algorithm against the "real" DOM. While we do some diff'ing, too, this is purely an optimisation step: we update the DOM by re-linking from the desired position, much as we do in the Formlets library for WebSharper.

An example

Perhaps the best way to demonstrate the library is via an example. Say we have an input box, and we want to use this as an input to multiple different functions, each doing something different with the data. In this case, it should be possible to write something in a box, and then display the entered text, the input text but capitalised, the input text but reversed, the number of words, and whether the word count is odd or even.

Let's dive right in. The actual code for this example contains a bit more styling than I have here, so I'm just going to talk about the interesting bits. Firstly, we create a reactive variable to store the input text.

1
2
let rvText = Var.Create ""

This creates a variable rvText of type Var<string>, which is essentially a 'cell' containing a string.

The next step is to create an input box, which is linked with this variable. Whenever a user types into this box, the variable will be updated, and anything which depends on it will be updated automatically. In addition to this, if something else updates the variable, the text in the box will be updated accordingly. Achieving this is simple:

1
2
Doc.Input [] rvText

(aside: the empty list parameter specifies attributes, which may themselves be backed by reactive variables).

Now we have the data input part, we need to have a look at how to display it. In order to do this, we create a reactive view. Views can be thought of a way to "peer into" a variable as it varies with time, and it's views that we attach to the DOM. It's also worth saying that views are, as their name would suggest, read-only. We can also chain different views together using applicative and monadic combinators, allowing a dynamic dataflow graph to be constructed.

Constructing a view from a variable is simple:

1
2
let view = View.FromVar rvText

The view variable then has the type View<string>. We can then embed this into the DOM by creating a text node inside a <div> tag:

1
2
3
4
Doc.Element "div" [] [
    Doc.TextView view
]

With this view, it's then possible to create the other views we want by using the View.Map : ('A -> 'B) -> View<'A> -> View<'B> function. Map simply creates a new view, with the function applied. Using this, we can easily implement all of the other ways of looking at the input:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let viewCaps = 
    view |> View.Map (fun s -> s.ToUpper () )

let viewReverse = 
    view |> View.Map (fun s -> new string ((s.ToCharArray ()) |> Array.rev))

let viewWordCount = 
    view |> View.Map (fun s -> s.Split([| ' ' |]).Length)

let viewWordCountStr = 
    View.Map string viewWordCount

let viewWordOddEven = 
    View.Map (fun i -> if i % 2 = 0 then "Even" else "Odd") viewWordCount

...and these can simply be embedded into the DOM as before.

What's Next?

We think that the experiment so far has gone quite well, and that we've demonstrated that this sort of dataflow structure works nicely with WebSharper and the DOM. Building on this, we're currently working on two different things: adding support for animation, and incorporating and using this framework to build on existing functional web abstractions.

For the animation side of things, we're hoping to find an intuitive, idiomatic, but powerful way to declaratively encode animations: we're looking at D3 for inspiration, but hope to improve the interface somewhat! This should mean that it's possible to use the dataflow layer to drive powerful visual, interactive documents in a pleasant, functional manner.

The second thing we're trying to do is to use UI.Next alongside different functional abstractions, making it easier to create interactive web applications. We've done some work on porting flowlets to the new system, which are an extension of formlets with a monadic binding operation to allow for dynamic composition. In particular, this means that it's possible to setout a "flow" for an application, showing how data from one stage of an application is used in a different part. More details are to come in a later blog post, but you can see the code for one example here.

In particular, the main part of this example is as follows:
1
2
3
4
5
6
7
8
9
let exampleFlow =
        Flow.Do {
            let! person = personFlowlet
            let! ct = contactTypeFlowlet
            let! contactDetails = contactFlowlet ct
            return! Flow.Static (finalPage person contactDetails)
        }
        |> Flow.Embed

We firstly get some user information from the personFlowlet page, determine which type of contact information to get using the contactTypeFlowlet page, use this to get the required information, and finally display all of these on the final, static page.

In addition to this, we're hoping to see how this approach integrates with Piglets, our library for pluggable UIs.

Thanks for reading, and stay tuned for more! If you have any comments, we'd love to hear them.

CloudSharper 0.9.14 released Core team

We just released version 0.9.14 of CloudSharper. This release is mainly geared towards enhanced usability with two main features:

  • A reworked dashboard, replacing both the old "Go to CloudSharper" page and the workspace list window with a streamlined page containing all the information you need.


  • A redesign of the left panel of the workspace view. Instead of the file system tree, now a logical solution/project tree is the default view. All functionality related to project handling has been moved to the context menus here: adding references, managing NuGet packages, building and cleaning; managing the list of files compiled or included in a project has been implemented. Note that file create, rename and delete are still available in the Files panel, but do not affect the list of files included in the project.


Here is a complete change log:

  • #402: Show a VS-like project list.
  • #411: Alert the user about changes to open files.
  • #422: Sort available deployment options.
  • #437: NuGet.InstallPackage in FSI uses the wrong Nuget.Core.dll
  • Replace "No local component" error window with a flash on the dashboard.
  • Use Gravatar to retrieve the user's picture.

Happy coding!

CloudSharper 0.9.13.1 Core team

This is a bugfix release fixing issues with NuGet integration and Mono.

There is a new installer to download containing these changes.

Here is the change log for this release:
  • #432: Nuget dependencies on WebSharper extensions
  • When adding/updating NuGet packages, only the already installed dependencies not in currently required version range are updated.
  • Removing old WebSharper.targets correctly when updating WebSharper package
  • Search in only currently enabled NuGet sources
  • #436: Create project fails on mono 3.2.8
  • Templates updated to using the latest WebSharper, which contains build fixes for Mono

Happy coding!

CloudSharper 0.9.13 with workspace cloud sharing! Core team

Here we are again with a new release of CloudSharper today. This is an exciting one, as it allows you to upload your workspaces to our cloud storage and share them with everyone!

To use this feature, simply go to the "Workspace" menu and choose "Publish Workspace", or type sync up in the console. The contents of the current workspace will be uploaded as shown below:



Once uploaded, you can share your work in two different ways: as a downloadable zip, or as a link to clone it as a new local CloudSharper workspace. It's that easy!

In order to avoid publishing workspaces littered with generated and downloaded files, we support a .csignore configuration file in the root of the workspace. This file contains a list of glob patterns for files and directories that should not be included in the uploaded workspace. As an example, here is the .csignore we now include with every newly created workspace:
1
2
3
/packages/
bin/
obj/

One last detail about this feature: subsequent uploads of the same workspace will overwrite the current one, so you can re-run sync up to update the online version of your workspace. In a future release, we will also include the capability to upload a snapshot of the workspace (or just a subfolder) under a separate unique ID.

Here is the full change log for this release:
  • Implement sync up command, and corresponding menu entry, to upload the current workspace to Azure cloud storage via cloudsharper.com.
  • #426: Use .csignore file as a list of glob patterns for files that should not be included in uploaded workspace.
  • #430: Automatically add a .csignore to new workspaces.
  • #429: Simplified the login page to a more minimalist style and added a registration form on this page.
  • #428: Put /zip download behind authentication.
  • NuGet source settings, including credentials, are now saved in a local file (~/CloudSharper/<username>/Workspaces/NuGet.config).
  • Editor tabs now have a context menu for saving or closing tabs.
  • Added Disqus comment threads to our blog entries.

CloudSharper 0.9.12 Core team

This new release of CloudSharper alpha improves the NuGet package management workflow.

  • Automatic referencing of newly installed or updated packages: CloudSharper inserts references in the project file, similarly to how Visual Studio does.
  • Support for package sources with authentication. Credentials are not saved and have to be provided again after reloading a workspace. For upcoming versions we are considering options to allow a better workflow without risking to compromise user authentication data.

This is a protocol-changing version, so make sure that you install the latest version of the CloudSharper local component. Happy coding!

CloudSharper 0.9.11.2 Core team

This minor release fixes several bugs and hopefully clarifies the situation regarding SSL certificates for nuget.org.

Change log:

  • #395: Respect folder structure when creating a workspace from zip.
  • #390: Completion: also surround with ``...`` when the identifier starts with a digit.
  • #415: On mono, on local component startup, test the presence of the SSL certificates for nuget.org and, in case of failure, warn that the user should run mozroots --import --sync.
  • #421: Deploy window: better heuristic to determine what is a sitelet and what is a static HTML application.

Happy coding!

WebSharper: What's New (June 2014) Core team

Mono, Mac and Linux


Since February, we worked on supporting WebSharper development, and not just deployment, on Mono, Mac and Linux. Most of the code works fine, but unfortunately Mono support for MSBuild with XBuild leaves much to be desired, and Xamarin team is in no hurry to fix or respond to this - see [link:bugzilla.xamarin.com] and [link:bugzilla.xamarin.com] - as they do not see XBuild/MSBuild compatibility as a priority.

Fortunately, we were able to find workarounds to avoid buggy XBuild features, by moving most build logic to F# code invoked via XBuild/MSBuild plugins. There is now some preliminary support for building on Mono and using MonoDevelop or Xamarin Studio 4.2, with 5.0 support and project turnaround between all IDEs (Visual Studio, XS/MD, CloudSharper) coming soon.

Numerics


We are working with Microsoft Research to improve WebSharper performance on numeric code for applications such as numeric biology. As part of this work, we created an experimental compiler from an F# subset to ASM.js. So far, the prototype failed to provide speedups on current benchmarks, but came quite close. As the experiments continue, we are considering more approaches, such as integrating loop-invariant code motion into the optimizer, or perhaps even taking advantage of LLVM IR and existing passes written for it.

Visualization and Extensions


Andras Janko has done interesting work lowering the barrier to using Sencha Architect UI design tool from WebSharper with Type Providers.

D3.js binding received an update and multiple improvements. There are also now a few more samples of using this wonderful library with WebSharper.

Leaflet.js now also has a WebSharper binding.

Single-Page Applications and Reactive DOM


There are some lively discussions on better SPA support with the IntelliFactory team - Andras Janko, Loic Denuziere and Simon Fowler who is joining us for a summer internship. We are evaluating Facebook React, Angular JS, and D3.js and looking how we can do better in a typed language, in particular how to better integrate dataflow and data binding. If the prototypes work out, WebSharper is likely to obtain a new powerful front-end combinator library by the end of this summer.