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.



No comments: