Phillip Trelford's Array

POKE 36879,255

F# Rational64 implementation

The F# Power Pack includes an arbitrarily large Rational type called BigNum, which in turn uses the arbitrarily large BigInt type for the numerator and denominator. The BigInteger type has recently moved into .Net 4.0 under the System.Numerics namespace, It would be nice if BigNum could join it there.

What if you want a fixed size Rational implementation that can be used from any .Net language? The following is a sample F# implementation using Int64 for the numerator and denominator values:

open System

type Rational64 (numerator:Int64,denominator:Int64) =
    do if denominator = 0L && numerator <> 0L then
        raise (new DivideByZeroException())
    let rec gcd x y =    
        match y with
        | 0L -> x
        | _ -> gcd y (x % y)
    let norm =
        let u = int64 (sign denominator) * numerator
        let v = abs denominator     
        let d = gcd (abs u) v     
        if denominator <> 0L then u / d, v / d
        else numerator, denominator
    let numerator, denominator = norm    
    static let zero = Rational64(0L,1L)
    static let Op f (a:Rational64,b:Rational64) = 
        let x,y = a.Numerator, a.Denominator
        let u,v = b.Numerator, b.Denominator
        f x y u v
    static let Add = Op (fun x y u v -> new Rational64(x * v + u * y, y * v))
    static let Sub = Op (fun x y u v -> new Rational64(x * v - u * y, y * v))
    static let Mul = Op (fun x y u v -> new Rational64(x * u, y * v))
    static let Div = Op (fun x y u v -> new Rational64(x * v, y * u))        
    static let Eq = Op (fun x y u v -> x * v = u * y)
    static let Lt = Op (fun x y u v -> x * v < u * y)
    static let Le = Op (fun x y u v -> x * v <= u * y)
    static let Gt = Op (fun x y u v -> x * v > u * y)
    static let Ge = Op (fun x y u v -> x * v >= u * y)
    static let Compare (a:Rational64,b:Rational64) =
        if Lt (a,b) then -1
        else if Gt (a,b) then 1
        else 0
    new(numerator:Int64) = Rational64(numerator,1L)                  
    member this.Numerator = numerator 
    member this.Denominator = denominator
    static member Zero = zero
    member this.ToDecimal() =
        decimal this.Numerator / decimal this.Denominator
    member this.ToDouble() =
        double this.Numerator / double this.Denominator
    override this.ToString() =
        match numerator, denominator with
        | n, 1L -> n.ToString()
        | n, d -> sprintf "%d/%d" n d                             
    static member ( + ) (a,b) = Add (a,b)
    static member ( - ) (a,b) = Sub (a,b)
    static member ( * ) (a,b) = Mul (a,b)
    static member ( / ) (a,b) = Div (a,b)
    static member op_Equality (a,b) = Eq (a,b)
    static member op_Inequality (a,b) = not (Eq (a,b))
    static member op_LessThan (a,b) = Lt (a,b)
    static member op_LessThanOrEqual (a,b) = Le (a,b)
    static member op_GreaterThan (a,b) = Gt (a,b)
    static member op_GreaterThanOrEqual (a,b) = Ge (a,b)
    interface IComparable with
        member this.CompareTo (x) = Compare (this, x :?> Rational64)                 
    static member Equals(a,b) = Eq(a,b)
    override this.Equals x = this = (x :?> Rational64) 


Finally specific for F# by implementing a NumericLiteralX module it is possible to declare Rational64 literals like so (Q for Quotient):

module NumericLiteralQ =
    let FromZero () = Rational64(0L)
    let FromOne () = Rational64(1L)
    let FromInt32 (x) = Rational64(int64 x) 
    let FromInt64 (x:Int64) = Rational64(x) 

module Test = 
    let x = 42Q


Rational64.fs (4.90 kb)

Rational64Test.cs (4.74 kb)


On Sunday, I thought I’d try and show my son the fun side of programming and Logo seemed a good place to start. Using a Logo Interpreter written in JavaScript, in seconds we were drawing pentagons.

to pentagon repeat 5 [ fd 100 rt 72 ] end

That jogged my memory to a cool sample Logo Interpreter written by Adam Granicz in less than 400 lines, posted on HubFS back in 2006. The code didn’t run straight away due to some subtle changes in the language, but after some worthwhile coercion I was able to resurrect the code, which I have attached.

Try executing:

canvas 300 300 
to pentagon :x repeat 5 [ fd :x rt 72 ] 
pentagon 100


canvas 400 500 
spiral :x repeat :x [fd 4 lt * repcount 1.1] 
spiral 10000



Logo.fsx (19.71 kb)

Software Architect 2009 Conference

For the last 2 days I’ve been attending the Software Architect 2009 conference located at the iconic Royal College of Physicians building opposite Regent's Park in central London. Overall the events have been interesting, that said, the content has not in general been particularly new or ground breaking, but that is probably the nature of the discipline. It has however been good to be reminded of key principles, to listen to the views of others, and as always I’ve found it quite thought provoking. For each talk I attended I’ve created an entry on Twitter @ptrelford:

Tim Ewald on Saving Software Architecture: "When you go too far up, abstraction-wise, you run out of oxygen" Joel on Architecture Astronauts

Kevin Seal on MorganDirect's client-side architecture: Swing app with Eclipse IDE look, blackboard pattern, detailed logs & takes screenshots

Kevlin Henney on Slicing design over time: take time estimate & half it, coding is performance art so practice, test cases are propositions.

Dave Wheeler on Coding a solid UI: "WPF is great", dependency properties are cool, do MVVM pattern, get an HCI expert & use Expression Blend

Richard Blewett on What's New in WF 4.0: Everything. Complete API rewrite. 3.5 favoured code based workflow. 4.0 declarative XAML is king.

Dino Esposito asks "How good are you at .NET software design?" Separation of concerns, OOD principles - prefer composition to inheritance etc

Kevlin Henney on Modelling in the age of agility: Most important aspect of modelling is the -ing, i.e. the social and collaborative aspects.

Simon Brown on "Documenting your software architecture - why and how?" Start with a context and set the scene. Put yourself in others shoes.

Most popular analogy: Construction (Tim Ewald & Kevlin Henney)

Favourite example: Fast-Track Construction of the Empire State Building (Kevlin Henney)

Best term usage: idempotent (Simon Brown)

Best vocabularly usage: pontificate (Kevlin Henney)

Only search term suggestion: Death by UML Fever (Kevlin Henney again)