taking functional programming into the mainstream - eclipse summit europe 2009
DESCRIPTION
Keynote from Eclipse Summit Europe 2009, presented by Don Syme from Microsoft Research.Over the last 10 years, Microsoft Research has been able to help progress functional programming to the point that it is now an accepted mainstream approach for certain problem domains. Now, with the increasing amount of data available to us, we need new ways of thinking around how to create scalable solutions in order to best exploit it as the multi-core revolution takes hold. Languages such as F#, Scala, Erlang and Haskell are well suited to this task as their functional programming style emphasize immutability, side effect free functions, compositional parallelism and asynchronous I/O. In this talk I will use F# as an extended example of how functional programming is becoming part of the mainstream, with ramifications across the spectrum of programming languages and platforms. We will look at why Microsoft and Microsoft Research is investing in functional programming, what this has meant for F#, C# and Haskell, and what we've done to build product-quality support for F#. Note: Examples will be given using Microsoft Visual Studio, though the talk is offered in the spirit of cooperation and progress across computing platforms.TRANSCRIPT
![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>