Phil Trelford's Array
POKE 36879, 255

PacMan Kata

January 11, 2012 11:37 by phil

F#unctional LondonersThe F#unctional Londoners Meetup Group will be starting 2012 with a code Kata on Thursday January 26th at 6:30pm at Skills Matter.

 
Kata

The term Kata comes from martial arts. A code Kata is a short programming exercise for practicing an aspect of software development.

C64_explodingfistBack in November in the Programming with the Stars session at the Progressive F# Tutorials our celebrities Mark Needham and Mark Seemann took on the Tennis Kata, first in C# and then F#.

As the two Mark’s talked through their solutions a number of people worked on their own versions, 2 of which you can see on the F# Snippets site:


PacMan
Scanning over the Kata catalogue for ideas the PacMan Kata bit me immediately.

    Pacman finds himself in a grid filled with monsters. Will he be able to eat all the dots on the board before the monsters eat him?

    maze

    To get things started I’ve built up a maze and some graphics. You can see an example over on F# Snippets that runs in the browser on http://tryfsharp.org which uses Silverlight: PacMan Maze

    I’ve also created a repository on BitBucket with sample projects for Visual Studio 2010 targeting WPF, Silverlight and HTML/JavaScript.

    The Javascript version uses the Pit compiler, you can see it running here. (Keys Q/A/Z/X *only in IE)

     


    Look forward to seeing you at the event.


    Tags:
    Categories: F# | Silverlight | WPF | .Net | JavaScript
    Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

    Sixes and Sevens

    November 20, 2011 06:53 by phil

    A few weeks back I built a simple console application with my 9yo using F# for practicing the times tables.

    TimesTable

    So that he could share the game with his friends at school I followed Attwood’s law and created a JavaScript version.

    Times Tables Java Script

    However I wasn’t particularly satisfied with this JavaScript version. Among other things, in the F# version I was able to easily do a timed count down before the game starts:

    for message in ["Get Ready";"3";"2";"1";"Go"] do 
        printfn "%s" message
        Thread.Sleep 1000

    To do the same thing in JavaScript would require nesting calls to Window setTimeout, which is neither readable or maintainable. I decided to skip this, but in doing so lost some of the aesthetic of the original implementation.

    With the recent release of the Pit project that compiles F# code to JavaScript, just over a week ago, I thought I’d revisit the game. Using F# computation expressions (a mechanism used to implement F# Async workflows), it was possible to implement the get ready sequence relatively cleanly:

    delay {
        root.InnerHTML <- "3"
        do! Delay 1000
        root.InnerHTML <- "2"
        do! Delay 1000
        root.InnerHTML <- "1"
        do! Delay 1000
        root.InnerHTML <- "Go"
        do! Delay 1000
        play total root
    }

    This generates the following quite heavily nested JavaScript:

    SevenSixes.App.countdown = function (total) {
       return function (root) {
          return function (builder) {
             return builder.Delay(function () {
                root.innerHTML = "3";
                return builder.Bind({
                   Item1: new SevenSixes.App.Delay.Delay(1000),
                   Item2: function (_arg5) {
                      root.innerHTML = "2";
                      return builder.Bind({
                         Item1: new SevenSixes.App.Delay.Delay(1000),
                         Item2: function (_arg4) {
                            root.innerHTML = "1";
                            return builder.Bind({
                               Item1: new SevenSixes.App.Delay.Delay(1000),
                               Item2: function (_arg3) {
                                  root.innerHTML = "Go";
                                  return builder.Bind({
                                     Item1: new SevenSixes.App.Delay.Delay(1000),
                                     Item2: function (_arg2) {
                                        SevenSixes.App.play(total)(root);
                                        return builder.Zero();
                                     }
                                  });
                               }
                            });
                         }
                      });
                   }
                });
             });
          } (SevenSixes.App.get_delay);
       };
    };

    Basically code gets mapped to a Bind method that runs a function after a specified timeout:

    type Delay = Delay of int
    type DelayBuilder() =
        [<Js>] member x.Bind(Delay t, f:unit->unit) = window.SetTimeout(f, t)
        [<Js>] member x.Return(t)  = fun () -> t
        [<Js>] member x.Delay(f:unit->'a) = f()
        [<Js>] member x.Zero () = ()
    let [<Js>] delay = DelayBuilder()

    So without further ado, click below to play the game:

    12x3

    As far as I’ve tested the game seems to run on IE9, Mozilla and Chrome browsers, along with Blackberry, iPhone and Windows Phone 7 (Mango).

    P.S. If you have an Android phone, please let me know if the game works for you.

    Resources


    Tags:
    Categories: F# | JavaScript
    Actions: E-mail | Permalink | Comments (2) | Comment RSSRSS comment feed

    Compiling F# to JavaScript with Pit

    November 14, 2011 11:15 by phil

    JavaScript is the old new thing.

    First shipped in Netscape Navigator 2.0 in 1995, JavaScript is supported by most popular browsers. Because of this, JavaScript has become an intermediate language for other languages to target. CoffeeScript (late 2009), ClojureScript (2011) and Dart (2011) are relatively recent examples of languages targeting JavaScript.

    The F# programming language makes it relatively easy to transform F# code to another form through a feature called code quotations. Simply annotating F# code with the ReflectedDefinition attribute makes it available as a quotation at runtime. Aliasing this attribute to say JavaScript or Js allows you to declaratively specify which code to generate.

    There are a number of tools providing support for targeting JavaScript from F#. FSharp.WebTools by Tomas Petricek, among other things, targeted JavasScript from F# way back in 2007. FSharp.JavaScript simply converts F# to JavaScript. While WebSharper is a commercial product with advanced features.

    Enter Pit

    Pit is a new F# to JavaScript compiler community project released just a few days ago. And it’s early days at version 0.1, but it’s already very useable.

    Check out the samples and documentation.

    Download and run the setup project, and within seconds a new Pit application project type is added to Visual Studio. This produces a simple hello world app:

    let [<Js>] main() =        
        alert("Hello World!!!")

    On top of the usual alert box debugging for JavaScript, Pit lets you set breakpoints!

    So far I’ve found Pit very intuitive to develop against.

    This was my first app in Pit, a simple calculator:

    PitCalc

    Which runs happily on iPhone, Blackberry and WP7! All from 80 odd lines of code:

    namespace Pit
    
    open Pit
    open Pit.Dom
    
    module Calculator =
    
        let [<Js>] (?) (el:DomElement) name =
            el.GetAttribute(name)
        let [<Js>] (?<-) (el:DomElement) name value =
            el.SetAttribute(name,value)
        type DomAttribute = { Name:string; Value:obj }
        let [<Js>] (@=) name (value:'a) =
            { Name=name; Value=box value }
        let [<Js>] tag name (attributes:DomAttribute list) =
            let el = document.CreateElement(name)
            for a in attributes do el.SetAttribute(a.Name,a.Value.ToString())
            el
    
        let [<Js>] display =
            tag "input" ["type"@="text";"value"@=0;"style"@="text-align:right"]
        let [<Js>] mutable operation : (int -> int) option = None
        let [<Js>] mutable append = false
    
        let [<Js>] clear () =
            display?value <- "0"
            append <- false
    
        let [<Js>] enter s =
            s, fun () ->
                let value = display?value
                if append then display?value <- value + s
                else display?value <- s; append <- true
    
        let [<Js>] calculate () =
            let value = int display?value
            operation |> Option.iter (fun op ->
                let newValue = op value
                display?value <- newValue.ToString() 
            )
            operation <- None
            append <- false
    
        let [<Js>] operator op () =
            calculate ()
            let value = display?value |> int
            operation <- op value |> Some
       
        let [<Js>] add = (+) 
        let [<Js>] sub = (-)
        let [<Js>] mul = (*)
        let [<Js>] div = (/)
    
        let [<Js>] buttons =
            [[enter "7"; enter "8"; enter "9"; "/", operator div]
             [enter "4"; enter "5"; enter "6"; "*", operator mul]
             [enter "1"; enter "2"; enter "3"; "-", operator sub]
             ["C", clear; enter "0"; "=", calculate; "+", operator add]]
    
        [<DomEntryPoint>]
        let [<Js>] main() =
            let table = (tag "table" [] |> DomTable.Of)  
            let tr = tag "tr" []
            let td = tag "td" ["colspan"@="4"]
            td.AppendChild display
            tr.AppendChild td 
            table.AppendChild tr 
            buttons |> List.iter (fun row ->
                let tr = tag "tr" [] 
                row |> List.iter (fun (text,action) ->
                    let td = tag "td" []
                    let input = 
                        tag "input" 
                            ["type"@="button";"value"@=text;"style"@="width:32px"]
                    input |> Event.click |> Event.add (fun _ -> action ())
                    td.AppendChild input
                    tr.AppendChild td
                )
                table.AppendChild tr
            )
            let div = document.GetElementById "calculator"
            div.AppendChild table

    Operator Overload


    For convenience the code above makes use of some F# operator overloading.

    The dynamic lookup operator is overloaded for getting and setting attributes:

    let [<Js>] (?) (el:DomElement) name =
        el.GetAttribute(name)
    let [<Js>] (?<-) (el:DomElement) name value =
        el.SetAttribute(name,value)

    This can be used to get and set the value of the input tag of the calculator’s display:

    let value = display?value
    display?value <- value

    The HTML input element for the calculator’s display is created dynamically:

    let [<Js>] display =
        tag "input" ["type"@="text";"value"@=0;"style"@="text-align:right"]

    The tag function creates a HTML element from a specified name and a list of attributes:

    let [<Js>] tag name (attributes:DomAttribute list) =
        let el = document.CreateElement(name)
        for a in attributes do el.SetAttribute(a.Name,a.Value.ToString())
        el

    And a custom operator (@=) creates an attribute record:

    type DomAttribute = { Name:string; Value:obj }
    let [<Js>] (@=) name (value:'a) =
        { Name=name; Value=box value }

    JavaScript as an Intermediate Language?


    Q: Why use an expressive statically typed high-level language like F# over plain JavaScript?

    A: This will probably come down to a mixture of problem context and personal preference.

    Certain problems, like parsing, are easy in F#. Alexander Stojanovic sums it up well:

    You must understand a (programming) language as a way of seeing. Languages don't just express thoughts, they shape them.

    Validation code written in F# can be run on both the client, via JavaScript, and the server, via .Net IL code.

    An area of particular interest for the F# community is generating live samples from code snippets. The F# Snippets site let you target your snippet against Silverlight via tryfsharp.org or an echo of the console via tryfs.net. For example here a game of Missile Command or Tetris running as scripts.

    Pit’s build libraries offer the potential to run F# snippets via JavaScript.

    Resources



    Tags:
    Categories: F# | JavaScript
    Actions: E-mail | Permalink | Comments (1) | Comment RSSRSS comment feed