Phillip Trelford's blog... evidently
when your only tool is an analogy, everything looks like a simile.

Units of measure auto-conversion

June 14, 2010 12:36 by phil

In a recent article I described some prototype F# code for defining runtime units of measure with similar functionality to F#’s compile time units of measure feature. The following code extends this prototype to provide auto-conversion when adding or multiplying unit values. Note that as unit conversion is done at runtime this implementation is also usable from C#. This allows for example the following calculations to succeed:

1km + 200m = 1200m

(1m/s) / 500milliseconds = 2m

To achieve this a new Measure type introduces Base Unit types and Measure multiples.

    Base Unit type examples 
  • length
  • mass
  • time
    Measure multiple examples 
  • Kilometres (1000)
  • Metres (1)
  • Millimetres (0.001)

Defining measure types:

let length = "length"
let time = "time"
let m = Measure("m", BaseUnit(length))
let km = Measure.Kilo(m)
let s = Measure("s", BaseUnit(time))
let milliseconds = Measure.Milli(s)

Measure type definition:

type MeasureType = 
    | BaseUnit of string
    | Multiple of Measure * ValueType
    with
    member this.BaseUnitName =
        let rec traverse = function
            | BaseUnit s -> s
            | Multiple(Measure(_,m),_) -> traverse m
        traverse this
and Measure = Measure of string * MeasureType with  
    member this.Name = match this with Measure(s,_) -> s
    member this.Type = match this with Measure(_,t) -> t   
    static member Kilo (m:Measure) = 
        Measure("k"+m.Name,Multiple(m,1000.0))  
    static member Milli (m:Measure) = 
        Measure("m"+m.Name,Multiple(m,0.001))
    static member ( * ) (v:ValueType,m:Measure) = UnitValue(v,Unit(m,1))

The add and multiply operations on a UnitValue now convert to the base unit if a dimensional unit mismatch exits (see Units conversion by factor-label):

and UnitValue = UnitValue of ValueType * UnitType with
    member this.Value = match this with UnitValue(v,_) -> v
    member this.Unit = match this with UnitValue(_,u) -> u
    override this.ToString() = sprintf "%O %O" this.Value this.Unit
    static member ToBaseUnit x =
        let rec toBaseUnit = function
            | UnitValue(v,(Unit(Measure(_,BaseUnit(_)),_))) as x -> 
                x
            | UnitValue(v,Unit(Measure(_,Multiple(quantity,coefficient)),p)) -> 
                toBaseUnit (UnitValue(v*coefficient, Unit(quantity,p)))            
            | UnitValue(v,(CompositeUnit(xs))) ->
                let v, ys =
                    (v,[]) |> List.foldBack (fun x (v,ys) -> 
                        let x = toBaseUnit (UnitValue(v,x))
                        x.Value, x.Unit::ys
                    ) xs
                UnitValue(v, CompositeUnit(ys)) 
        toBaseUnit x
    static member private DoesDimensionalUnitMismatchExist lhs rhs =
        let rec measures = function
            | Unit(m,_) -> Set.singleton (m)
            | CompositeUnit(us) ->
                us |> List.map measures |> Set.unionMany                          
        measures lhs |> Set.exists (fun x ->
            measures rhs |> Set.exists (fun y ->
                y.Type.BaseUnitName = x.Type.BaseUnitName 
                && not (x = y)  
            )
        )
    static member (+) (lhs:UnitValue,rhs:UnitValue) =                         
        if lhs.Unit = rhs.Unit then       
            UnitValue(lhs.Value+rhs.Value, lhs.Unit+rhs.Unit)             
        else             
            let x1 = UnitValue.ToBaseUnit lhs
            let x2 = UnitValue.ToBaseUnit rhs
            if x1.Unit = x2.Unit then
                UnitValue(x1.Value+x2.Value,x1.Unit+x2.Unit)
            else                                                      
                raise (new System.InvalidOperationException())                 
    static member (*) (lhs:UnitValue,rhs:UnitValue) =            
        if UnitValue.DoesDimensionalUnitMismatchExist lhs.Unit rhs.Unit then            
            let lhs = UnitValue.ToBaseUnit lhs
            let rhs = UnitValue.ToBaseUnit rhs
            UnitValue(lhs.Value*rhs.Value,lhs.Unit*rhs.Unit)
        else
            UnitValue(lhs.Value*rhs.Value,lhs.Unit*rhs.Unit)   
    static member (*) (lhs:UnitValue,rhs:ValueType) =                        
        UnitValue(lhs.Value*rhs,lhs.Unit)      
    static member (/) (lhs:UnitValue,rhs:UnitValue) =
        if UnitValue.DoesDimensionalUnitMismatchExist lhs.Unit rhs.Unit then            
            let lhs = UnitValue.ToBaseUnit lhs
            let rhs = UnitValue.ToBaseUnit rhs
            UnitValue(lhs.Value/rhs.Value,lhs.Unit/rhs.Unit)
        else                 
            UnitValue(lhs.Value/rhs.Value,lhs.Unit/rhs.Unit)   
    static member (/) (lhs:UnitValue,rhs:ValueType) =
        UnitValue(lhs.Value/rhs,lhs.Unit) 

The only change to the Unit type is that it references a Measure type instead of a literal string signifying the measure:

and UnitType =
    | Unit of Measure * int
    | CompositeUnit of UnitType list
    static member Create(m) = Unit(m,1)
    override this.ToString() =
        let exponent = function
            | Unit(_,n) -> n
            | CompositeUnit(_) ->                
                raise (new System.InvalidOperationException())
        let rec toString = function        
            | Unit(s,n) when n=0 -> ""
            | Unit(Measure(s,_),n) when n=1 -> s
            | Unit(Measure(s,_),n)          -> s + " ^ " + n.ToString()            
            | CompositeUnit(us) ->               
                let ps, ns = 
                    us |> List.partition (fun u -> exponent u >= 0)
                let join xs = 
                    let s = xs |> List.map toString |> List.toArray             
                    System.String.Join(" ",s)
                match ps,ns with 
                | ps, [] -> join ps
                | ps, ns ->
                    let ns = ns |> List.map UnitType.Reciprocal
                    join ps + " / " + join ns
        match this with
        | Unit(_,n) when n < 0 -> " / " + toString this
        | _ -> toString this        
    static member ( * ) (v:ValueType,u:UnitType) = UnitValue(v,u)    
    static member ( * ) (lhs:UnitType,rhs:UnitType) =
        let text = function
            | Unit(Measure(s,_),_) -> s
            | CompositeUnit(us) -> us.ToString()       
        let normalize us u =
            let t = text u
            match us |> List.tryFind (fun x -> text x = t), u with
            | Some(Unit(s,n) as v), Unit(_,n') ->
                us |> List.map (fun x -> if x = v then Unit(s,n+n') else x)                 
            | Some(_), _ -> raise (new System.NotImplementedException())
            | None, _ -> us@[u]
        let normalize' us us' =
            us' |> List.fold (fun (acc) x -> normalize acc x) us        
        match lhs,rhs with
        | Unit(u1,p1), Unit(u2,p2) when u1 = u2 ->
            Unit(u1,p1+p2)
        | Unit(u1,p1), Unit(u2,p2) ->            
            CompositeUnit([lhs;rhs])
        | CompositeUnit(us), Unit(_,_) ->
            CompositeUnit(normalize us rhs)
        | Unit(_,_), CompositeUnit(us) ->
            CompositeUnit(normalize' [lhs]  us)
        | CompositeUnit(us), CompositeUnit(us') ->
            CompositeUnit(normalize' us us')
        | _,_ -> raise (new System.NotImplementedException())
    static member Reciprocal x =
        let rec reciprocal = function
            | Unit(s,n) -> Unit(s,-n)
            | CompositeUnit(us) -> CompositeUnit(us |> List.map reciprocal)
        reciprocal x
    static member ( / ) (lhs:UnitType,rhs:UnitType) =        
        lhs * (UnitType.Reciprocal rhs)
    static member ( + ) (lhs:UnitType,rhs:UnitType) =       
        if lhs = rhs then lhs                
        else raise (new System.InvalidOperationException())
and ValueType = float

    Known issues
  • Operator precedence means 10 * m / 2 * s = 5 m s instead of 5 m /s
    - As a workaround use brackets, i.e. (10 * m) / (2 * s)
  • Conversions requiring constant difference like degrees to kelvins are not supported

UnitType.fs (7.17 kb)


Tags:
Categories: .Net | C# | F#
Actions: E-mail | Permalink | Comments (3) | Comment RSSRSS comment feed

Exposing F# Dynamic Lookup to C#, WPF & Silverlight

May 23, 2010 15:20 by phil

Like C#, F# is primarily a statically typed programming language. That said both languages provide support for dynamic typing.

Sometimes dynamic typing can be a pragmatic way of solving a specific problem. For example say you’re a solutions provider with a core product and have a number of clients with bespoke requirements. One client asks for a product rating feature. This can be relatively easily achieved using dynamic properties:

  • a bunch of client specific properties are read from the database, including the rating value, which is then set as a dynamic property on the product object
  • zero changes are required to the core code
  • at the UI, on WPF, the dynamic property can simply be bound through XAML like any other object property
  • on Silverlight 4,0 direct binding is not currently possible, however there is a simple workaround - specifying the dynamic property as a parameter for a value converter (example later)

C# and F# use slightly different approaches for dynamic properties:

  • C# 4.0 provides a dynamic type, which tells the compiler that member lookup on the object should be deferred to run time
  • F# employs a dynamic lookup operator, which when overloaded defines the behaviour at runtime. This means that in F# dynamic lookup is explicit (the ? operator), and can be mixed with static lookup on the same object (the . operator)

Is it is still possible to implement dynamic properties in F# that can be consumed by other .Net languages like C#, VB.Net, IronRuby or IronPython; plus WPF and Silverlight. The trick is to inherit from .Net 4.0’s System.Dynamic.DynamicObject type and implement the System.ComponentModel.INotifyPropertyChanged interface:

open System.Dynamic

/// Dynamic Lookup type
type DynamicLookup () =
    inherit DynamicObject ()
    /// Synchronization object
    let sync = obj()
    /// Property Changed event
    let propertyChanged = Event<_,_>()    
    /// Properties
    let mutable properties = Map.empty
    /// Gets property value
    member private this.GetValue name = 
        Map.tryFind name properties
    /// Sets property value, creating a new property if none exists
    member private this.SetValue (name,value) =
        /// Atomically writes new properties reference
        let Write () = 
            properties <-
                properties 
                |> Map.remove name 
                |> Map.add name value
        // Synchronize property writes
        lock sync Write
        // Trigger property changed event
        (this,System.ComponentModel.PropertyChangedEventArgs(name))
        |> propertyChanged.Trigger    
    override this.TryGetMember(binder:GetMemberBinder,result:obj byref ) =     
        match this.GetValue binder.Name with
        | Some value -> result <- value; true
        | None -> false
    override this.TrySetMember(binder:SetMemberBinder, value:obj) =        
        this.SetValue(binder.Name,value)
        true
    override this.GetDynamicMemberNames() =
        properties |> Seq.map (fun pair -> pair.Key)
    [<CLIEvent>]
    member this.PropertyChanged = propertyChanged.Publish
    interface System.ComponentModel.INotifyPropertyChanged with
        [<CLIEvent>]
        member this.PropertyChanged = propertyChanged.Publish     
    static member (?) (lookup:#DynamicLookup,name:string) =
        match lookup.GetValue name with
        | Some(value) -> value
        | None -> raise (new System.MemberAccessException())        
    static member (?<-) (lookup:#DynamicLookup,name:string,value:'v) =
        lookup.SetValue (name,value)
    static member GetValue (lookup:DynamicLookup,name) =
        lookup.GetValue(name).Value

F# usage:

/// Product type inherits dynamic lookup
type Product (name,price) =
    inherit DynamicLookup ()
    member this.Name = name
    member this.Price = price
 
// Initiate product object with dynamic rating value
let p = Product("F# for Scientists",49.95M)
do p?Stars <- 5
// Access product's properties
let stars = System.Convert.ToInt32(p?Stars)
do printf "%s...%M %s" p.Name p.Price (System.String('*',stars))

C# usage:

// Create Product type with dynamic stars value
Product product = new Product("Expert F#",54.99M);
((dynamic)product).Stars = 5;       
// Read product properties
dynamic p = product;
string s = 
    string.Format("{0}...{1} {2}",
        p.Name, p.Price, new String('*', (int) p.Stars));

Use from Silverlight 4.0

<t:PropertyLookup x:Key="DynamicConverter"/>

 

<TextBox Text="{Binding Converter={StaticResource DynamicConverter},
                ConverterParameter=Stars}"/>

 

dynamic product = new Product("Real World FP", 35.99);
product.Stars = 5;
DataContext = product;

 

public class PropertyLookup : IValueConverter
{
    public object Convert(
        object value, 
        Type targetType, 
        object parameter, 
        CultureInfo culture)
    {        
        return DynamicLookup.GetValue(
            (DynamicLookup) value,
            (string) parameter);            
    }

    public object ConvertBack(object value, 
        Type targetType, 
        object parameter, 
        CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Note: Silverlight 4.0 requires Microsoft.CSharp.dll to use dynamic types.


Tags:
Categories: F# | WPF | Silverlight | Architecture | .Net | C#
Actions: E-mail | Permalink | Comments (4) | Comment RSSRSS comment feed

MVMMC – MVVM grows a Controller

May 19, 2010 15:27 by phil

Ray Booysen does it again! The first time I saw Ray do a talk was at NxtGen in Cambridge, when he gave me a timely introduction to MVVM just as I was starting to play with WPF. MVVM (Model-View-View Model) is an architectural pattern, that improves on code behind, making it possible to unit test your UI code (View Model), a good thing. Over a year later and I’m just starting to play with Silverlight, Ray delivers another timely talk on Silverlight gotchas at the Edge UG in London, based on his real-world development experience (developing Financial applications). This time he introduces among other good things MVVMC (MVVM plus Controller). Here the controller takes responsibility for communication between the Model and View Model, leaving the View Model with the single responsibility of providing data to the View.

Somewhat shell shocked I was left with a few questions on implementation details, again Ray to the rescue via Twitter:

ptrelford Excellent @raybooysen Silverlight gotchas talk - MVVMC (C for controller), Network is on UI thread, browser connection limits #edgeug

ptrelford @raybooysen really liked Fat Controller slide, of Thomas the Tank Engine; controller takes responsiblity for marshalling threads etc #edgeug

raybooysen @ptrelford fat controller should be in all slide decks. :)

raybooysen Talk finished at @edge_ug. Think it went ok. Feel like I rambled a little.

ptrelford So with MVVMC the Model is observed by a Controller, which constructs & updates a View Model, which the (XAML) View binds to

raybooysen @ptrelford thanks for coming tonight. :)

ptrelford @raybooysen using MVVMC the Controller observes the Model & updates View Model, which observes user input and passes messages to the Model?

raybooysen @ptrelford viewmodel observes and notifies the the controller.

ptrelford @raybooysen thanks! So View Model takes a reference to the parent controller?

raybooysen @ptrelford no. Can surface the ui interaction via events. Or use rx if you're in for some fun.

ptrelford @raybooysen Cool thanks again! That makes sense, View Model exposes IObservable<T> properties. BTW your talk blew me away (hence questions)!

raybooysen @ptrelford no worries. Iobservable feels quite right in these scenarios. Since controller essentially owns the viewmodel

Finally, this was the same talk that Ray delivered at DDD Scotland, so the slides are already available here

image

image

image

 

image


Tags:
Categories: C# | .Net | Architecture | WPF | Silverlight
Actions: E-mail | Permalink | Comments (2) | Comment RSSRSS comment feed

F# Agents and Retlang: quick comparison

March 14, 2010 09:27 by phil

Erlang style message passing is a great way of simplifying concurrency. The open source Retlang library aims to bring some of the benefits to .Net languages like C# and VB.Net. Whereas F# has built-in message passing support with the MailboxProcessor also referred to as Agents. To compare Retlang against F# Agents I have coded up the Retlang Summation example (171 lines) as an equivalent F# implementation (41 lines):

type Agent<'a> = MailboxProcessor<'a>

type Summation =
    | Add of int
    | Total of AsyncReplyChannel<int>    
and SummationAgent () =
    let agent = Agent.Start ( fun inbox ->    
        let rec loop total =
            async {
            let! message = inbox.Receive()
            match message with 
            | Add n -> do! loop (n + total)
            | Total reply -> reply.Reply(total)
            }
        loop 0
    )    
    /// Adds value to total
    member this.Add n = Add(n) |> agent.Post
    /// Returns total and ends computation
    member this.Total () = (fun reply -> Total(reply)) |> agent.PostAndReply

/// Invokes specified function with numbers from 1 to limit
let numberSource f limit =
    async {
        for i = 1 to limit do
            f i            
            if i % 10 = 0 then System.Console.WriteLine("{0}\t({1})",i,limit)        
    }

do  /// Summation agent instance
    let agent = SummationAgent ()    
    // Post series of numbers to summation agent in parallel
    [100;50;200]
    |> Seq.map (numberSource agent.Add)
    |> Async.Parallel
    |> Async.RunSynchronously
    |> ignore    
    // Get total
    let value = agent.Total ()
    System.Diagnostics.Debug.Assert(26425 = value);
    value |> System.Console.WriteLine

 

If you compare this to the Retlang example implementation, it should be clear that C# is missing the easy message definition (discriminated unions) and pattern matching part of message passing. You may also notice that in the F# version, the functionality is accomplished, not only without locks, but also without any low-level threading primitives (like AutoResetEvent). However, if you find yourself constrained to C# development then Retlang is definitely worth a look.


Tags:
Categories: F# | .Net | Architecture | C#
Actions: E-mail | Permalink | Comments (1) | Comment RSSRSS comment feed

C# is not C

February 14, 2010 05:57 by phil

Chances are that if you are habitually applying C-style Micro-Optimization tricks when coding C#, like moving variable declarations out of loops, you are probably:

  1. Prematurely optimizing
  2. Doing it completely wrong

mccarthy-youre-doing-it-wrong-s

To demonstrate the point lets start by ignoring that there is a perfectly good Array.Reverse function in the framework and write our own:

static void Reverse1<T>(T[] xs)
{
    for (int i = 0; i < xs.Length / 2; i++)
    {
        T x = xs[i];
        xs[i] = xs[xs.Length - 1 - i];
        xs[xs.Length - 1 - i] = x;
    }
}

Now micro-optimize by taking the temp declaration out of the loop:

static void Reverse2<T>(T[] xs)
{
    T x;
    for (int i = 0; i < xs.Length / 2; i++)
    {
        x = xs[i];
        xs[i] = xs[xs.Length - 1 - i];
        xs[xs.Length - 1 - i] = x;
    }
}

 

The IL (byte code) generated for both implementations is identical in both release and debug builds. If you don’t believe me then check it for yourself by using the ildasm tool.

Another micro-optimization would be to store a copy of the array length in a local variable:

static void Reverse3<T>(T[] xs)
{           
    int len = xs.Length;
    for (int i = 0; i < len / 2; i++)
    {
        T x = xs[i];
        xs[i] = xs[len - 1 - i];
        xs[len - 1 - i] = x;
    }
}

 

This does actually result in the generation of different IL code, however IL generation is only part of the story. The difference in execution time between these implementations is negligible. The reason is that the IL code is just-in-time (JIT) compiled to machine code before execution and this compilation step will apply further optimizations.

Premature optimization is wrong on so many levels:

  • the optimization was probably unnecessary anyway
  • code can become less readable for no tangible benefit
  • you’re double guessing 2 compilation steps
  • you’re probably not even considering high level optimizations
    Further reading:

Pareto principle

The Sad Tragedy of Micro-Optimization Theater

Micro-Optimization and Meatballs

Micro-optimization tips to increase performance


Tags:
Categories: C# | .Net
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed