Archive

Monthly Archives: December 2015

prescription-pad-1

I was on the Phone with Doc Norton a couple weeks ago which resulted in a truly thought provoking experience.  

Doc told me that in the past, some companies would post a job requiring a programming language that had not yet been adopted by mainstream programmers. Hence, these companies would seek talented and motivated developers by requesting a unique language that only this breed of developer would have experience using. Specifically, this obscure language would usually be harnessed by developers who write code on their personal time. Hence, this strategy would identify highly motivated developers.

Doc then provided me with an example of companies that would seek out Ruby developers. Again, the client would feel confident that they were hiring highly motivated, multi-paradigm developers. Thus, these companies benefited greatly by applying this filter for hiring this breed of developer. Then something happened.

Doc told me that businesses were benefitting greatly by hiring mystical Ruby developers. That is until the “Ruby on Rails” framework was released. Thus, this framework significantly reduced the development effort required for Ruby developers to pump out applications. However, the side-effect of this was that many DMDs (i.e. Dark Matter Developers) entered the arena of Ruby programming and thus had a heavy reliance on the “Ruby on Rails” framework to solve their problems without having a deep understanding of Ruby language fundamentals. Thus, these companies now had to once again develop a strategy to filter top-notch talent from the rest of mainstream programmers.

Once again, Doc had inspired me. I immediately reflected on my own dependencies for some frameworks. In my case though, I tend to use the frameworks that I write myself. However, I have experienced shops that blindly mandate the utilization of specific frameworks without identifying the root cause for having to use these frameworks. Based on my reflection on the shops that mandated the use of specific frameworks without any rationale, I realized that frameworks today are typically used as a prescription medication. Hence, these frameworks treat the symptoms of a problem. However, as professional developers, we shouldn’t treat symptoms and send the client or the app on their way. No! As professional developers we should stop looking for a prescription and instead diagnose the true source of the problem. Is this an application problem or is this a people problem? Almost always, the problem is a lack of understanding…

Intro

Documenting interpretation of Railway-Oriented Programming.

The “Railway” provides a “Success Track” and a “Failure Track”. The Success Track is defined as the track of the “Happy Path”. This means that the objective of a function was completed successfully without errors. There also exists an alternate track that isn’t exposed initially. This track is known as the Failure Track. The Failure Track represents the “Sad Path”.

The railway starts off on one track which is known as the Success track. If any errors occur, this one track will spawn a fork. This fork exposes a separate track as the new execution path that is to be taken. This track is known as the Failure Track.

Track Foundation

The following code reflects the Tracks foundation:

module Core.Validation.Railway
 
type Result<'TSuccess,'TFailure> = 
    | Success of 'TSuccess
    | Failure of 'TFailure
 
let bind nextFunction lastFunctionResult = 
    match lastFunctionResult with
    | Success input -> nextFunction input
    | Failure f -> Failure f

Client

module Validators
open Core.Validation.Railway
 
type Request = {name:string; email:string}
 
let validate1 input =
   if input.name = "" then Failure "Name must not be blank"
   else Success input
 
let validate2 input =
   if input.name.Length > 50 then Failure "Name must not be longer than 50 chars"
   else Success input
 
let validate3 input =
   if input.email = "" then Failure "Email must not be blank"
   else Success input;;
 
let Validate = 
    validate1 
    >> bind validate2 
    >> bind validate3;;
 
// Setup
let goodInput = {name="Alice"; email="abc@abc.com"}
let badInput = {name=""; email="abc@abc.com"};;
 
// Test
Validate goodInput |> printfn "%A";;

This source code will serve as a reference for common set operations that have been partially implemented for a BlackJack game.
Feedback is welcomed within the comments section as I continue learning this mythical language.

module Core
 
type Suit = | Spades
            | Clubs
            | Diamonds
            | Hearts
 
type Face = | Two | Three | Four | Five 
            | Six | Seven | Eight | Nine | Ten
            | Jack | Queen | King | Ace
 
type Card = {Face:Face; Suit:Suit}
 
type Deal = | Hand of Card * Card
            | Hit of Card
 
let private suits = [Spades; Clubs; Diamonds ; Hearts]
let private faces = [Two; Three; Four; Five; Six; Seven; Eight; Nine; Ten;
                     Jack; Queen; King; Ace]
 
let deck = [for suit in suits do
            for face in faces do
                yield {Face=face; Suit=suit}]
 
let hitPlayer (deck:Card list) =
    (deck.Head, deck.Tail)
 
let deal = function
    | card1::card2::remaining -> Some(card1, card2), remaining
    | _ -> None, []
    
let shuffle xs =
    let swap i j (array : _[]) =
        let tmp = array.[i]
        array.[i] <- array.[j]
        array.[j] <- tmp
    let rnd = System.Random()
    let xArray = Seq.toArray xs
    let n = Array.length xArray
    for i in [0..(n-2)] do
        let j = rnd.Next(i, n-1)
        swap i j xArray
    xArray |> Seq.toList
 
let hand, deckRemaining = deal (shuffle deck);;
let cardsLeft = Seq.length deckRemaining;;