Phillip Trelford's Array

POKE 36879,255

Software Architecture for Non-Developers

Its the 3rd of 7 weekly instalments of a Software Architecture evening course I’m giving for 20 or so non-developers. So far each session has been split in two with a half hour of lecture and a half hour workshop. For the workshop the class is split into teams of 3, 4 or 5 and given a task to solve with UML:

  • Week 1: Use Cases for an Auction system
  • Week 2: Class Diagrams for an Auction system
  • Week 3: Class Diagrams for an Exchange
    Each team presented their diagram to the class, and here are the results for this week -developers better beware. ;)

  Exchange Class Diagram 2Exchange Class Diagram 1 Exchange Class Diagram 3 Exchange Class Diagram 4Exchange Class Diagram 5

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)

Logo

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

and:

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

spiral

 

Logo.fsx (19.71 kb)