My First Avalon Application, in F#

A little story of how I spent my Sunday morning:

WinFX is Microsoft's next-generation API for Windows. Unlike the Win32 API, which is largely designed to be called from C, WinFX is a managed API designed to be used from any managed language. A preview WinFX SDK was released last week, so I decided to take a look at the API using my favourite language, F#. F# is a managed functional programming language written by Don Syme of Microsoft Research.

WinFX is a large API. Today I looked at Avalon, which is the part of WinFX that does graphics and UI. I decided to write the quintessential first program, Hello World. Here it is:

(* lets us conveniently construct colours from RGB triples *)

let color r g b =

      System.Windows.Media.Color.FromRgb(Byte.of_int r, Byte.of_int g, Byte.of_int b)

 

(* a couple of colours *)

let red = color 204 0 0

let black = color 0 0 0

 

(* Avalon application's OnStartingUp event builds its main

   window *)

let on_starting_up (event_args: System.Windows.StartingUpCancelEventArgs) =

      (* create a window *)

      let win = new System.Windows.Window() in

      win.Text <- "Hello, Avalon-F# World!";

     

      (* create a label *)

      let text = new System.Windows.Controls.TextBlock() in

      text.TextContent <- "Hello,\nAvalon-F# World!";

      text.FontFamily <- "Lucida Sans";

      text.FontSize <- System.Windows.FontSize.FromInches(0.8);

      text.TextAlignment <- System.Windows.TextAlignment.Center;

      text.VerticalAlignment <- System.Windows.VerticalAlignment.Center;

     

      (* this is Avalon, so need to do something vaguely pretty;

         here I'm adding a cool gradient to the label's text *)

      let brush = new System.Windows.Media.LinearGradientBrush() in

      brush.StartPoint <- new System.Windows.Point(0.0, 0.0);

      brush.EndPoint <- new System.Windows.Point(0.0, 1.0);

      brush.AddStop(red, 0.0);

      brush.AddStop(black, 1.0);

      text.Foreground <- (brush :> System.Windows.Media.Brush);

 

      (* add the label to the window *)

      win.Content <- (text :> obj);

     

      (* show the main window *)

      win.Show()

 

let _ =

      (* create and run Avalon application *)

      let app =

            { new System.Windows.Application() as base with

              OnStartingUp(event_args) =

                  base.OnStartingUp(event_args);

                  on_starting_up event_args } in

      app.Run()

Why no XAML?
Avalon programmers often write user interfaces in Extensible Application Markup Language (XAML). I decided to stick with F#. I'll tell you why: XAML lacks abstractional power. So although today's exercise would probably look quite neat in XAML, when I move on to more complex applications I want the power of F#.

What Next?
XAML is succinct because it is declarative, but I think an Avalon UI can probably be equally succinctly expressed in F# by defining combinators that work with Avalon dependency properties. This is where I plan to go next, and write a couple of applications on the way. (I have two specific ones in mind, but you'll have to wait!)

Loose Ends
I'm using F# 1.0.4.2. When you compile, fsc goes looking for fslib20b2.dll. I just added --cli-version 2.0b1 to the compiler command line options and everything works (so far! I think there have been some changes to collections. I haven't run into any problems yet, though.)

The syntax highlighting in this post is from cutting and pasting from Visual Studio. The F# distribution, available on Microsoft Research's downloads page, includes Visual Studio integration with syntax highlighting, autocomplete, and IntelliSense. It is really cool-- I recommend you download F# and give it a try.

If you're really observant, you will have noticed that this is not “my first Avalon application, in F#” (there's some prior art here) but “my first Avalon application in F#” (note the missing comma.) If you can call trivial Hello, Worlds applications other than in the System.Windows.Application sense. So my first Avalon application is either already written, or yet to be written, depending on your point of view.

Comments:


Way to go Dominic! Fantastic!
— Don Syme

Powered by Google App Engine
Custom Search