Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Highlights of F# lightning talk

1,203 views

Published on

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Highlights of F# lightning talk

  1. 1. Some F# Highlights Matt Harrington http://blog.mbharrington.org mbh.work@gmail.com @mh415
  2. 2. Features • Multiparadigm: FP, OO, imperative • Managed runtime • Statically typed • Immutable by default • Eager evaluation by default • Impure – allows side effects
  3. 3. 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
  4. 4. Robin Milner University of Edinburgh ML – 1970s Xavier Leroy, et al. INRIA, France Ocaml - 1996 Don Syme MSR Cambridge F# - 2002
  5. 5. Where is it used? • Windows x64 driver verification • adCenter • Halo 3 – Xbox live • Amyris • Credit Suisse • WebSharper • Avalda – F# to FPGA • F# itself
  6. 6. Source: http://vslab.codeplex.com
  7. 7. 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
  8. 8. OO • Classes • Inheritance • Extension methods • Interfaces • Structs • Properties • Delegates • Enums • Mutability: let mutable n = 5
  9. 9. Totally subjective beta slide Scala F# HaskellJava C# 100101 00011 01000 00000 00001 000100 λ Not to scale!
  10. 10. 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
  11. 11. Tail Call Optimization .method public static int32 g(int32 x) cil managed { .maxstack 5 L_0000: nop L_0001: ldarg.0 L_0002: ldc.i4.0 L_0003: ble.s L_0007 L_0005: br.s L_0009 L_0007: br.s L_0019 L_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 }
  12. 12. Discriminated Unions type Nucleotide = | Adenine | Guanine | Tyrosine | Cytosine
  13. 13. Discriminated Unions (cont.) type BinaryTree = | Node of int * BinaryTree * BinaryTree | Empty 2 1 4 3 5 From "Programming F#" by Chris Smith, p. 72
  14. 14. Units of Measure [<Measure>] type kilogram let bowlingBall = 7.26<kilogram> let force (mass : float<kilogram>) = mass * 9.8
  15. 15. Pipeline operator |> let numbers = [1 .. 100] let square x = x * x let sumOfSquares = numbers |> List.map square |> List.sum
  16. 16. 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 isPrime let 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
  17. 17. More… • Matt Harrington: mbh.work@gmail.com, @mh415, blog.mbharrington.org • SFsharp.org • Luca Bolognese’s video (see links on SFsharp.org) • Programming F# by Chris Smith

×