WebSharper at CUFP 2011 Core team

Back in 2004 when we founded IntelliFactory to do commercial F# development, there were just a few dozen people who have heard about F# worldwide. When pitching to various companies or talking informally about what we do I usually met with total utter disbelief - how could a company that specializes in something unknown ever succeed?

Fast forward ca. 6 years: after over 130 internal and commercial projects/applications completed in F#, having presented at numerous conferences and workshops about our work, and tackling some of the most challenging and interesting problems on a daily basis, I have to confess that there have been nothing more fulfilling than doing what we do: thinking of something big, implementing it in F#, and seeing it benefit people.

Most of the time you hear about F# users coming from big banks and investment companies, but if you think that's all where they are you are definitely wrong. Personally, I strongly oppose the "F# as a complementary language to C#" idea, and I don't feel that F# is "best only in certain domains." We had been working hard to prove this in the web sphere: F#, coupled with a framework like WebSharper, is a fantastic tool set to develop client-oriented, rich internet applications, not only compatible with proven standards like ASP.NET but also yielding a huge developer productivity boost that no other language/web framework combo can match.

Commercial Users of Functional Programming (CUFP)


CUFP is the primary place to learn about commercial users and applications of functional programming in industry. We presented about F# there back in 2009, when we demoed a marketing automation stack we built for one of our partners in Silicon Valley. This project consisted of several large pieces: a data mart collecting marketing campaign data and responses; an analysis engine to run sophisticated queries; a web front-end to construct these queries, to create marketing communications, and to visualize their effectiveness over a larger campaign scope; an execution platform to deliver these campaigns and their waves; and a printing automation that managed and optimized the printing and delivery processes.

This year we are back to CUFP! This time we are presenting our work on WebSharper applied to build mobile applications with F#. From type-safe, composable mobile UIs to integrating third-party services, WebSharper Mobile is unmatched in giving mobile developers the kind of abstractions that make mobile development easier, much quicker, and much more fun!

The abstract of the talk is below:

Native mobile applications enjoyed tremendous success in recent years,
and looking at various mobile application stores such as Apple's App Store
or Google's Android Market reveals a staggering number of native mobile
applications. As technologies to build these applications mature and the
market saturates, mobile OS vendors are struggling to find ways to keep
up with and secure the exponential market growth. Inhibiting factors include
platform-specific development environments, programming languages, and
building blocks for applications; developer-unfriendly licensing, policies
and subscriptions; and controlled channels of application distribution.

These problems have given rise to many promising alternatives and
technologies that aim to bridge across various mobile platforms and enable
sharing some or all the code in between versions of applications for different
mobile OSs. Two main directions unfolded: targeting mobile code generation
from mainstream languages such as C# and Java, and embracing web
applications with platform-independent UI abstractions and enhanced access
to the capabilities of the underlying device. While the technologies that
enabled the former are an interesting topic, we believe that the latter has
implications not only for mobile applications but also for their desktop
counterparts, and finding ways to utilize functional programming in the
development of these web-based applications has an immense impact on
mobiles and desktops alike.

In this talk I will highlight some of the work we are doing at IntelliFactory to
enable building platform-independent mobile applications in F#. This work
leverages our commercially available WebSharper framework, the premiere
functional web development framework for F# with thousands of active users
and partner companies, and utilizes some key functional programming
abstractions that enable modeling first-class, type-safe, composable web
applications and user interfaces. I will briefly outline the metaprogramming
infrastructure that enables us to enlist arbitrary JavaScript libraries into the
type-safe discipline of F#, and the underlying CoreJS language that is more
amenable to reasoning about and applying code transformations and
optimizations.

At the end of the talk, I will briefly touch upon our upcoming F# in the Cloud
support and how that helps to seamlessly scale into the cloud desktop and
mobile web applications with immense server computation needs.


It's still not too late to sign up to CUFP and attend the talk in Japan! We are definitely interested in hearing your feedback, please visit the FPish forums (more on FPish in the coming days...) to ask or comment. Also, the drop to try out WebSharper Mobile will be available and announced here shortly. Happy mobile coding!

WebSharper Extensions for Bing Maps 7.0 Updated Core team

The WebSharper Extensions for Bing Maps has been updated to reflect the last changes in the 7.0 API. Here is a list of additions:

  • A new "modules" API which allows you to create extension modules for Bing Maps. This also comes with the three following built-in modules.
    • Directions: This is a simplified API to access the Routes REST API. It provides a very convenient interface, with attractive features such as draggable waypoints which trigger a recalculation of the route, and clickable instructions which causes the map to zoom on the corresponding location.
    • We advise you to only use our previously existing interface to the Routes REST API if you want to use it without displaying a map.
      Traffic: This simple class allows you to display traffic information as a layer on the map.
    • VenueMaps: This API provides precise information about buildings surrounding an area, and draws their ground footprint on the map.
  • A new "strokeDashArray" property for polylines and polygons which allows you to use dashed lines. The WebSharper extension use an array of integers to represent the list of dash lengths more safely than the string used by the JavaScript API.

To demonstrate the simplicity of these new APIs, here is the code for a map allowing the user to search for a route between two locations.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
open IntelliFactory.WebSharper.Bing
open IntelliFactory.WebSharper.Bing.Directions

[<JavaScript>]
let MapWithRouteRequest () =
    let origin = Input []
    let destination = Input []
    let button = Input [Attr.Type "button"; Attr.Value "Request route"]
    let answer = Div [Id "answer"]
    let mapContainer =
        Div []
        |>! OnAfterRender (fun el ->
            let opts = MapOptions(Credentials = "Your Bing maps developer key",
                                  Width = 600,
                                  Height = 500)
            let map = Map(el.Body, opts)
            map.SetMapType(MapTypeId.Road)
            let onDirsLoaded() =
                let dirman = DirectionsManager(map)
                let request (_:Element) (_:Events.MouseEvent) =
                    dirman.ResetDirections()
                    dirman.AddWaypoint
			<| Waypoint(WaypointOptions(Address = origin.Value))
                    dirman.AddWaypoint
			<| Waypoint(WaypointOptions(Address = destination.Value))
                    dirman.SetRenderOptions
			<| DirectionsRenderOptions(ItineraryContainer = answer.Body)
                    dirman.SetRequestOptions
			<| DirectionsRequestOptions(DistanceUnit = DistanceUnit.Kilometers)
                    dirman.CalculateDirections()
                button |>! OnClick request |> ignore
            Maps.LoadModule("Microsoft.Maps.Directions", LoadModuleArgs(onDirsLoaded))
        )
    Div [mapContainer
         Span[Text "From:"]; origin
         Span[Text "To:"]; destination
         button
         answer]



The updated extension for Bing Maps can be downloaded at this address.

WebSharper 2.3 - targeting enterprise applications Core team

We have been pretty busy these past few months working on a number of enhancements to WebSharper for its 2011 Q2 milestone - and I am happy to announce that the new 2.3 release is now out for public consumption.

Anton gave a short overview about some of the new features in this release, in particular the new deployment layout that packages generated artifacts into the target assembly, greatly simplifying the process of building and deploying WebSharper 2.3 applications.

Generated artifacts


The WebSharper 2.2 compiler generated a pair of new files for every assembly it processed:

  • A .dep file with the dependency information for the assembly, and

  • A .js file with the generated JavaScript code for the client-side components.



This had several issues and small annoyances. On one hand, moving three files in sync often grew above the capabilities of MSBuild, leaving stale dependency or generated JavaScript files in place. This meant having to do a manual clean when things "got confused" - a rare, but annoying occurrence that could really steal a few minutes from your daily work. Furthermore, the "single-file-for-the-JavaScript-output" approach enabled no support for debug and release versions for the generated JavaScript code. Here in past versions we made the conscious choice to output verbose, developer-friendly JavaScript, but this was often too heavy and thus slower in production deployments.

With the 2.3 enhancements, WebSharper now produces both debug (verbose, with fewer optimizations applied) and release mode (more optimized and compact) JavaScript output, and packs both of these and the dependency information onto the top of the target assembly. As usual, this involves calling the WebSharper compiler after the F# compiler in sequence, producing an assembly that is "WebSharper-aware" and ready to be dropped in a standard web project with WebSharper enabled.

The standard WebSharper Visual Studio templates are modified to "process" the WebSharper-aware assemblies as part of preparing the web project to be run, dumping out the debug/release versions of the contained JavaScript code in a scripts folder. These are then served based on the "debug" setting in your Web.Config file by the WebSharper runtime.

Enhanced Async support


There is quite a buzz around Async's lately with their inclusion into C# - and a lot of people don't realize that Async's have been a standard part of F# for years now. The previous versions of WebSharper had partial support for asynchronous computations, leaving you without a couple important API members such as Async.Parallel despite fully supporting the computation expression syntax. This was due to the inherent single-threaded nature of JavaScript execution engines in most modern browsers, which was a conceptual barrier to any asynchronous implementation.

The current 2.3 release further improves on WebSharper's Async support by implementing a round-robin scheduler with a granularity of a single bind operation (that is, a let! binding inside an Async computation expression) and giving a client-side implementation to Async.Parallel using this scheduler. Overall, this makes it possible to emulate executing multiple asynchronous computations "in parallel", such as initiating multiple web service calls or manipulating the DOM from multiple "agents" executing on your page independently.

We will surely be blogging about this new feature, in the meantime check out Joel's article on implementing an asynchronous slot machine using simple and powerful F# Async expressions.

Sitelet enhancements


Sitelets have been an integral part of the WebSharper Professional product line, a clear differentiator to the WebSharper Standard line. If you have been to any of our talks or listened to our webcasts, you probably are aware that we recommend developing your web applications on a sitelet foundation, e.g. using sitelets to model your application functionality.

The 2.3 release bring a couple smaller enhancements to sitelets:

  • You can now use the tilde (~) character in your sitelet template markup files (*.template.xml) to refer to the application root directory. In particular, any src and href attribute will be mapped accordingly. This now works correctly even if you are deploying to a virtual directory under IIS.

  • Full authentication support using the ASP.NET authentication pipeline. Previous implementations relied on cookies only, this now is extended to all authentication protocols you may have been used to in your traditional ASP.NET applications.

  • Placeholders in the [Head] section of a markup template - it is now possible to place arbitrary placeholders inside the head section in tag positions. These placeholders have a slightly different type than ordinary placeholders.



Bug fixes and further enhancements


Anton's announcement also lists over 30 further bug fixes and enhancements to the installer, the formlet library, updating to the latest jQuery, sitelets, and Visual Studio integration. We certainly recommend updating to the 2.3 release even if you are working on larger enterprise application projects, the new features and enhancements in this release are very much worth the effort.

Extensions


As usual, the new 2.3 compiler is accompanied by an update to every available WebSharper extension, and the new 2.3 series of each are now available on the WebSharper Extensions page. This new batch also includes the long-awaited Twitter extension and the upcoming extensions for TinyMCE, a mature and powerful, open-source and platform-independent WYSIWYG HTML editor.

A tiny glimpse of WebSharper 2.4


In our efforts to bring you the most advanced functional web programming framework, we continue to implement various code optimizations to bring down the generated code size (now in Release mode). The current 2.3 release has no new optimizations, it simply removes whitespace to save you about 20-25% on the generated code size. We plan to implement some key optimizations in the upcoming 2.4 release, giving a massive (50% or more) drop in the generated code size.

The other major enhancement planned in 2.4 is making the jQuery dependency optional. The current releases assume jQuery as the default DOM functionality provider, and although it is technically feasible to implement additional providers, they don't come out-of-the-box with WebSharper. The plan is to support an alternate DOM provider implementation, targeting a more lightweight foundation suitable for running efficiently especially on mobile devices.

If you encounter any issues, please use the WebSharper Bugzilla so your issue can be tracked properly. Thanks, and enjoy the current 2.3 release!

WebSharper 2.3 Core team

WebSharper 2.3 improves on the 2.2 version by using a safer deployment file layout, implementing parallel Async methods in JavaScript, adding new operators, and fixing several bugs.

The deployment file layout in WebSharper 2.2 assumed that JavaScript and binary metadata files are deployed alongside WebSharper assemblies. This caused problems, in particular when these files were not being copied correctly. WebSharper 2.3 bundles these files as embedded resources, reducing the problem to conventional .NET deployment. Debug and release versions of JavaScript are now provided, with the choice being made at runtime depending on whether ASP.NET debugging is on or off.

The F# method Async.Parallel and Async.StartChild are now available for use on the client. The implementation uses a cooperative round-robin scheduler. Thread cooperation happens on every bind in the Async workflow expressions.

Constructing JavaScript object literals, getting and setting object fields in F# became easier with the addition of helper operators (#456):

1
2
3
4
5
6
val New<'T> : seq<string*obj> -> 'T
val ( => )  : string -> obj -> string * obj
val ( ? )   : obj -> string -> 'T
val ( ?<- ) : obj -> string -> obj -> unit

They make this code:
1
2
3
4
let window = New<obj> ["height" => 640; "width" => 480]
window?height <- window?height / 2

equivalent to:
1
2
3
4
var window = {height: 640, width: 480};
window.height = window.height / 2;

The most important fixes include #453 that was breaking virtual folder deployments of sitelet-based applications, and multiple bugs related to metadata file handling that lead to compiler failures. The bug fixes include:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#339 [formlets] InitWith is not always effectful.
#350 [templates] Template generator fails on HEAD placeholders.
#368 [formlets] Formlet values triggered multiple times.
#369 [compiler] Bundpe DEP and JS files with the DLL.
#370 [compiler] Provide minified and unminified output.
#379 [ide] VS 2010 Add-In failed to load.
#404 [templates] Building template fails on Vista64.
#406 [templates] HTML Application template fails on Vista64.
#407 [installer] Uninstallation failure.
#409 [sitelets] VS9 template fails to map '/'.
#411 [installer] No menu shortcuts for samples.
#413 [templates] Embedding text under Body tag fails.
#414 [installer] Installation fails on Vista x64.
#416 [sitelets] Authentication support for sitelets.
#417 [collections] Fixed Map.remove.
#421 [jquery] Upgraded to 1.6.1.
#423 [compiler] Access denied error during compilation.
#424 [sitelets] Sitelets should respect ASP.NET authentication.
#426 [jquery-ui] Missing configurationfor range slider.
#427 [jquery-ui] Make slider formlet allow multiple handlers.
#430 [compiler] Failure to load reference assemblies.
#432 [html] Incorrect rendering of BR tags.
#433 [installer] Installation failure.
#434 [html] Server-side HTML5 tags and attributes support.
#435 [control] Parallel async methods support.
#438 [formlets] Add 'class' configuration for form buttons.
#445 [formlets] Add 'readonly' versions of formlets controls.
#448 [formlets] Enhance.FormContainerConfiguration - bogus padding values.
#449 [core] Runtime error on sequence expressions.
#450 [core] F# ranges with negative steps do not work.
#453 [sitelets] Sitelet routing gets confused by non-root deployments
#456 [websharper]  Add support for dynamic operators

The details can be found at bugs.intellifactory.com.

Color the Wind - a 2D Canvas demo with WebSharper Core team

The demoscene is a computer subculture focused on the creation of demos: short real-time animations showcasing a wide variety of technologies. Among these, web technologies have been getting increasing interest during the last months. DemoJS is an example of this interest: it is a demoparty (a demoscene meeting and competition) that was co-organized by Mozilla Labs in Paris on the 2nd and 3rd of July.

Color the Wind is a demo that was developed with WebSharper and presented at DemoJS. It uses the HTML5 Canvas element with a 2D context.



Color the Wind was created in just a few hours, and took the sixth place in the competition. You can have a look at the F# source code at this address.

WebSharper / O3D sample: Snooker game Core team

We are happy to present to you the first game coded using WebSharper. It is a translation from one of O3D's biggest samples: the snooker.



This WebSharper snooker is on par with its JavaScript counterpart in terms of game speed, showing the performance of our generated code. But the source code is actually about 25% shorter than the original. Moreover, the extra safety brought by F# and WebSharper would have made its development easier and faster.

Why is it safer?

When we developed the WebSharper bindings to O3D, we brought a few modifications which added some extra safety.

First, mathematical operations on vectors, matrices and quaternions are more strongly typed. Indeed, while the JavaScript API uses arrays to represent these data types, we use tuples. Therefore the number of elements is always known. For example, if you try to compute the dot product of two vector of different sizes (using o3djs.math.dot) in JavaScript, it will silently return an erroneous value. However, in WebSharper, the error is detected at compile time by the type system, because there is no overload on O3DJS.Math.Dot taking two tuples of different sizes.

Another element that makes O3D in JavaScript unsafe is its use of methods whose return type depends on the arguments. An example is Pack.createObject. It takes a string designating a type, and returns an object of the given type. In WebSharper, there is an appropriately typed version of this method for each possible return type. So instead of:
1
var material = pack.createObject('o3d.Material');
You would write:
1
let material = pack.CreateMaterial()
This makes its use a lot safer, and eliminates the risk for hard-to-find bugs due to typos in the string.

Why is it shorter?

When we translated the snooker to WebSharper, we modified it to a more idiomatic functional style. For example, a loop like the following in JavaScript:
1
2
3
4
5
6
for (i = 0; i < arr.length; ++i)
{
  var element = arr[i];
  // do things with element
}
is written in F# as:
1
2
3
4
arr |> Array.iter (fun element ->
  // do things with element
)
This style makes it more immediately apparent that we are actually iterating over the elements of arr, and that no other criterion interferes with the control flow. As an appreciable extra, it makes the code shorter by several lines.



So, go ahead, try it and don't hesitate to have a look at the source!

O3D Extension for WebSharper available Core team

In our continuing effort to make the most powerful JavaScript tools available to WebSharper developers, we are releasing the extension for Google O3D. O3D is a 3D programming library built on top of WebGL. Its functionalities include:
  • A render graph allowing hierarchical management of objects, views and rendering passes;
  • Resource management: loading of individual resources (textures, models) or JSON object descriptions, convertible from COLLADA;
  • Algebraic operations for matrices, vectors and quaternions, integrated in the render graph;
  • Skinning primitives for bone-based animation and deformation.
    The following sample, displaying a rotating cube, shows how O3D abstracts away most of WebGL.

The following sample, displaying a rotating cube, shows how O3D abstracts away most of WebGL.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
[<JavaScript>]
let vertexShaderString = "
    attribute vec4 position;
    uniform mat4 world;
    uniform mat4 view;
    uniform mat4 projection;

    void main() {
        gl_Position = projection * view * world * position;
    }"

[<JavaScript>]
let pixelShaderString = "
    void main() {
        gl_FragColor = vec4(1, 0, 0, 1);  // Red.
    }"

[<JavaScript>]
let createCube (pack : O3D.Pack) (material : O3D.Material) =
    let cubeShape = pack.CreateShape()
    let streamBank = pack.CreateStreamBank()
    let positionsArray = [|
        -0.5; -0.5;  0.5;    0.5; -0.5;  0.5;  // vertex 0, 1
        -0.5;  0.5;  0.5;    0.5;  0.5;  0.5;  // vertex 2, 3
        -0.5;  0.5; -0.5;    0.5;  0.5; -0.5;  // vertex 4, 5
        -0.5; -0.5; -0.5;    0.5; -0.5; -0.5;  // vertex 6, 7
    |]
    let indicesArray = [|
        0; 1; 2;   2; 1; 3;  // face 1
        2; 3; 4;   4; 3; 5;  // face 2
        4; 5; 6;   6; 5; 7;  // face 3
        6; 7; 0;   0; 7; 1;  // face 4
        1; 7; 3;   3; 7; 5;  // face 5
        6; 0; 4;   4; 0; 2;  // face 6
    |]
    let positionsBuffer = pack.CreateVertexBuffer()
    let positionsField = positionsBuffer.CreateFloatField(3)
    positionsBuffer.Set positionsArray |> ignore
    let indexBuffer = pack.CreateIndexBuffer()
    indexBuffer.Set indicesArray |> ignore
    streamBank.SetVertexStream(O3D.Stream.POSITION, 0, positionsField, 0) |> ignore
    let cubePrimitive = pack.CreatePrimitive(Material = material,
                                             Owner = cubeShape,
                                             StreamBank = streamBank,
                                             primitiveType = O3D.Primitive.TRIANGLELIST,
                                             NumberPrimitives = 12,
                                             NumberVertices = 8,
                                             IndexBuffer = indexBuffer)
    cubePrimitive.CreateDrawElement(pack, null)
    cubeShape

[<JavaScript>]
let g_clock = ref 0.

[<JavaScript>]
let renderCallback (cubeTransform : O3D.Transform) (event : O3D.RenderEvent) =
    g_clock := !g_clock + event.ElapsedTime
    cubeTransform.Identity()
    cubeTransform.RotateY(2. * float !g_clock)

[<JavaScript>]
let Samples() =
    Div [Attr.Id "o3d"; Attr.Style "width: 600px; height: 600px;"]
    |>! OnAfterRender (fun d ->
        O3DJS.Webgl.MakeClients (fun clients ->
            let client = As<O3D.Client> (JavaScript.Get "client" clients.[0])
            let pack = client.CreatePack()
            let viewInfo = O3DJS.Rendergraph.CreateBasicView(pack, client.Root,
                                                             client.RenderGraphRoot)
            viewInfo.DrawContext.Projection <-
                O3DJS.Math.Matrix4.Perspective(O3DJS.Math.DegToRad 30.,
                                               float client.Width/float client.Height,
                                               1., 5000.)
            viewInfo.DrawContext.View <- O3DJS.Math.Matrix4.LookAt((0., 1., 5.),
                                                                   (0., 0., 0.),
                                                                   (0., 1., 0.))
            let redEffect = pack.CreateEffect()
            redEffect.LoadVertexShaderFromString vertexShaderString |> ignore
            redEffect.LoadPixelShaderFromString pixelShaderString |> ignore
            let redMaterial = pack.CreateMaterial(DrawList = viewInfo.PerformanceDrawList,
                                                  Effect = redEffect)
            let cubeShape = createCube pack redMaterial
            let cubeTransform = pack.CreateTransform(Parent = client.Root)
            cubeTransform.AddShape cubeShape
            client.SetRenderCallback (renderCallback cubeTransform))
    )



You can download the WebSharper Extension for O3D at this address.

RESTful Web Conversations 2 Community

Having created a back-end using the new WCF Web API, I decided it was time to create a front-end and, not being a particular fan of JavaScript, went with WebSharper instead. Here’s a brief experience report. Source code is, as always, available here: https://bitbucket.org/nesteruk/restfulwebconversation JSONP, again… Before doing anything, I mirrored the conversation data structure [...]
>> Read the full article on devtalk.net