# How To Write A Perfect Program

May 13, 2014 “Let me take you on an adventure which will give you superpowers.” –`@bitemyapp`

https://github.com/nuttycom/startup_week-2014

# Start Very Simple

``````
True
``````

This program doesn’t have any bugs.

``````
nuttycom@crash: ~ \$ ghci
GHCi, version 7.6.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> True
True
``````

## Learn To Count

``````
data Bool = True | False

boolProgram :: Bool
-- "::" is pronounced, "has type"
``````

How many states could boolProgram inhabit?

1 + 1 = 2

applause

``````
intProgram :: Int32
``````

This one is just awful…

``````
strProgram :: String
``````

## Learn to Count

``````
-- if haskell had unsafe type-level pattern matching...
inhabitants :: Type -> Nat

inhabitants Bool = 2
inhabitants Int32 = 2^32
``````

## Learn to Add

``````
-- Maybe there's one of these...
data Maybe a = Just a | Nothing

inhabitants (Maybe a) = inhabitants a + 1

-- Either there's one of these, or one of those...
data Either a b = Left a | Right b

inhabitants (Either a b) = inhabitants a + inhabitants b
``````

Bool, Maybe and Either are called sum types for the obvious reason.

## Learn to Multiply

``````
tuple :: (Bool, Int32)
``````
• `fst :: (a, b) -> a`
• `(fst tuple)` has 2 inhabitants

• `snd :: (a, b) -> b`
• 232 inhabitants if `(fst tuple) == True`
• 232 inhabitants if `(fst tuple) == False`

• 2 * 232 = 233

With tuples, we always multiply.

## Learn to Multiply

``````
inhabitants (a, b) = inhabitants a * inhabitants b
inhabitants (Int32, Int32) = 2^32 * 2^32 = 2^64

inhabitants (a, b, c) = inhabitants a * inhabitants b * inhabitants c
inhabitants (Bool, Bool, Int32) = 2 * 2 * 2^32 = 2^34
``````

We call these “product” types.

## Isomorphic Types

These types have the same inhabitants.

``````
-- expressed as a product
tuple :: (Bool, Int32) -- 2^33 inhabitants

-- expressed as a sum
either :: Either Int32 Int32 -- 2^33 inhabitants
``````

Choose whichever one is most convenient

``````
eitherBoolOrInt :: Either Bool Int32 -- 2 + 2^32 inhabitants
``````

Either is more flexible

## Add if you can, multiply if you must

``````
inhabitants (Either Bool Int32) = 2 + 2^32
``````

Most languages emphasize products.

Bad ones don’t let you define a type
with 2 + 232 inhabitants easily.

``````interface EitherVisitor<A, B, C> {
public C visitLeft(Left<A, B> left);
public C visitRight(Right<A, B> right);
}

interface Either<A, B> {
public <C> C accept(EitherVisitor<A, B, C> visitor);
}

public final class Left<A, B> implements Either<A, B> {
public final A value;
public Left(A value) {
this.value = value;
}

public <C> C accept(EitherVisitor<A, B, C> visitor) {
return visitor.visitLeft(this);
}
}

public final class Right<A, B> implements Either<A, B> {
public final B value;
public Right(B value) {
this.value = value;
}

public <C> C accept(EitherVisitor<A, B, C> visitor) {
return visitor.visitRight(this);
}
}``````

“Bug fixing strategy: forbid yourself to fix the bug. Instead, render the bug impossible by construction.” –Paul Phillips

# The Vampire Policy

Don’t let him in.

# Strings (Ugh.)

The type `String` should only ever appear in your program when a value is being shown to a human being.

## Two common offenders

• Strings as dictionary keys
• Strings as serialized form

## Garlic

Use newtypes liberally.

``````
newtype Name = Name { strValue :: String }
-- don't export strValue unless you really, really need it
``````
``````
case class Name(strValue: String) extends AnyVal
``````

Never, ever pass bare String values
unless it’s to `putStrLn` or equivalent.

Never, ever return bare String values
except from `readLn` or equivalent

## Holy Water

Hide your newtype constructor behind validation.

``````
case class IPAddr private (addr: String) extends AnyVal

object IPAddr {
val pattern = """(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})""".r

def parse(s: String): Option[IPAddr] = for {
xs <- pattern.unapplySeq(s) if xs.forall(_.toInt <= 255)
} yield IPAddr(s)
}
``````

We’ve shrunk down an infinite number of states to (2564 + 1). Given the inputs, that’s the best we can do.

# Stake

## import scalaz._

Three very useful types:

• `A \/ B`

• `Validation[A, B]`

• `EitherT[M[_], A, B]`

`MyError \/ B`

• `\/` (Disjunction) has a Monad biased to the right

• We can sequentially compose operations that might fail

• `for` comprehension syntax is useful for this

``````
import scalaz.std.syntax.option._

def parseJson(s: String): ParseError \/ JValue = ???
def ipField(jv: JValue): ParseError \/ String = ???

def parseIP(addrStr: String): ParseError \/ IPAddr =
IPAddr.parse(addrStr) toRightDisjunction {
ParseError(s"\$addrStr is not a valid IP address")
}

val ipV: ParseError \/ IPAddr = for {
jv <- parseJson("""{"hostname": "nuttyland", "ipAddr": "127.0.0.1"}""")
addrStr <- ipField(jv)
ipAddr <- parseIP(addrStr)
} yield ipAddr
``````

`Validation[NonEmptyList[MyError], B]`

• Validation does not have a Monad instance.

• Composition uses Applicative: conceptually parallel!

• if you need sequencing, `.disjunction`

``````
type VPE[B] = Validation[NonEmptyList[ParseError], B]

def hostname(jv: JValue): VPE[String] = ???

def ipField(jv: JValue): ParseError \/ String = ???
def parseIP(addrStr: String): ParseError \/ IPAddr = ???

def host(jv: JValue) = ^[VPE, String, IPAddr, Host](
hostname(jv),
(ipField(jv) >>= parseIP).validation.leftMap(nels(_))
) { Host.apply _ }
``````

`EitherT[M[_], MyErrorType, B]`

• EitherT layers together two effects:

• The “outer” monadic effect of the type constructor M[_]

• The disjunctive effect of `\/`

``````
// EitherT[M, A, _] <~> M[A \/ _]

def findDocument(key: DocKey): EitherT[IO, DBErr, Document] = ???
def storeWordCount(key: DocKey, wordCount: Long): EitherT[IO, DBErr, Unit] = ???

val program: EitherT[IO, DBErr, Unit] = for {
doc <- findDocument(myDocKey)
words = wordCount(doc)
_ <- storeWordCount(myDocKey, words)
} yield ()
``````