Tutorial

Introducing FunScript

Hello world

Click the following button to say hello to the world.

Say hello!
×

This example shows basic features of FunScript. It demonstrates how to use the TypeScript type provider to access standard DOM library functions and to call JavaScript libraries (such as JQuery).

Project structure

FunScript is a library that can be called in a number of ways. Most of the samples in the Examples directory follow the same pattern - they are executable programs that, when started, generate JavaScript source code (as *.js file) and run a simple HTTP web server that can be used to view the generated web.

In this mode, a typical project needs to reference FunScript.dll (containing the core JavaScript translator), FunScript.TypeScript.dll (a type provider that generates nice types for calling JavaScript libraries) and FunScript.TypeScript.Interop.dll (which is required by the TypeScript type provider).

All code that is translated to JavaScript needs to be marked with the FunScript.JS attribute (an alias for ReflectedDefinition):

1: 
2: 
3: 
4: 
5: 
[<FunScript.JS>]
module Page

open FunScript
open FunScript.TypeScript

The FunScript.TypeScript namespace contains the TypeScript provider, which is discussed in the next section.

Referencing the TypeScript provider

TypeScript is a language that extends JavaScript with types. It uses definition files (*.d.ts) to specify the types of existing JavaScript libraries. FunScript can import information from TypeScript definition files and generate F# types for accessing the DOM and calling external JavaScript libraries.

In this file we have imported definitions for jQuery and the JavaScript DOM.

Hello World

Let's now write a typical Hello world sample. The global window object available in the browser can be accessed using Globals.window. When you type Globals.window. in F#, you will get an autocomplete suggestion including the alert function:

1: 
2: 
let hello () =
  Globals.window.alert("Hello world!")

This snippet defines a function hello that can be translated to JavaScript (because the module is marked with the FunScript.JS attribute). It will be mapped to a simple JavaScript function that calls window.alert.

Next, we look how to use jQuery to access elements on the page and work with them. You can use any JavaScript library as long as there is a TypeScript definition for it (the Definitely Typed contains a number of them).

The $("...") command known from jQuery can be invoked by typing Globals.Dollar.Invoke("..."). To simplify the access to elements by ID, we can define the F# dynamic operator and write just jq?helloWorld instead of Globals.Dollar.Invoke("#helloWorld"). The following snippet gives the necessary definitions:

1: 
2: 
3: 
// Allows writing jq?name for element access
let jq(selector : string) = Globals.Dollar.Invoke selector
let (?) jq name = jq("#" + name)

The ? operator takes a parameter of type j.JQueryStatic which is a (generated) type that represents the type of jQuery. The details of the snippet are not important - the important fact is that we can now easily access DOM elements:

1: 
2: 
let main() = 
  jq?helloWorld.click(fun _ -> hello() :> obj)

The mainHello function will be later called when the web page is loaded. It gets the element with id helloWorld and registers the hello function as a handler for the click event.

Hosting the web page

As discussed earlier, many of the sample FunScript projects use a simple launcher. When the project is started, it generates JavaScript and hosts it via a simple web server. This launcher automatically looks for the main function (and so it finds the function in the above section). To start the launcher, the Page.fs file ends with the following line:

1: 
do Runtime.Run()
namespace FunScript
type JS = ReflectedDefinitionAttribute

Full name: FunScript.JS
module Page
namespace FunScript.TypeScript
val hello : unit -> unit

Full name: Page.hello
type Globals

Full name: FunScript.TypeScript.Globals
property Globals.window: Window
member Window.alert : ?message:string -> unit
val jq : selector:string -> JQuery

Full name: Page.jq
val selector : string
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = System.String

Full name: Microsoft.FSharp.Core.string
property Globals.Dollar: JQueryStatic
member JQueryStatic.Invoke : unit -> JQuery
member JQueryStatic.Invoke : element:Element -> JQuery
member JQueryStatic.Invoke : elementArray:Element array -> JQuery
member JQueryStatic.Invoke : _object:AnonymousType436 -> JQuery
member JQueryStatic.Invoke : _object:JQuery -> JQuery
member JQueryStatic.Invoke : callback:Function -> JQuery
member JQueryStatic.Invoke : selector:string * ?context:Element -> JQuery
member JQueryStatic.Invoke : html:string * attributes:Object -> JQuery
val jq : (string -> 'a)
val name : string
val main : unit -> JQuery

Full name: Page.main
type obj = System.Object

Full name: Microsoft.FSharp.Core.obj

Live demo

Click here to open the sample live, running using JavaScript in a dialog window.

To look at the generated JavaScript, view the source of this web page and scroll to the end of the file.

Tutorials

Learn FunScript from the following introductory tutorials

Samples

Browse other amazing samples created with FunScript

Fork me on GitHub