Quick Intro to F#
Calculating Moving Average in F#
Quick Intro to Silverlight
Visualizing F# Using Silverlight Toolkit
Agenda
Quick Intro to F#
Functional language developed by Microsoft Research 2002 language design started by Don Syme
2005 F# 1.0.1 public release (integration w/ VS2003)
2010 F# is “productized” and baked into VS2010
Multi-paradigm Functional/Imperative/OO/Language Oriented
Key characteristics Succinct, Type Inference (strongly typed), 1st class
functions
What is F#
Type inferencing
Strong typed
Functions as values
F# Intro
let a = 5
let b = 6.0
let c = “7 feet”
let d x = x * x
let e = d b
b is a float
d is a function
What data type is e?
The |> Combinator “Pipe Forward”
Example
F# Combinators
x |> f is the same as f x
let sqr x = x * x sqr 5 5 |> sqr
Moving Average in F#
Start with a list of numbers
Moving Average step 1
let testdata = [1.0 .. 10.0]
testdata is a list of floats
Create windows of the series
Moving Average step 2
Seq.windowed 4 testdata
it is a sequence of float arrays
Average the values in each array
Moving Average step 3
Array.average [|1.0; 2.0; 3.0; 4.0|]
Use Seq.map to calculate average of all arrays in the sequence
Moving Average step 4
let windowedData = Seq.windowed period data
Seq.map Array.average windowedData
the first argument is the function to apply to each item in the sequence
the second argument is the sequence
Use the pipe forward operator to put it together and omit the let
Moving Average step 5
Seq.windowed period data |> Seq.map Array.average
Put our algorithm into a function and test it
Moving Average function
let MovingAverage period data = Seq.windowed period data |> Seq.map Array.average
let testdata = [1.0 .. 10.0]let test = MovingAverage 4 testdata
Let’s generate some random data
open System
let GenerateData offset variance count = let rnd = new Random() let randomDouble variance = rnd.NextDouble() * variance let indexes = Seq.ofList [0..(count-1)] let genValue i = let value = float i + offset + randomDouble variance value Seq.map genValue indexes
let dataGenerator = GenerateData 50.0 100.0 200
Putting it together
let data1 = List.ofSeq dataGenerator
let data2 = List.ofSeq <| MovingAverage 10 data1
Time to visualize…
Quick Intro to Silverlight
What is Silverlight? Microsoft RIA plug-in for browsers
2007 Version 1.0 JavaScript based
2008 Version 2.0 .NET based
2009 Version 3.0 more controls, out of browser support (offline)
2010 Version 4.0 printing, COM, Multi-touch
Runs on multiple browsers/OS IE, Safari, Firefox, Chrome / Win, MacOS, Linux*
• via Mono Moonlight implementation
• WPF/E (original name)
VS 2008 Microsoft Silverlight 3 Tools for Visual Studio 2008
SP1
VS 2010 Built in support for Silverlight 3
Current RC requires “Silverlight 4 Tools for VS 2010”
http://www.silverlight.net/getstarted/silverlight-4/ RTM expected to include Silverlight 3 and 4 tools
built in
Visual Studio Integration
Visual Studio 2008 Using Luke Hoban’s F#
Silverlight templates
Visual Studio 2010 RC Built-in
F# Support for Silverlight in VS
http://code.msdn.microsoft.com/fsharpsilverlight
Silverlight Toolkit http://silverlight.codeplex.com/
Silverlight SDK Silverlight 3 SDK
Silverlight 4 SDK Beta
Graphing Controls
Visualizing F# using Silverlight Toolkit
Use the “Silverlight Application” template in Visual Studio Creates Silverlight Application (produces XAP)
Creates Web Application (hosts web site and XAP)
Create a Silverlight Application
Initial UserControl
Notice XML Namespaces (need to add more)
XAML
Add References
Add namespaces to XAML to support Silverlight Toolkit
xmlns:controls="clr-namespace: System.Windows.Controls; assembly=System.Windows.Controls"
xmlns:controlsToolkit="clr-namespace: System.Windows.Controls; assembly=System.Windows.Controls.Toolkit"
xmlns:chartingToolkit="clr-namespace: System.Windows.Controls.DataVisualization.Charting; assembly=System.Windows.Controls.DataVisualization.Toolkit"
xmlns:chartingPrimitivesToolkit="clr-namespace: System.Windows.Controls.DataVisualization.Charting.Primitives; assembly=System.Windows.Controls.DataVisualization.Toolkit"
Sample Series comes from Static Resource.
Define Static Resource in App.xaml
Add a chart to MainPage.xaml
add namespace
add sample dataset
Static Resource App.xaml
Similar to a Class Library project except it compiles with special options to target the Silverlight CLR
Use file links to share F# files between Class Library and Silverlight Library Add Existing File
Choose “Add As Link” from dropdown
Create an F# Silverlight Library
SeriesDataPoint is a class (type) that has two members, Index and Value
Used for series data
Add Chart Helper
type SeriesDataPoint(index, value) = member this.Index with get() = index member this.Value with get() = value
Used by XAML Designer to bind at design time
Add Sample Data Set
type SampleDataSet() = static member SampleSeries1 = let data = new ObjectCollection() data.Add(new SeriesDataPoint(0, 124.1)) data.Add(new SeriesDataPoint(1, 124.3)) data.Add(new SeriesDataPoint(2, 125.7)) data.Add(new SeriesDataPoint(3, 115.4)) data.Add(new SeriesDataPoint(4, 115.9)) data.Add(new SeriesDataPoint(5, 125.0)) data.Add(new SeriesDataPoint(6, 133.6)) data.Add(new SeriesDataPoint(7, 131.9)) data.Add(new SeriesDataPoint(8, 127.3)) data.Add(new SeriesDataPoint(9, 137.3)) data
Designer is now binding with F#
Code behind for MainPage.xaml
Use constructor to wire up events
Add code behind for MainPage
public partial class MainPage : UserControl{ public MainPage() { InitializeComponent(); SilverlightEvents.RegisterHandlers(this.LayoutRoot); }}
Event handling code for application in F#
SilverlightEvents in F#
Sample Button Click Event
buttonGenerateSampleData.Click.Add(fun(_) -> let data = GenerateDataPoints 125.0 10.0 10 let series = DataConverter.ConvertDataPointsToLineSeries "Sample Series 3" data chart.Series.Add(series) )
Slider Events - Mouse
member internal this.UpdateSeries() = m_range <- (int slider.Value) let movingAverage = MovingAverage m_range m_data let newSeries = this.GetMovingAverageSeries movingAverage chart.Series.[1] <- newSeries ()
slider.MouseLeftButtonUp.Add(fun(_) -> model.UpdateSeries())
Slider Events – Value Changed
slider.ValueChanged.Add(fun(callback) -> model.UpdateMovingAverage(callback))
member this.UpdateMovingAverage(args:RoutedPropertyChangedEventArgs<float>) = let oldVal = int args.OldValue let newVal = int args.NewValue if oldVal = newVal then () elif (Math.Abs(oldVal - newVal) > 4) then m_range <- newVal this.UpdateSeries() () else m_range <- newVal ()
Generate Data and Moving Average
Getting Started http://www.silverlight.net/getstarted/silverlight-4/
Tim Heuer’s Blog http://timheuer.com/blog/archive/2010/03/15/what
s-new-in-silverlight-4-rc-mix10.aspx
Silverlight 4 and Visual Studio 2010 RC
Bart Czernicki’s Silverlight Hack Blog http://www.silverlighthack.com/post/2009/11/04/S
ilverlight-3-and-FSharp-Support-in-Visual-Studio-2010.aspx
Luke Hoban’s WebLog http://blogs.msdn.com/lukeh/archive/2009/06/26/f
-in-silverlight.aspx
support for F# in VS 2008 http://code.msdn.microsoft.com/fsharpsilverlight
F# and Silverlight 2.0 http://jyliao.blogspot.com/2008/11/f-and-silverligh
t-20.html
Other Helpful Links
Thank you. Questions?F# and Silverlight
Talbott Crowell
ThirdM.com
http://talbottc.spaces.live.com
Twitter: @talbott and @fsug
http://fsug.org