Fun Friday (Monday version) – Fractions

This will be a slightly longer series of posts. I thought about treating fractions as a distinct problem, and wanted to find a way to code reducing fractions in a logical and meaningful way.

The first problem was describing the type. Naturally, you can do it a as simple pair:

type Fraction = int * int
let a = (-1, -2 : Fraction)  // negatives?

But that design describes some issues I’m not super keen on handling, namely negative denominators. Mathematically, negative denominators aren’t all that complicated to deal with, but in my head, it seemed unnecessary to solve them, so that led to the following:

type Fraction = int * uint32
let a = (-1, 2u : Fraction) // ugh, not as clean as I'd like

Now we’ve dealt with the negative denominator problem, but that leaves us describing fractions in a sort of “planar” way. Great for talking to a professor, but I’ve always been something of a “make it clear” personality. Record types work well for this.

type Fraction = { Numerator : int; Denominator : uint32 }
{ Numerator = 1 ; Denominator = 2u; }

Nice and pretty. Except 0 is a valid uint32 value. Shit.

type BiggerThanZero = private BiggerThanZero of uint32

module BiggerThanZero =

     let create uintValue =
          if (uintValue > 0u ) then BiggerThanZero uintValue
          else failwith "No zeros"

     let value (BiggerThanZero u) =
          u

type Fraction = { Numerator: int; Denominator: BiggerThanZero }

Alright. Something is breaking my “F# is less verbose” than other languages spidey-sense here, in C#.

using System;

public class Fraction
{
    public struct BiggerThanZero
    {
        public BiggerThanZero(UInt32 u)
        {
            if(u == 0u) then 
                throw new ArgumentException("No zeros");
            Value = u;
        }

        public UInt32 Value 
        {
            get;
        }
    }

    public Fraction(int numerator, BiggerThanZero denominator)
    {
        Numerator = numerator;
        Denominator = denominator;
    }
    public int Numerator { get; }
    public BiggerThanZero Denominator { get; }
}

Nope, spidey-sense was off. C# is still more code. Phew… thought I was going to have to go back to OO land. 🙂

OK… so now we have a domain object. We cannot represent an object in the domain that is “invalid” in any way, so fundamentally, our functions should be easy to reason about.

So first thing… decimals to my new “Fraction” type.

let getFraction decimalValue = 
    let rec fract dm =
        let a = (d * m)
        let r = a % 1.0m
        match r with
            | 0.0m -> { Numerator = (int a) ; Denominator = BiggerThanZero.create (uint32 m)}
            | _ -> fract d (m * 10.0m)
    fract decimalValue 10.0m

This function goes back to our old friend, the recursive inner function. We take our input decimal value, and multiplying it by 10, and calling the result ‘a’ (shorthand for ‘amount’). Then we take ‘a’, and get the decimal part of that value by applying the modulo function to it and 1.0, and naming that value ‘r’ (shorthand for remainder). Assuming that ‘r’ is non-zero, we recurse into the loop, updating the multiplier to another factor of 10 greater than what we had before. Otherwise, we simply return a Fraction object, with the Numerator set to ‘a’, and the Denominator set to the multiple. E.G.

 

getFraction 0.4m;;
val it : Fraction = { Numerator = 4; Denominator = BiggerThanZero 10u }

getFraction 0.542m;;
val it : Fraction = { Numerator = 542; Denominator = BiggerThanZero 1000u }
 
getFraction 0.8675421m;;
val it : Fraction = { Numerator = 8675421; Denominator = BiggerThanZero 10000000u }

This is the start of our Fractions work, and although it’s correct, it’s certainly got some potential error cases. Our int and uint32 bases for values could be overflowed. That’s fixed in the following.


type BiggerThanZero = private BiggerThanZero of bigint
module BiggerThanZero =
let create uintValue =
if (uintValue > 0I ) then BiggerThanZero uintValue
else failwith "No zeros"
let value (BiggerThanZero u) =
u
type Fraction = { Numerator: bigint; Denominator: BiggerThanZero }
let getFraction decimalValue =
let rec fract d (m : decimal) =
let a = (d * m)
let r = a % 1.0m
match r with
| 0.0m ->
{ Numerator = (bigint a) ; Denominator = BiggerThanZero.create (bigint m) }
| _ -> fract d (m * 10.0m)
fract decimalValue 10.0m

Next time, we’ll deal with reducing our fractions.

 

Modeling the Domain : Short Codes

Anyone who’s read For Fun and Profit’s domain modeling exercise may see some similarities in today’s code. Mainly, I wanted to point out the value of quickly being able to create types that describe my functions here.  For context, I’m in the middle of rewriting a sticky report that consumes data from a ton of different places… this is an example (slightly modified, to avoid spilling too many of {Redacted}’s beans.)


type ShortCode = private ShortCode of string
type ProductShortCode = private ProductShortCode of ShortCode
type AccountShortCode = private AccountShortCode of ShortCode
module ShortCode =
let create s =
if System.String.IsNullOrEmpty s then None
elif s.Length > 15 then None
else Some (ShortCode s)
let value (ShortCode s) =
s
module AccountShortCode =
let create s =
match ShortCode.create s with
| Some sc -> Some (AccountShortCode sc)
| None -> None
let value (AccountShortCode (ShortCode s)) = s
module ProductShortCode =
let create s =
match ShortCode.create s with
| Some sc -> Some (ProductShortCode sc)
| None -> None
let value (ProductShortCode (ShortCode s)) = s

view raw

ShortCode.fsx

hosted with ❤ by GitHub

In the above, we’re dealing with a thing called ‘Short Codes.’ At redacted, we have a shortened string which represents many of our more common domain objects, called a ‘Short Code’ which makes domain objects easily identifiable when viewed in spreadsheets.

In C# code, we’ll typically treat these objects as simple strings, or you deal with of domain types as espoused in Vladir Khorikov’s Pluralsight course, “Applying Functional Principles in C#”.

But in F#, you get drastically simpler code, that gives you similar benefits.

  1. Any change to ShortCodes can be done once, and all references using it get the change. That’s as DRY as it comes.
  2. ShortCodes can be equal to each other, but AccountShortCodes cannot be equal to ProductShortCodes cannot be (try it in FSI, you get compiler errors!)
  3. The modules allow us to retain the business logic, so we avoid the annoying issues of duplicating validation code everywhere. If I reference an AccountShortCode, it’s implied that I created one successfully in the first place!

The code to do stuff becomes quite easy:

type ConsumingRecord = { ShortCode : AccountShortCode
                         ImportantValue : decimal }

let m = AccountShortCode.create "APPLE";;
// m is an AccountShortCode option, because of the 
// validation logic there, so we need it from the option, 
// before we push it into our consuming type.

let n = { ShortCode = (Option.get m)
          ImportantValue = 5.0m}

The subtle thing here is that we have to actually deal with the fact that it’s an option. We CAN fail to get an AccountShortCode here, depending on what we pass in, but once we have a “ConsumingRecord” object, the validity of the ShortCode is guaranteed. This only works, however, because F# doesn’t do nulls. Once your language does nulls, it throws this stuff right out the window.

But I’m sure eventually C# will get that, too. You’ll just have to use an attribute to make your class less C-sharpy. 😉

Not Much F# Today

You ever have one of those days when everything goes wrong and it’s all a C# developer’s fault? I kid, of course, but it made for a difficult day with almost no sitting at my own desk to actually get anything done.

My mission is to update this blog every day, regardless of what I actually accomplish for the day. Today, I saved the world, and solved problems that were a little more tactical in nature. I did enjoy a welcome to the firm lunch with a new QA in the office, but beyond that, very little coding.

A Random Thought…

I was driving home last night, near the 124th street exit, and an older-looking Honda Civic merged in front of me. When the driver turned on his blinker, indicating the merge, I noticed the blinker was blinking decidedly faster than the average blinker on the freeway at that time. I became annoyed at this, and genuinely thought less of this random driver for his “spastic blinking.” I even made a face, indicating my displeasure. Self-awareness came when I noticed the grumpy frown in my rear-view mirror.

I fear lunacy, as I’m sure anyone would, given the circumstances.

Taking Friday Off

Honestly, I’m not a big “take the day off” sort of guy. I’m a workaholic. I define myself by what I do. I code… I sit in a little room, listen the heavy metal music, and write the best code I can. (And yes, it’s awesome code.) Still, a friend of mine said “your kids don’t care about your project right now…” so Friday, was to be my day off.

It started with a day in the mud. We awoke, and we went out to the South 47 farms, where apparently, someone had ordered 50 tons of mud spread around the place. We did the farm tots experience, and I can now say, that 2009 has involved the requisite minimum hay ride count. The same can be said of corn mazes. Picking pumpkins concluded our farm experience, and Lydia was the only child who picked a pumpkin that actually weighed less than herself.

The remainder of the day was fairly lounge-worthy. An early chicken dinner gave way to the carving festivities. Zoe and I spent the first of our carving time cleaning off 4 pounds of mud from the pumpkins, and by the time we’d completed them, Lydia and Heather had completed the tiny “princess pumpkin.” Emerson had fallen quite deeply to sleep while Heather and Zoe dug through pounds of seedy innards. Zoe’s pumpkin had a distinct “Scary Sloth from Goonies” sort of appeal, while Emerson’s was a classic “semi-toothless” grin.

The evening ended with a quick family movie night. We’d been going with the classics… Star Wars, Wizard of Oz, but this time, we tried more a “modern classic”, watching The Neverending Story. That movie brings fond memories for any child of the 80s, but there is a distinct campiness there. A REALLY distinct campiness. It’s a campiness that’s almost unwatchable.

However, there’s an emotional capability that I didn’t remember immediately. I’m speaking, of course, of the Death of Artax. The story-lead Atreyu, leading his horse (Artax) through the Swamps of Sadness, realizes that the sadness has overtaken the poor horse, eventually drowning the beast. Atreyu, obviously, emotionally distraught… cries out for his horse. Sebastian, the “kid reading the story,” cries out for the horse. And Lydia, tears streaming from eyes to ears, gave the most accusatory glares as she could muster for the parents who decided to show her a pony-snuff-film.

I didn’t look at my computer once, hauled 160+ pounds of children and pumpkin around all day (although, a good 10 pounds of weight was likely just in dirt.) All told, not a bad day off.

Fall stuff.

September came and went quickly, and October seems to be doing the same. Work is steady, long and challenging, and in my project, we’re solving some problems that needed to be solved. Given other projects I’ve been on, it’s a nice pace.

On the family front, the fall schedule has come upon us with full force. Every day of the week, there’s something going on, whether it’s preschool during the week, or some such activity planned on the weekend, and up until recently, when some of the kids simply came down with the seasonal whatnots, an unplanned block of 20 minutes rarely seemed to come entirely into fruition.

Notable things that have happened since my last post.
– We went to the fair, in the pouring rain (the pictures are good, but Heather doesn’t like my Picture adder thing on this website.)
– I ate a Maple Bar with Bacon on it at Frost donuts in Mill Creek.
– The kids have started preschool (and almost immediately afterwords)
– The kids have all started coughs/colds/flu stuff.
– Lydia turned 3.
– Zoe has gotten herself almost 100% potty trained.

Final things… we’ve been starting to think about Kindergarten and 1st grade for Zoe. Next year, she’ll start kindergarten.

Beyond that… we’re keepin’ on.

Way to long to post something.

But everything’s broken with the heat… arg!

Just to get back into the swing of posting more regularly, I’m gonna start this one with a link I like. To those who like Obama’s healthcare plan, please read: the following. If you get nothing from it, just remember the following:

As with any good or service that is provided by some specific group of men, if you try to make its possession by all a right, you thereby enslave the providers of the service, wreck the service, and end up depriving the very consumers you are supposed to be helping.

– Dr. Leonard Peikoff

Other notes: we’re all fine. To everyone.. sorry for taking so long. We all say Hi.

King County Sheriff Schene – God Damn It, WTF

For those who may not have seen some local (to me) news, a King County Sheriff plead not guilty to a 4th-degree assault charge on a 15 year old girl. It matters to me, because frankly, I live here in King County, and I don’t like to think of our cops as anything but the faithful public servants that most of them are. Just do a quick Google Search on “King County, 4th Degree”, and you’ll find a whole bunch of articles on the guy, and the kid in question. When they had her in custody, the girl kicked her shoe off at the cop, hitting him in the knee, and he went after her. Here’s one of the better videos on the subject:

I have a general respect for cops. They have an unpleasant job that I’m thankful they do. This video makes me respect cops a little less.

I hope the girl isn’t hurt. I hope she can learn to trust that cops are (in general) good people trying to make things safe for everyone. However, this particular situation may have precluded the possibility of that. I mean, putting yourself in her shoes, can you reasonably assume that cops aren’t just as weak-willed as any other random mugger? I hope so, but I do doubt it.

OK, eventually I get back to things.

It’s currently the evening of the 19th, as I write this entry. I’m sitting upstairs in my makeshift office, listening to an old Guns and Roses album.

To update on the most recent and pressing of items:

1) Emerson is fine. His medications are being upped again tomorrow, but he seems to be taking them just fine. There’s still no change in his heart size, but at this point, he’s not getting worse.

2) Lydia and Zoe are back in preschool now. They’ve seemed to get themselves back into a rhythm now.

3) Work has slowed down, considerably. This is expected for the time of year, but is a bit on the boring side. I’m doing a few things which are interesting, but none of them are interesting to more than a few people.

We had Zoe’s birthday party this past weekend (and took dozens of photos with the new camera.) I think she had a lot of fun having a “second birthday” this year. Something awesome… kid parties at the YMCA. Do a few in your house, and then do one at the Y. You don’t have to clean and the kids get to play at the playground and you don’t have to clean. Seriously… you don’t have to clean, so it’s totally worth it right there.

Right now, I’m in a sort of weird slump / busy period. On one hand, things really are picking back up (and it’s busy again.) On the other, I’ve never felt quite like I’ve accomplished less during the day. I know I’m working… I’ll get to work at 9AM, and look down at the clock when I get a quick hunger pang at 2:30 PM wondering what happened to the day.

I’m doing things… coding a little, researching things mostly (and doing some work for local non-profits.) But it’s all a lot of busywork, and nothing concrete.

My poker league (the Deuce Deuce Revolvers) is starting up again this week, which should be interesting. If anything, it’ll cause another fight between Heather and I (Lydia’s preschool is Thursday evenings, which is exactly the same time as my poker league.) Granted, my league is monthly, but trying to schedule it has been a touch silly this month, so getting Heather to take Lydia to preschool (while having someone watch Zoe and Emerson for 2 hours) is a bit much to handle. I may have to skip it, which is not that bad as I was the one who wrote the league rules about “No Shows.”

Now that I finally wrote a new post, let’s see how long it takes me to get another one out. I’m gonna try for tomorrow… let’s hope 🙂