highlights of f# lightning talk
TRANSCRIPT
Features
• Multiparadigm: FP, OO, imperative
• Managed runtime
• Statically typed
• Immutable by default
• Eager evaluation by default
• Impure – allows side effects
Free, as in beer & speech
• Open source & cross-platform
• Apache 2.0 license
• Syntax highlighting for TextMate, vim, emacs, TextPad, jedit, and others.
• Free IDEs:
– MonoDevelop
– SharpDevelop
– Visual Studio Shell
Robin MilnerUniversity of EdinburghML – 1970s
Xavier Leroy, et al.INRIA, FranceOcaml - 1996
Don SymeMSR CambridgeF# - 2002
Where is it used?
• Windows x64 driver verification
• adCenter
• Halo 3 – Xbox live
• Amyris
• Credit Suisse
• WebSharper
• Avalda – F# to FPGA
• F# itself
Source: http://vslab.codeplex.com
FP buzzwords
• First class functions
• Immutability
• Recursion
• Type inference
• Pattern matching
• Lists, sequences, tuples, records, discriminated unions
• Option type
• Monads• Asynchronous
programming• Pipeline operator |>• Curried by default• Continuations• Memoization• Lazy evaluation
OO
• Classes• Inheritance• Extension methods• Interfaces• Structs• Properties• Delegates• Enums• Mutability: let mutable n = 5
Totally subjective beta slide
Scala
F#
HaskellJava
C#
10010100011010000000000001000100
λ
Not to scale!
Taming Asynchronous I/O
using System;using System.IO;using System.Threading;
public class BulkImageProcAsync{
public const String ImageBaseName = "tmpImage-";public const int numImages = 200;public const int numPixels = 512 * 512;
// ProcessImage has a simple O(N) loop, and you can vary the number// of times you repeat that loop to make the application more CPU-// bound or more IO-bound.public static int processImageRepeats = 20;
// Threads must decrement NumImagesToFinish, and protect// their access to it through a mutex.public static int NumImagesToFinish = numImages;public static Object[] NumImagesMutex = new Object[0];// WaitObject is signalled when all image processing is done.public static Object[] WaitObject = new Object[0];public class ImageStateObject{
public byte[] pixels;public int imageNum;public FileStream fs;
}
public static void ReadInImageCallback(IAsyncResult asyncResult){
ImageStateObject state = (ImageStateObject)asyncResult.AsyncState;Stream stream = state.fs;int bytesRead = stream.EndRead(asyncResult);if (bytesRead != numPixels)
throw new Exception(String.Format("In ReadInImageCallback, got the wrong number of " +"bytes from the image: {0}.", bytesRead));
ProcessImage(state.pixels, state.imageNum);stream.Close();
// Now write out the image.// Using asynchronous I/O here appears not to be best practice.// It ends up swamping the threadpool, because the threadpool// threads are blocked on I/O requests that were just queued to// the threadpool. FileStream fs = new FileStream(ImageBaseName + state.imageNum +
".done", FileMode.Create, FileAccess.Write, FileShare.None,4096, false);
fs.Write(state.pixels, 0, numPixels);fs.Close();
// This application model uses too much memory.// Releasing memory as soon as possible is a good idea, // especially global state.state.pixels = null;fs = null;// Record that an image is finished now.lock (NumImagesMutex){
NumImagesToFinish--;if (NumImagesToFinish == 0){
Monitor.Enter(WaitObject);Monitor.Pulse(WaitObject);Monitor.Exit(WaitObject);
}}
}
public static void ProcessImagesInBulk(){
Console.WriteLine("Processing images... ");long t0 = Environment.TickCount;NumImagesToFinish = numImages;AsyncCallback readImageCallback = new
AsyncCallback(ReadInImageCallback);for (int i = 0; i < numImages; i++){
ImageStateObject state = new ImageStateObject();state.pixels = new byte[numPixels];state.imageNum = i;// Very large items are read only once, so you can make the // buffer on the FileStream very small to save memory.FileStream fs = new FileStream(ImageBaseName + i + ".tmp",
FileMode.Open, FileAccess.Read, FileShare.Read, 1, true);state.fs = fs;fs.BeginRead(state.pixels, 0, numPixels, readImageCallback,
state);}
// Determine whether all images are done being processed.// If not, block until all are finished.bool mustBlock = false;lock (NumImagesMutex){
if (NumImagesToFinish > 0)mustBlock = true;
}if (mustBlock){
Console.WriteLine("All worker threads are queued. " +" Blocking until they complete. numLeft: {0}",NumImagesToFinish);
Monitor.Enter(WaitObject);Monitor.Wait(WaitObject);Monitor.Exit(WaitObject);
}long t1 = Environment.TickCount;Console.WriteLine("Total time processing images: {0}ms",
(t1 - t0));}
}
let ProcessImageAsync () =async { let inStream = File.OpenRead(sprintf "Image%d.tmp" i)
let! pixels = inStream.ReadAsync(numPixels)let pixels' = TransformImage(pixels,i)let outStream = File.OpenWrite(sprintf "Image%d.done" i)do! outStream.WriteAsync(pixels') }
let ProcessImagesAsyncWorkflow() =Async.Run (Async.Parallel
[ for i in 1 .. numImages -> ProcessImageAsync i ])
Processing 200 images in parallel
Equivalent F#, more robust
Slide Credit:Don Syme
Tail Call Optimization
.method public static int32 g(int32 x) cil managed{
.maxstack 5L_0000: nopL_0001: ldarg.0 L_0002: ldc.i4.0 L_0003: ble.s L_0007L_0005: br.s L_0009L_0007: br.s L_0019L_0009: newobj instance void Program/g@9::.ctor()L_000e: ldarg.0 L_000f: ldc.i4.1 L_0010: sub L_0011: tail L_0013: call int32 Program::f(class [FSharp.Core]Microsoft.<snip>)L_0018: ret L_0019: ldarg.0 L_001a: ret
}
Discriminated Unions
type Nucleotide =
| Adenine
| Guanine
| Tyrosine
| Cytosine
Discriminated Unions (cont.)
type BinaryTree =
| Node of int * BinaryTree * BinaryTree
| Empty
2
1 4
3 5From "Programming F#" by Chris Smith, p. 72
Units of Measure
[<Measure>]
type kilogram
let bowlingBall = 7.26<kilogram>
let force (mass : float<kilogram>) = mass * 9.8
Pipeline operator |>
let numbers = [1 .. 100]
let square x = x * x
let sumOfSquares =
numbers |> List.map square
|> List.sum
Euler Problem #7
let isPrime num = let upperDivisor = int32(sqrt(float num)) match num with | 0 | 1 -> false | 2 -> true | n -> seq { 2 .. upperDivisor } |>
Seq.forall (fun x -> num % x <> 0)
let primes = Seq.initInfinite id |> Seq.filter isPrimelet nthPrime n = Seq.nth n primes
printfn "The 10001st prime number is %i." <| nthPrime 10000
Code from "Juliet" on http://stackoverflow.com/questions/3251957.
num |> float |> sqrt |> int
More…
• Matt Harrington: [email protected],@mh415, blog.mbharrington.org
• SFsharp.org
• Luca Bolognese’s video (see links on SFsharp.org)
• Programming F# by Chris Smith