Wednesday, June 28, 2017

Enumeration - Part 2 (Swift)

7:50 AM Posted by CHANDAN MAKHIJA 1 comment
Associated Value Enumerations
Associated values, allow us to combine a set of enumeration cases and yet associate different sets of values of with each enumeration case. This includes any number of values of any type we like as well as potentially having no associated values at all. In Swift we can’t use both raw values and associated values within the same enumeration at the same time.
Let’s have a look at an example.
Here I’ve defined an enumeration to represent colours in two different colour spaces):
enum ColorSpace {
    case rgba(red: UInt8, green: UInt8, blue: UInt8, alpha: Float)
    case cmyk(cyan: Float, magenta: Float, yellow: Float, black: Float)
}

 There are a few things to take note of:
First, there is no raw value type after the enumeration as we saw with raw values (i.e. no colon followed by a type name after the enumeration name). This is because with associated values, each enumeration case can have a different set of associated values and it therefore doesn’t really make sense to specify a single type.
Secondly, notice that the .rgba and .cmyk cases have a different sets of values associated with them with each set of associated values being defined as a comma separated list of label / type pairs between a pair of parentheses. The key point is that each enumeration case only has the associated values that it needs.
Another thing of note is that it is not actually a requirement that we supply labels for each of the associated values. We could just as easily have written the enumeration above as:
enum ColorSpace {
    case rgba(UInt8, UInt8, UInt8, Float)
    case cmyk(Float, Float, Float, Float)
}

Assigning Enumerations Values with Associated Values

To create an enumeration value with associated values, we must supply values for each of the associated values of the enumeration at the point we assign the enumeration value:
var color1 = Color.rbga(red: 100, green: 100, blue: 100, alpha:1.0)
var color2 = Color.cmyk(cyan: 0.5, magenta: 0.5, yellow: 0.5, black: 0.5)

Enumerations and Pattern Matching

For simple enumerations and enumerations with raw values, we can use a simple enumeration case pattern to match individual enumeration cases:
enum DayOfWeek {
    case Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
}

let day = DayOfWeek.Monday

switch day {
    case .Monday: print("The Moon's day")
    case .Tuesday: print("The Norse god Tyr")
    case .Wednesday: print("The Norse god Odin")
    case .Thursday: print("The Norse god Thor")
    case .Friday: print("The Norse god Frigg")
    case .Saturday: print("Saturn's Day")
    case .Sunday: print("The Sun's Day")
}
// prints "The Moon's day"

When it comes to enumeration cases with associated values, we also have the option of using the value-binding pattern to match and extract enumeration cases and their associated values:
enum Day {
    case Monday(units: Int)
    case Tuesday(units: Int)
    case Wednesday(units: Int)
    case Thursday(units: Int)
    case Friday(units: Int)
    case Saturday(units: Int)
    case Sunday(units: Int)
}

let sales = Day.Monday(units: 42)

switch sales {
case let .Monday(units):
    print("Sold \(units) on Monday")
case let .Tuesday(units):
    print("Sold \(units) on Tuesday")
// ...
default:
    print("Not sure about the rest of the week!")
}

Enumeration Equality

Enumerations checking for equality is relatively straight forward:
enum Planet {
    case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto
}

var planet = Planet.Mercury
if planet == .Earth {
    print("The Blue Marble")
}

This also works for enumerations with raw values:
enum Planet : Int {
    case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto
}

var planet = Saturn
if planet == .Saturn {
    print("The Ringed Planet")
}

Boolean Comparison of Associated Values Enumerations

This is little difficult because Swift doesn’t know how to compare the different associated values for each enumeration case to determine whether two cases are equal or not. To fix this, we have to give Swift a bit of help. This means implementing the equality operator (==) for the enumeration type ourselves.
For example:
enum UserAction {
    case Start
    case Pause
    case Stop
    case Restart(delay: Int)
}

func ==(lhs: UserAction, rhs: UserAction) -> Bool {
    switch (lhs, rhs) {
    case let (.Restart(delay1), .Restart(delay2)):
        return delay1 == delay2
    case (.Start, .Start), (.Pause, .Pause), (.Stop, .Stop):
        return true
    default:
        return false
    }
}

UserAction.Start == UserAction.Start // true
UserAction.Start == UserAction.Restart(delay:10) // false
UserAction.Restart(delay: 10) == UserAction.Restart(delay:12) // false
UserAction.Restart(delay: 10) == UserAction.Restart(delay: 10) // true


Recursive Enumerations
It’s probably easier to explain recursive enumerations with an example. Imagine we wanted to represent a binary tree within our code.
We could model the binary tree using an enumeration as follows:
enum BinaryTree<T> {
    case leaf(T)
    case node(leftChild: BinaryTree, rightChild: BinaryTree?)
}

The key point here is that the second case of the enumeration has up to two associated values which themselves are also of the same type as enumeration type that is being defined (BinaryTree<T>).
The other thing with this example is that, as written, it doesn’t actually compile.
If we put this into a playground, Xcode displays the following error
Recursive enum ‘BinaryTree<T>’ is not marked as ‘indirect’.
Recursive definitions like the one written above aren’t actually allowed.Instead, we have to tell Swift to modify the way that it stores the associated values of the enumeration by including the indirect keyword.
enum BinaryTree<T> {
    case leaf(T)
    indirect case node(left: BinaryTree, right: BinaryTree?)
}
This modifies the storage of just those cases only.
indirect enum BinaryTree<T> {
    case leaf(T)
    case node(left: BinaryTree, right: BinaryTree?)

This will modify the storage of all cases with associated values


Nested Enumerations

Nested enumerations are enumerations that are defined within the body of another enumeration. The main reason for defining nested enumerations is so we can group together enumerations that are related, for example where one enumeration is used as the associated value of one or more cases in another enumeration.
enum TyreType {
    enum TyreColor {
        case purple // UltraSoft
        case red // SuperSoft      
        case yellow // Soft
        case white // Medium
        case orange // Hard
        case green // Intermediate
        case blue // FullWet
    }
    
    case ultraSoft(color: TyreColor)
    case superSoft(color: TyreColor)
    case soft(color: TyreColor)
    case medium(color: TyreColor)
    case hard(color: TyreColor)
    case intermediate(color: TyreColor, litresClearedPerSecond: UInt8)
    case fullWet(color: TyreColor, litresClearedPerSecond: UInt8)
}

let qualificationTyre = TyreType.ultraSoft(color: .purple)
let raceTyre = TyreType.intermediate(color:.green, litresClearedPerSecond: 25)

Contained Enumerations

We can contain enumerations within other structured types such as classes or structs.
For example
struct F1RacingCar {
    enum RaceTeam {
        case mercedes
        case ferrari
        case redBullRacing
        case williams
        case toroRosso
        case mcLaren
        case forceIndia
        case renault
        case sauber
        case haasF1
        case manorRacing
    }

    enum TyreType {
        case ultraSoft
        case superSoft
        case soft
        case medium
        case hard
        case intermediate
        case fullWet
    }

    let team: RaceTeam
    let tyre: TyreType
}

let racingCar = F1RacingCar(team: .mercedes, tyre: .superSoft)

Monday, June 26, 2017

Enumerations - Part 1 (Swift)

3:45 AM Posted by CHANDAN MAKHIJA No comments

What is enumeration ?

Enumerations, or ‘enums’ for short, are a common feature in many programming languages providing a convenient way of grouping a set of related values together into a single code construct.
Think about a traffic light. The colours of a traffic light can be one of three colours – red, amber or green. They can’t be blue, they can’t be purple and they can’t be one of the millions or other colours that humans perceive.
So, inorder to build a traffic light using code we can define enum named as traffic light which will contain three values i.e Red, Amber and Green.

Three Types of Swift Enumeration

In Swift, there are three distinct categories of enumeration:
– Basic Enumerations
– Enumerations that have Raw Values
– Enumerations that have Associated Values

so lets begin one by one
Basic Enumerations
In Swift, Basic enumerations are, as you might have guessed, the simplest type of enumeration we can define. In practice, basic enumerations are similar to the enumerations that you may have experience of in C or Objective-C.
enum TrafficLightColor {
   case red
   case amber
   case green
}

Here, TrafficLightColor is the enumeration type, Enumeration type is always written in camel case, where first letter of the word is capital and the rest letters are small. Red, amber and green are 3 different values called as enumeration cases. Enumeration cases are written as lowerCamelCase naming convention with a lowercase first letter and a capitalised letter for each subsequent word.

We can also define 3 cases on a single line

enum TrafficLightColor {
   case red, amber, green
}

Assigning Enumeration Cases To Variables and Constants

We can also assign enumeration cases to a variable or constants as shown below:

let firstColor : TrafficLightColor

firstColor = TrafficLightColor.red

If the type of a variable or constant is already know and that type is an enumeration type, we can assign a new value to a variable (or initialise a constant) by omitting the enumeration type name completely and using just a period followed by the enumeration case we want to assign:
secondColor = .amber


Raw Value Enumerations

Raw values are almost like constants that are assigned to each enumeration case. They are pre-populated values that are assigned when the enumeration is first defined and remain fixed for the life of that enumeration type. On top of this, the raw values assigned to each of the enumeration cases must also all be of the same type and like the cases themselves must also be individually be unique within the enumeration (i.e. you can’t have two cases with the same raw value).

enum DayOfTheWeek : Int {
   case monday = 1
   case tuesday = 2
   case wednesday = 3
   case thursday = 4
   case friday = 5
   case saturday = 6
   case sunday = 7
}

Most of the declaration above should be relatively familiar. The first difference though is the addition of the colon and the Int type after the enumeration name. This is where we define the type of raw value that each enumeration case will be assigned. Second difference you might come across is the "=" sign. Using equal to sign we are assigning the raw values to the enumeration cases.
In C and Objective-C the values associated with enumeration cases are generally limited to just integer values. In Swift though, this is not the case. Swift allows us to assign not only integer values but also Float, Double, Character and even String values as raw values

enum Color : String {
   case red = "Red"
   case amber = "Amber"
   case green = "Green"
}

enum Color : Float {
   case red = 1.0
   case amber = "2.0
   case green = 3.0
}

Implicit Raw Value Assignment

In the case of an enumeration where the raw values are either Int or String values (it doesn’t work for any of the other types such as Float or Double), Swift can automatically assign raw values to enumeration cases without us having to explicitly assign them. Take enumerations with raw values of type Int. The general rules here is that unless otherwise stated, Swift will start at zero and assign raw values to each enumeration case with each case being assigned a raw value one greater than that of the previous case.

enum ShortDayOfWeek: Int {
   mon, tue, wed, thu, fri = 10, sat, sun
}
// mon = 0, tue = 1, ..., thu = 3, fri = 10, sat = 11, sun = 12

enum DayOfWeek: String {
   case monday, tuesday, wednesday = "Hello", thursday, friday, saturday, sunday
}
// monday = "monday", tuesday = "tuesday", wednesday = "Hello", ... , sunday = "sunday"

Accessing the Raw Value of an Enumeration Case

When we assign raw values to enumeration cases, each enumeration case automatically gains a read-only property called rawValue which we can use to access the raw value

let day : String = DayOfWeek.monday.rawValue
// day is now "monday"

Enumeration Initialisation Using Raw Values

This way around, things are a little more complicated.
Enumeration type automatically gains an initialisation method that has a single parameter (called rawValue) of the same type as the enumerations raw value type. We can use this initialisation method to construct new enumeration values from a given raw value:

let day = DayOfWeek("monday")

Well now think about the case when we pass a string which doesnot gets matched with any of the enum cases. In that case what will happen ?. Well, it won’t surprise you then to find out that the enumerations initialisation function is a failable initialiser. Fialable initialiser returns nil when none of the case is matched. It means it returns an optional value of the enumeration type.

let day2 : DayOfWeek? = DayOfWeek(rawValue: "Tuesday")
// day is now an optional with a value of .Tuesday
let badDay : DayOfWeek? = DayOfWeek(rawValue: "Grrrr")
// badDay is now nil


This is the end of second type of swift enumeration. In the next part i will explain the third type and other important information about swift enumeration.

Sunday, June 25, 2017

Closures - Part 1 (Swift)

4:12 AM Posted by CHANDAN MAKHIJA No comments
Today, i will walk you through the most important concept in swift i.e Closures. Today i will talk about the meaning of closure, higher order function, first class function. These words may come across foreign to you. Well, let’s learn together.

What are closures ?
In the most basic terms if i say, a closure is just like a function without the keyword func and without a name. From the newcomer’s perspective, however, Closures seem naked and even incomplete.

So, let’s compare how you would add two numbers in a function vs closure. Both will take two Int parameters and return one Int. Let’s begin with a function.
func addTwoNumbers(number1: Int, number2: Int) -> Int {
return number1 + number2
}
var storedFunc = addTwoNumbersstoredFunc(2, 9) // 11
// Closure
var storedClosure: (Int, Int) -> Int = { (number1, number2) in
return number1 + number2
}
storedClosure(number1: 5, number2: 9) // 14
// Shorter
var storedClosure: (Int, Int) -> Int = { return $0 + $1 }
// Super Short
var storedClosure: (Int, Int) -> Int = { $0 + $1 }
var closureHelloWorld: () -> String = { return "hello" }
insertSomething(closure: closureHelloWorld) // "hello"
insertSomething(closure: { return "hello world"}) // "hello world"

I’ve stored the addTwoNumber function into the newly created var called, storedFunc. But, how is this possible? Well, in Swift , just like many other programming languages, Swift functions are described as a first-class function. I don’t know why it is called that way, but you can store a function to a variable/constant.
However, we don’t have to use the func keyword to store a function. Indeed, we can use closure instead.
var storedClosure: (Int, Int) -> Int = { (number1, number2) in
 return number1 + number2
}
storedClosure(number1: 5, number2: 9) // 14

The above example is identical to the first example. The in keyword is used to separate the input parameters,number1 andnumber2from the return part. Also, we’ve stated that the type of storedClosure is (Int, Int) -> Int. The pre-stated type tells the variable that it takes two parameters and return one Int.

But, the example above can be simplied, and, yes, it is still called closure.
// Shorter
var storedClosure: (Int, Int) -> Int = { return $0 + $1 }
// Super Short
var storedClosure: (Int, Int) -> Int = { $0 + $1 }

So, what the heck is $0and $1 ? Well, it’s just a syntax by Swift. It automatically recognizes two Int parameters. The first input value is $0 and the second, $1. Also, we don’t even need to put return if you are just playing with those two parameters.

So far, you’ve learned closures and functions are pretty much the same and both are first-class since you can store them into a variable. But also, they are called, higher order function. You can use closure/function as parameters and even return them.  

 If you want to add a closure as a parameter, you could do this way
Example 1:
insertSomething(closure: { return "hello world"}) // "hello world"

Example 2:


func someFunctionThatTakesAClosure(completionClosure: () -> ()) {
    // function body goes here
    if(error = false) {
       completionClosure()
    }

}

//Call it
someFunctionThatTakesAClosure({
    //Completions Stuff
    println("someFunctionThatTakesAClosure")
});