![Page 1: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/1.jpg)
Taking Functional Programming into the MainstreamDon Syme, Principal ResearcherMicrosoft Research, Cambridge
![Page 2: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/2.jpg)
Disclaimer
• I’m a Microsoft Guy. I’m a .NET Fan. I will be using Visual Studio in this talk.
• This talk is offered in a spirit of cooperation and idea exchange. Please accept it as such
![Page 3: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/3.jpg)
Topics
• Why is Microsoft Investing in Functional Programming?
• Some Simple F# Programming
• A Taste of Parallel/Reactive with F#
• An Announcement
![Page 4: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/4.jpg)
Why is Microsoft investing in Functional Programming?
![Page 5: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/5.jpg)
What Investments?
• C# (Generics, LINQ)• F#• Reactive Framework• Haskell• VB, Python, Ruby
![Page 6: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/6.jpg)
Simplicity
![Page 7: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/7.jpg)
Economics
![Page 8: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/8.jpg)
Fun, Fun and More Fun!
![Page 9: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/9.jpg)
Simplicity
![Page 10: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/10.jpg)
Code!
//F#open Systemlet a = 2Console.WriteLine a
//C#using System;
namespace ConsoleApplication1{ class Program { static int a() { return 2; } static void Main(string[] args) { Console.WriteLine(a);
} }}
More Noise Than Signal!
![Page 11: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/11.jpg)
Pleasure type Command = Command of (Rover -> unit)
let BreakCommand = Command(fun rover -> rover.Accelerate(-1.0))
let TurnLeftCommand = Command(fun rover -> rover.Rotate(-5.0<degs>))
Pain abstract class Command { public virtual void Execute(); } abstract class MarsRoverCommand : Command { protected MarsRover Rover { get; private set; } public MarsRoverCommand(MarsRover rover) { this.Rover = rover; } } class BreakCommand : MarsRoverCommand { public BreakCommand(MarsRover rover) : base(rover) { } public override void Execute() { Rover.Rotate(-5.0); } } class TurnLeftCommand : MarsRoverCommand { public TurnLeftCommand(MarsRover rover) : base(rover) { } public override void Execute() { Rover.Rotate(-5.0); } }
![Page 12: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/12.jpg)
Pleasure
let swap (x, y) = (y, x)
let rotations (x, y, z) = [ (x, y, z); (z, x, y); (y, z, x) ]
let reduce f (x, y, z) = f x + f y + f z
Pain
Tuple<U,T> Swap<T,U>(Tuple<T,U> t){ return new Tuple<U,T>(t.Item2, t.Item1)}
ReadOnlyCollection<Tuple<T,T,T>> Rotations<T>(Tuple<T,T,T> t)
{ new ReadOnlyCollection<int> (new Tuple<T,T,T>[] { new
Tuple<T,T,T>(t.Item1,t.Item2,t.Item3); new
Tuple<T,T,T>(t.Item3,t.Item1,t.Item2); new
Tuple<T,T,T>(t.Item2,t.Item3,t.Item1); });}
int Reduce<T>(Func<T,int> f,Tuple<T,T,T> t) { return f(t.Item1) + f(t.Item2) + f
(t.Item3); }
![Page 13: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/13.jpg)
Pleasuretype Expr = | True | And of Expr * Expr | Nand of Expr * Expr | Or of Expr * Expr | Xor of Expr * Expr | Not of Expr
Painpublic abstract class Expr { } public abstract class UnaryOp :Expr { public Expr First { get; private set
; } public UnaryOp(Expr first) { this.First = first; } } public abstract class BinExpr : Expr { public Expr First { get; private set
; } public Expr Second { get; private se
t; } public BinExpr(Expr first, Expr seco
nd) { this.First = first; this.Second = second; } } public class TrueExpr : Expr { } public class And : BinExpr { public And(Expr first, Expr second)
: base(first, second) { } }public class Nand : BinExpr { public Nand(Expr first, Expr second)
: base(first, second) { } } public class Or : BinExpr { public Or(Expr first, Expr second) :
base(first, second) { } } public class Xor : BinExpr { public Xor(Expr first, Expr second)
: base(first, second) { } } public class Not : UnaryOp { public Not(Expr first) : base(first)
{ } }
![Page 14: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/14.jpg)
Economics
![Page 15: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/15.jpg)
Fun, Fun and More Fun!
![Page 16: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/16.jpg)
YouCanInteroperateWithEverything
![Page 17: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/17.jpg)
EverythingCanInteroperateWithYou
![Page 18: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/18.jpg)
F#: Influences
OCaml
C#/.NET
F#
Similar core language
Similar objectmodel
![Page 19: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/19.jpg)
F#: Combining Paradigms
I've been coding in F# lately, for a production task.
F# allows you to move smoothly in your programming style... I start with pure functional code, shift slightly towards an object-oriented style, and in production code, I sometimes have to do some imperative programming.
I can start with a pure idea, and still finish my project with realistic code. You're never disappointed in any phase of the project!
Julien Laugel, Chief Software Architect, www.eurostocks.com
![Page 20: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/20.jpg)
Let’s WebCrawl...
![Page 21: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/21.jpg)
Orthogonal & Unified Constructs
• Let “let” simplify your life…
let data = (1, 2, 3)
let f (a, b, c) = let sum = a + b + c let g x = sum + x*x (g a, g b, g c)
Bind a static value
Bind a static function
Bind a local value
Bind a local function
Type inference. The safety of C# with the
succinctness of a scripting language
![Page 22: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/22.jpg)
Quick Tour
Comments // comment
(* comment *)
/// XML doc commentlet x = 1
![Page 23: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/23.jpg)
Quick Tour
Booleansnot expr Boolean negationexpr && expr Boolean “and”expr || expr Boolean “or”
Overloaded Arithmeticx + y Addition x - y Subtraction x * y Multiplication x / y Division x % y Remainder/modulus -x Unary negation
![Page 24: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/24.jpg)
Fundamentals - Whitespace Matterslet computeDeriative f x = let p1 = f (x - 0.05)
let p2 = f (x + 0.05)
(p2 – p1) / 0.1
Offside (bad indentation)
![Page 25: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/25.jpg)
Fundamentals - Whitespace Matterslet computeDeriative f x = let p1 = f (x - 0.05)
let p2 = f (x + 0.05)
(p2 – p1) / 0.1
![Page 26: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/26.jpg)
Orthogonal & Unified Constructs
• Functions: like delegates + unified and simple
(fun x -> x + 1)
let f x = x + 1
(f, f)
val f : int -> int
Lambda
Declare afunction
A pair of function values
predicate = 'T -> bool
send = 'T -> unit
threadStart = unit -> unit
comparer = 'T -> 'T -> int
hasher = 'T -> int
equality = 'T -> 'T -> bool
One simple mechanism,
many uses
A function type
![Page 27: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/27.jpg)
Functional– Pipelines
x |> f
The pipeline operator
![Page 28: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/28.jpg)
Functional– Pipelines
x |> f1 |> f2 |> f3
Successive stages in a pipeline
![Page 29: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/29.jpg)
Functional – Pipelining
open System.IO
let files = Directory.GetFiles(@"c:\", "*.*", SearchOption.AllDirectories)
let totalSize = files |> Array.map (fun file -> FileInfo file) |> Array.map (fun info -> info.Length) |> Array.sum
Sum of file sizes
![Page 30: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/30.jpg)
Immutability the norm…
Values may not be
changed
Data is immutable by
default
Not Mutate
Copy & Update
![Page 31: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/31.jpg)
In Praise of Immutability
• Immutable objects can be relied upon
• Immutable objects can transfer between threads
• Immutable objects can be aliased safely
• Immutable objects lead to (different) optimization opportunities
![Page 32: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/32.jpg)
Functional Data – Generating Structured Data
type Suit = | Heart | Diamond | Spade | Club type PlayingCard = | Ace of Suit | King of Suit | Queen of Suit | Jack of Suit | ValueCard of int * Suit
Union type (no data =
enum)
Union type with data
![Page 33: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/33.jpg)
Functional Data – Generating Structured Data (2)
let suits = [ Heart; Diamond; Spade; Club ] let deckOfCards = [ for suit in suits do yield Ace suit yield King suit yield Queen suit yield Jack suit for value in 2 .. 10 do yield ValueCard (value, suit) ]
Generate a deck
of cards
![Page 34: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/34.jpg)
//F##lightopen Systemlet a = 2Console.WriteLine(a)
//C#using System;
namespace ConsoleApplication1{ class Program { static int a() { return 2; }
static void Main(string[] args)
{ Console.WriteLine(a);
} }}
Looks Weakly typed?
Maybe Dynamic?
Weakly Typed? Slow?
![Page 35: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/35.jpg)
Typed Untyped
EfficientInterpretedReflection
Invoke
F#Yet rich, dynamic
Yet succinct
![Page 36: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/36.jpg)
What is Functional Programming?
• “Working with immutable data”• “A language with queries”• “A language with lambdas” • “A language with pattern matching”• “A language with a lighter syntax”• “Taming side effects”
“Anything but imperative
programming”???
![Page 37: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/37.jpg)
Some Micro Trends
• Communication With Immutable Data
• Programming With Queries• Programming With Lambdas• Programming With Pattern Matching• Languages with a Lighter Syntax• Taming Side Effects
REST, HTML, XML, JSON, Haskell, F#, Scala, Clojure, Erlang,...
C#, VB, F#, SQL,
Kx....
C#, F#, Javascript,
Scala, Clojure
F#, Scala, ...
Python, Ruby, F#, ...
Erlang, Scala, F#, Haskell, ...
![Page 38: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/38.jpg)
The Huge Trends
THE WEB MULTICORE
![Page 39: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/39.jpg)
F# Objects
![Page 40: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/40.jpg)
F# - Objects + Functional
type Vector2D (dx:double, dy:double) =
member v.DX = dx member v.DY = dy member v.Length = sqrt (dx*dx+dy*dy) member v.Scale (k) = Vector2D (dx*k,dy*k)
Inputs to object
construction
Exported properties
Exported method
![Page 41: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/41.jpg)
F# - Objects + Functional
type Vector2D(dx:double,dy:double) =
let norm2 = dx*dx+dy*dy
member v.DX = dx member v.DY = dy member v.Length = sqrt(norm2) member v.Norm2 = norm2
Internal (pre-computed) values and functions
![Page 42: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/42.jpg)
F# - Objects + Functional
type HuffmanEncoding(freq:seq<char*int>) = ... < 50 lines of beautiful functional code> ...
member x.Encode(input: seq<char>) = encode(input) member x.Decode(input: seq<char>) = decode(input)
Immutable inputs
Internal tables
Publish access
![Page 43: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/43.jpg)
F# - Objects + Functional
type Vector2D(dx:double,dy:double) =
let mutable currDX = dx
let mutable currDX = dy
member v.DX = currDX member v.DY = currDY member v.Move(x,y) = currDX <- currDX+x currDY <- currDY+y
Internal state
Publish internal
state
Mutate internal
state
![Page 44: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/44.jpg)
OO andFunctionalCanMix
![Page 45: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/45.jpg)
Interlude: Case Study
![Page 46: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/46.jpg)
The adCenter Problem
![Page 47: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/47.jpg)
The Scale of Things
• Weeks of data in training: N,000,000,000 impressions, 6TB data
• 2 weeks of CPU time during training: 2 wks × 7 days × 86,400 sec/day =
1,209,600 seconds• Learning algorithm speed requirement:
• N,000 impression updates / sec• N00.0 μs per impression update
![Page 48: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/48.jpg)
F# and adCenter
• 4 week project, 4 machine learning experts
• 100million probabilistic variables
• Processes 6TB of training data
• Real time processing
![Page 49: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/49.jpg)
AdPredict: What We Observed
• Quick Coding
• Agile Coding
• Scripting
• Performance
• Memory-Faithful
• Succinct
• Symbolic
• .NET Integration
F#’s powerful type inference means less typing, more
thinking
Type-inferred code is easily refactored
“Hands-on” exploration.
Immediate scaling to massive data
setsmega-data
structures, 16GB machines
Live in the domain, not the language
Schema compilation and
“Schedules”Especially Excel, SQL Server
![Page 50: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/50.jpg)
Smooth Transitions
• Researcher’s Brain Realistic, Efficient Code
• Realistic, Efficient Code Component
• Component Deployment
Late 2009 Update... now part of Bing’s “sauce” for advertisers
![Page 51: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/51.jpg)
F# Async/Parallel
![Page 52: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/52.jpg)
F# is a Parallel Language
(Multiple active computations)
F# is a Reactive Language
(Multiple pending reactions)
e.g. GUI Event Page Load
Timer CallbackQuery ResponseHTTP Response
Web Service ResponseDisk I/O
CompletionAgent Gets Message
![Page 53: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/53.jpg)
async { ... }
• For users: You can run it, but it may take a while
Or, your builder says...
OK, I can do the job, but I might have to talk to someone else about it. I’ll get back to you when I’m done
async { ... }
A Building Block for Writing Reactive Code
![Page 54: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/54.jpg)
async { ... }
async.Delay(fun () -> async.Bind(ReadAsync "cat.jpg", (fun image -> let image2 = f image async.Bind(writeAsync "dog.jpg",(fun () -> printfn "done!" async.Return())))))
async { let! image = ReadAsync "cat.jpg" let image2 = f image do! WriteAsync image2 "dog.jpg" do printfn "done!" return image2 }
Continuation/Event callback
Asynchronous "non-blocking"
action
You're actually writing this (approximately):
![Page 55: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/55.jpg)
Code: Web Translation
![Page 56: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/56.jpg)
Typical F# Reactive Architecture
Single Threaded GUI
Or
Single Threaded Page Handler
Or
Command Line Driver
Async.Parallel [ ... ]
new Agent<_>(async { ... })
new WebCrawler<_>() Internally: new Agent<_>(...) ...
event x.Started event x.CrawledPage event x.Finished
...
Async.Start (async { ... }
(queued)
![Page 57: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/57.jpg)
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') do Console.WriteLine "done!" } let ProcessImagesAsyncWorkflow() = Async.Run (Async.Parallel [ for i in 1 .. numImages -> ProcessImageAsync i ])
Processing 200 images in parallel
![Page 58: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/58.jpg)
Units of Measure
![Page 59: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/59.jpg)
let EarthMass = 5.9736e24<kg>
// Average between pole and equator radiilet EarthRadius = 6371.0e3<m>
// Gravitational acceleration on surface of Earth let g = PhysicalConstants.G * EarthMass / (EarthRadius * EarthRadius)
![Page 60: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/60.jpg)
Microsoft + Eclipse Interoperability
For Vijay RajagopalanMicrosoft Interoperability Team
![Page 61: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/61.jpg)
•Enh
anc
e
Ecli
pse
dev
elop
er
exp
erie
nce
on
Win
dow
s 7
Eclipse on Windows 7
•Plu
g-in
for
Ecli
pse
to
buil
d
Silv
erli
ght
Rich
Inte
rnet
App
licat
ions
Eclipse Tools for
Silverlight
•Ena
ble
PHP
,
Java
dev
elop
ers
usin
g
Ecli
pse
to
buil
d &
depl
oy
on
Azu
re
Windows Azure +
Eclipse / PHP
Announcing: Projects fostering interoperability between Eclipse and Microsoft’s platform
![Page 62: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/62.jpg)
8 Ways to Learn Functional Programming
• F# + FSI.exe
• F# + Reflector
• Haskell
• Clojure
• http://cs.hubfs.net
• Scala
• C# 3.0
• ML
![Page 65: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/65.jpg)
Questions
![Page 66: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/66.jpg)
The many uses of async { ... }
• Sequencing CPU computations
• Sequencing I/O requests
async { let result1 = fib 39 let result2 = fib 40 return result1 + result2 }
async { let! lang = CallDetectLanguageService text let! text2 = CallTranslateTextService (lang, "da", text) return text2 }
![Page 67: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/67.jpg)
The many uses of async { ... }
• Parallel CPU computations
• Parallel I/O requests
Async.Parallel [ async { return fib 39 }; async { return fib 40 }; ]
Async.Parallel [ for targetLang in languages -> translate (text, language) ]
![Page 68: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/68.jpg)
The many uses of async { ... }
• Sequencing CPU computations and I/O requestsasync { let! lang = callDetectLanguageService text
let! text2 = callTranslateTextService (lang, "da", text) let text3 = postProcess text return text3 }
![Page 69: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/69.jpg)
The many uses of async { ... }
• Repeating tasks
• Repeating tasks with state
async { while true do let! msg = queue.ReadMessage() <process message> }
let rec loop count = async { let! msg = queue.ReadMessage() printfn "got a message" return! loop (count + msg) }
loop 0
let rec loop () = async { let! msg = queue.ReadMessage() printfn "got a message" return! loop () }loop ()
![Page 70: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/70.jpg)
The many uses of async { ... }
• Representing Agents (approximate) let queue = new Queue()
let rec loop count = async { let! msg = queue.ReadMessage() printfn "got a message" return! loop (count + msg) } Async.Start (loop 0)
queue.Enqueue 3queue.Enqueue 4
![Page 71: Taking Functional Programming Into The Mainstream - Eclipse Summit Europe 2009](https://reader035.vdocument.in/reader035/viewer/2022081414/54907a41b4795942548b4572/html5/thumbnails/71.jpg)
The many uses of async { ... }
• Representing Agents (real) let agent = Agent.Start( let rec loop count = async { let! msg = queue.ReadMessage() printfn "got a message" return! loop (count + msg) } loop 0)
agent.Post 3agent.Post 4Note:
type Agent<'T> = MailboxProcessor<'T>