Friday, March 25, 2016

Swift: Guard ... what?????

At first I saw guard code sample, and I was like WHATT? WHY????

See in C++  there is only if (x) or if(!x) where x being an expression that can contain more than one expression in itself. So pardon me when I say WHY?????

Then after googling I found some nice articles, which explain why and when guard could be used efficiently.


So here goes my understanding:

Basically Guard is like If conditional statement except, it enters its scoped block only if the condition is false.

if guard x = x else { return; }

The code block inside else should either be a function that does not return anything, or it should move the control of execution outside the guard statement's code block. Meaning, only return/break/continue/throw can be used. Also one of these should be used otherwise be ready to face the compiler wrath with "/path/GameScene.swift:55:3: 'guard' body may not fall through, consider using 'return' or 'break' to exit the scope"

But why? Why can't I do if let x != nill { return; } ? This and the guard seems to be exactly the same.
Here is where nuances of the language comes into play.

Here are a few pointers regarding guard. I am going to list that out for you here.

1. Automatic unwrap of the optional 
If x is not nil, that is if x is valid, then if you use IF statement, then you would have to force unwrap it everytime after the IF statement using x!.function();

But if you use guard, then you need not force unwrap it, and can use it as a non optional parameter as x.function(); because guard preserves the context of x. Keeps it intact.

Say What????

So this would mean, when you use guard, you need not force unwrap the non optional parameter with !, but guard does that for you when exiting its scope. Which some people perceive as fine, and some not.

For e.g

var lastTick: NSTimeInterval? = 0


void update(){
     guard lastTick = lastTick where lastTick > 0 else {
        return;
    }

   lastTick.advanceBy(5); //automatically unwrapped by guard if exits, for you. How convenient and intuitive. Because if it was null, it would have returned from the function.
}

2. Guard is more like a graceful assert
Since guard scoped block executes only if the condition is not true, it can be looked upon as an assert, but instead of asserting, it would gracefully exit.

3. You need not check for the NOT condition. 
Yes that is a convenience. Instead of doing if (!x) you can do guard x.
for e.g 

var previousDate: NSDate?;


void update()
{
    guard let previousDate = previousDate else{
        return;
    }
}

In this, the condition which should be true is clearly evident to the same programmer after many years, or to a different programmer the same day.
     
4. Also to keep the code clean, instead of using nested conditions with if, you can guard them individually and exit from the scope if not met

Normally when lots of conditions have to be met as pre-checks in order for a code inside a function to run, it seems cleaner to do a guard for each, and exit from scope if not met.

This is the same as "Designed by Contract" software design terminology, that states all the preconditions have to be met before the main block of module could be executed.

Note: 
As an added bonus (I am kidding ofcourse) you can use guard on non optional values as well.

Thanks for reading this write up.


Monday, March 21, 2016

Closures in c++ vs that in Swift

Being a newbie in Swift language, I try to find correlation between the new language and the one I am familiar with.

One such technicality that I came across with is "Closures". It is there in both Swift and C++.



C++:
Closure in C++ are associated with Lambdas. There is a closure class, and a closure instance is created for each Lambda. The closure class is unique for each lambda. The class has member function to execute the code provided in lambda.

For e.g

auto C1 = [x](int y){ return x * y > 55; }

C1 is a copy of the closure of the lambda.

During compilation, closure class is created. During runtime closure instance is created.

There are two default capture modes in C++11. By reference and by value. It simply means, how the arguments are going to be passed in to the lambda class's member function. The memory is taken from the context in which they are defined.

Beware of dangling reference in case of by reference capture mode.

Sorting closure:

1. std::vector names = {"Damien", "Bob", "Alex", "Mari", "Dexter"}; //list initialization

std::sort(names.begin(), names.end(),[](const std::string& a, const std::string&b){ return a.compare(b) > 0; }// closure will compare a and b (two strings from the names' list passed as arguments, and return true to create backwards order.

The argument type has to be specified in the argument list in C++11. Auto variable cannot be used. Polymorphic or generic lambdas are part of C++14 though.

In Swift though, it can infer the type from the context, and the argument type need not specified . See e.g 4.

Swift:

Closure in Swift basically is a block of code that performs a function. It can be used as arguments.

Closure in Swift also has capture mode (by reference) of any variable or constant from the context in which they are defined.

So essentially seems to be same as that of C++. But. But. read below to know the nuance of Swift Closure.

Sorting closure:

2. let names = ["Damien", "Bob", "Alex", "Mari", "Dexter"];
func backwards(s1: String, _ s2: String) -> Bool { return s1 > s2; } // comparison function returns bool

var reversed = names.sort(backwards);
print(reverse);

or
3. reversed = names.sort( {(s1: String, s2: String) -> Bool in return s1 > s2 ; } )

or
4. reversed = names.sort( { s1, s2 in return s1 > 2 ; } ) // because Swift is cool to infer the argument's type from the list type.

or
5.  reversed  = names.sort( { s1, s2 in s1 > s2; } ) //because Swift can infer the return type from the code. So return keyword is not required.

or
6. reversed = names.sort( { $0 > $1 } ) //because Swift can use shorthand argument names.

or
7. reversed = names.sort(>) //because String has a > function that does the comparison. Swift will infer that you want to use string specific comparison operator.

-The end. No more shortcuts.