Monday, June 23, 2014

Advanced Swift - Part 2

This is a summary of the topics and notes that I found interesting from watching the Advanced Swift WWDC session 404 by John McCall and Dave Abrahams. I highly recommend you watch the session. It also has some commentary from me which you may or may not agree with. Please feel free to join the conversation. You can find Part 1 here.

I have also attached a swift playground file with the sample code for part 2.


Swift Language Protocols


In swift, you can hook into language features by using special protocols. Swift is very much a protocol based language. Some of the language protocols include:

LogicValue if LogicValue {
Printable "\(printable)
Sequence for x in sequence
IntegerLiteralConvertible 65536
FloatLiteralConvertible 1.0
StringLiteralConvertible "abc"
ArrayLiteralConvertible [ a, b, c ]
DictionaryLiteralConvertible [ a:x, b:y ]
Equatable x == y

Let's look at a simple example of implementing the Printable protocol that allows you to provide a custom description that will be used by println.


Unfortunately when using the playground, the Printable protocol isn't used. I assume this will be fixed at some point.

Subscript Declarations


You can use Swift's subscript declarations to add subscripts and even support for subscript ranges. Here is a useful example adapted from a Stack Overflow post that extends the String class to add subscript access to Strings.


This allows for natural String manipulations, which I think should actually be built into Swift:

var string     = "abcdef"
var firstChar  = string[0]
var subString  = string[0...2] // subString equals "abc"
var subString2 = string[2..4]  // subString2 equals "cd"

While you can have your subscript code perform arbitrary work, care should be used to make them behave in a way that is consistent with what people would expect subscripts to do.

Operator Overloading


Swift also supports operating overloading. I'm not a fan of operating overloading as I think it creates maintainability issues. I would advice to use operating overloading very cautiously.

Operators are defined using global functions so they are available outside the scope of the classes they work with:

We also added a new method to our Thing class which is nameWithArticle so it can provide a basic implementation of using "a" vs "an".

The next feature is one that I was hoping Apple was going to bring to Objective-C and that is Generics.

Generics


Generics is a powerful concept that allows you to reuse code while preserving and leveraging strong typing. In fact, we have already used generics (see the Range parameter under Subscript Declarations). No more using an id, NSObject, or in Swift the Any type unless you need something to be truly typeless such as a collection that can hold multiple types or for dynamic polymorphism.

Here is a simple example that shows a generic function that just prints the given value to the console and then returns that value back out. 



Most compilers treat generics as templates and generate additional code for each type instance of the generic. However, Swift doesn't to do this. It only has one instance of the code for its generics. In addition, the Swift compiler generates more efficient code when it can make optimizations based on the type. 

You can also constrain the type information to force it to conform to a protocol. This allows the compiler to know what operations can be performed by the type.  For example:


The above example uses the Equatable protocol to let the compiler know it can perform the "==" operator. There is a lot more on equatable and generics in the session, and I encourage you to watch it. There is some very cool stuff that Swift can do with its generic system. There is a mind blowing example of a generic "memorize" function that is worth studying.

Wrap Up


Lots of people are starting to learn Swift, including myself, so I hope this was helpful. If you see anything incorrect or if you have different opinions please share your thoughts.

You can download the playground file which will allow you to play with and copy and paste all the code used. Note that you will need XCode 6 to run the example.

Thanks,
Tod Cunningham
Five Lakes Studio, LLC
co-founder

Thursday, June 19, 2014

Advanced Swift - Part 1

This is a summary of the topics and notes that I found interesting from watching the Advanced Swift WWDC session 404 by John McCall and Dave Abrahams.  I highly recommend you watch the session.  It also has some commentary from me which you may or may not agree with.  Please feel free to join the conversation. :)

I have also attached a swift playground file with the sample code.


The Simple Thing Class


The first class the session introduced was the "Thing" class.  It's fairly basic, so I went ahead and completed its implementation. This was also the first time I realized that class initializes don't use the "func" keyword!  This is because initializers have some special characteristics that distinguish them from functions some of which is explored later on.


The location can be nil (no object) so it uses the "?" modifier.  We can easily create an instance of "Thing" using named parameters:


The simple Thing class is actually using a simplified version of argument names that make the caller's argument name equal to the name used by the initializer.  You can also create a version that uses the full argument names.

Full Argument Names


You can actually use the argument definitions full form to define argument names that allow the caller of the initializer to use a different name then what the initializer itself uses.


You can also do a condensed version of the arguments where the caller doesn't need to specify the argument name.  This is done through an anonymous wildcard expression.  Let's first take a look at these expressions to see how they work and then we will apply them to argument definitions.

Anonymous Wildcard Expressions (_)


Swift has the concept of an anonymous wildcard expression which is represented by an underscore (_). The wildcard expression can be used when you want to explicitly ignore a value during assignment. This comes in really handy when dealing with tuples.


You can apply the same technique to argument names.

Anonymous Argument Names


Instead of having explicit argument names you can specify anonymous argument names.  This should only be done in situations where the code becomes more readable/maintainable without the named parameters.


To me this is an example where Swift is giving too much flexibility in its expressiveness and is asking for abuse.

Protocols


Protocols are like Objective-C protocols in that they don't provide an implementation.   Here is an example:


This example also introduced the difference between the === and the == operator.  The === means the objects must be the same instance where == just means they need to be equal but not necessarily the same instance.

Testing for Protocol Conformance


You can use a conditional cast to check if an object conforms to the protocol.  However, the example given in the session was incorrect.  When trying to compile it, I kept getting an error "cannot downcast from 'Thing' to non-@objc protocol type 'Pullable'".  According to the documentation under "Checking for Protocol Conformance” you can only test for protocol conformance of objective-c compatible protocols.   This makes the protocol only usable for class types which is fine in this case.  So making the adjustments to the protocol we can now implement a function that tests for conformance.


The example given also only specified the use of the "as" operator as opposed to "as?".  However, the documentation states that "as" will trigger a runtime error if it can't cast to the specified type so we need to use the "as?" operator to allow for cases when the object doesn't conform to the protocol.  So we had to use the "as?" operator as shown above.

Wrap Up


Lots of people are starting to learn Swift, including myself, so I hope this was helpful.  If you see anything incorrect or if you have different opinions please share your thoughts.

You can download the playground file which will allow you to play with and copy and paste all the code used.  Note that you will need XCode 6 to run the example.

Thanks,
Tod Cunningham
Five Lakes Studio, LLC
co-founder