Generics and the Art of Inference Part 3 of 3

In the pre-generics days of Obj-C the only way to pass around things of unknown type was with an id type, but with Swift Generics/Protocols we can do things like Promises statically and safely with an associateType. Although large scale projects has been built in several Swift libraries already, we’ll look at how a barebones version can be written in under 40 lines of code and used in the context of your networking layer.

Modeling a Result enum type against how Optional is implemented in Foundation we create a Result type to contain a value of .somewith associated value generic type Wrapped or .error that would contain a BasicError

(1)The initializers are shortcuts that let us call Result(BasicError.unknown) or just Result(.unknown)

(2)fire unwraps the type using a switch and passes it into the correct Promise closure.

Our promise function stores a reference to the complete/failure functions until it recieves the Result via the trigger variable.
The async closure waiting to apply the Result to trigger will keep our Promise alive until it is fired.

Although this Promise implementation lacks the composability of a then, you can start to see how much we can accomplish with very little code.

Using this in the context of your networking layer might look like:

We can genericize this using a JSONDecodable constraint on a generic T to guarantee we can call init(object: [String: AnyObject]) throws.

Now the compiler can infer what is wrapped in our Promise using our complete function.

Also, thank you @nevyn for you feedback on this!

Generics and the Art of Inference Part 2 of 3

Our example this round will be constructing/deconstructing a struct to and from a Dictionary.

Here is the basic definition of the struct we would like to encode/decode.
We can define a protocol for this as simply:

Now we can extend our type to implement these, but before we do that let’s extend some functions into optional to make decoding easier.

Underneath unbox() casts our optional to an optional inferred result type. This is useful in the next two functions:
unboxString() and unboxArray. unboxString() clearly returns a String but unboxArray still needs to infer a result type for the generic Element type enclosed in the array.

The destruct() function is as we would expect, we create a dictionary and add the properties’ values in. Since subSorts is an array of the same type we can call destruct() on it as well and add it to the dictionary.

Using .unboxString() on the contents of our array is straight forward. The next line though, retrieving the AnyObject result from the construct array and working with it as a [String: AnyObject] result is a little more work. We take the construct array passed in, retrieve the SortItems in an encoded state(AnyObject) and call unboxArray on it. We then map that result with an initializer SortItem.init in hopes that the generic return type on unboxArray can be inferred through this mapping step. To our dismay, even though we only have one init that takes in a single parameter:init(_ construct: [String: AnyObject]) we get an ambiguous use of init error..
If we try commenting out all of the other initializers the error still persists because the basic initializer for our struct is there by default.

As we are of course unwilling to give into the defeat of ambiguity, let’s try tricking the compiler with just a bit of indirection back in our struct definition.

We did two things here. First we wrote out the default initializer for the struct and second we added default values for the second property in both of the two-param initializers. Now our compiler has forgotten about these and we no longer have an ambiguity error. And finally, we can return to this line of code to appreciate our generic array type inferring correctly through our map function.

Generics and the Art of Inference Part 1 of 3

The power of inference in Swift generics is something I find most people underestimate and underuse. Personally generics and inference has saved me from writing tons of boilerplate and duplicated code. In any case there is a ton I’d like to share about this topic, but to begin here are a couple common cases where I have found it useful…

Dequeueing Cells in a UITableViewCell/UICollectionViewCell

If your cell identifier and classname are identical, this UITableView extension is a great shortcut for retrieving a cell for doing two actions with a single key. It also is a great way of remembering what your cell identifiers actually are.

(1) Here we get the cell identifier by converting the class parameter into a string.

(2) Then we pass the identifier into dequeueReusableCellWithIdentifier and cast back to our type T, which we already know from passing in the class type as T.type. Now we no longer need to cast to a type inside our cellForIndexPath function:

And of course an extension on UICollectionView would look almost identical.

Loading From Nibs

We first need to create a protocol with an init for our nib loading requirement. Since UIVC already has this initializer, we can extend UIVC to VCNibable for free.

Now we reuse the cell dequeueing logic:

We then utilize the VCNibable protocol to genericize the init, as just using UIViewController.init(nibName:bundle:) for a subclass will load our custom VC with the wrong class type.

Using the same logic as in the dequeueing example, T.Type input allows us to first get the identifier by converting the type to a string (we assume the type and nib are the same name) and second use T for a generic return type.

The protocol conformance on T <T: VCNibable> then lets us call the init to retrieve the nib for that class.

we can now get a VC from a nib like so:

Going a step farther we can extend UIViewController to be able to present nibs from classes as easily as we can with segue identifiers:

Here we use NibLoader.loadNibFromClass to retrieve our nib VC with the proper class, and pass it into presentNibVC

presentNibVC then presents our VC and gives us a more sophisticated completion block to prepare the view with.

(1) Only types inheriting from UIVC can be presented by our UIVC, so we use guard and cast to ensure our nib inherits from UIVC. We used a generic here instead of UIVC in the param so that we can later pass it into the completion later.

(2) Since presentViewController has a completion block in the form of (() -> Void)?. I am just calling our custom completion(T -> Void) inside a compatible closure, so that we can finish with access to the view we are presenting, without all the extra mess we might otherwise have.

And finally we can do something concise and magical like so:

We could even go a step further and add a pre-present closure, to specify how to present the view, i.e. modally, over current context, etc.

Trying to Build a Better Hashable

The standard example: You have a type that is uniquely identifiable by an id property and want to be able to use contains on a collection of this type, while not worrying so much about having duplicates. For a single struct, we can conform to Hashable and implement a == case to handle the object.

The reason I am returning id above instead of running it through a hash function is that id is already a unique identifier and an Int.

Read section below if you’d like a general overview of hashing

Hash Values

A hashValue is traditionally a value generated from an input by a hash function, which runs in constant time. The hashValue is then used internally as part of calculating object equality. Since the hash function output should be some bytes fewer, there is no way to avoid repeated output values… Meaning two different input values can potentially have the same hash output. The point to remember here is that if two types have different outputs, their input is definitely not the same.

The purpose of a hashValue is a quicker, constant time, implementation of proving inequality when hashValues are different. In the case of equal hashValues we only know they COULD be equivalent. So in these cases a function to compare the type is needed for checking definite equality, thus the need for the == function definition(and why Hashable requires conformance to the Equatable protocol).

Id Hashable Protocol

What if we have many different types that are uniquely identifable by id? We of course expand the previous implementation into it’s own protocol!

This by default works the same way as our first example, assuming that the type has a property id that is a unique identifer. We also replace the the Equatable == function with a generic one conforming to the IdHashable protocol. We could now rewrite the original implementation as such below:

If we decide we are going to change what constitutes the uniqueness of the type, to something more complex than an Int, to a String or something…

We could easily piggyback off of the hashValue implementation on the String struct. Although a sound way of implementing a hashValue, this defeats the purpose of using our custom protocol over the Hashable protocol since we need to implement a type specific equality function still… Since our id value can now be the same for two different string values.

For these cases our protocol seems a lot less useful,… since we need to implement == outside of the function. So we are doing just as much work as we’d be doing to implement Hashable, but we could improve it slightly by bringing the logic for == function into the type definition and leaving it with a default definition that compares id.

Now this seems more like Objective-C, but we don’t have to worry about including a function outside of the conforming type and can just implement id if you have a uniquely identifiable Int, while still having the option to also implement isEqual for types with true hash values.

Our conforming types now look like:

And our uniquely Identifying type looks like:

More to note on isEqual and global operator definitions, I recently found out that operators are eventually planned to be allowed inside of type definitions, see mention here in this swift-evolution thread.

Swift Gist Favorites of 2015

Taking a look back recently, I realized a lot of my Swift sharing has been in the form of gists and less in the form of blog. As thus, here is a breakdown of my top three Swift gists since 2.0 came out.

3 – Optional Array Accessor

This is an array accessor that returns nil if the index is out of bounds. I use the &[index] syntax to mimic the unsafe arithmetic operators indicating operations are over/underflow-able without an error in Swift. i.e &+, &*,…

2 – Nested Keys in Dictionaries

The task here is to use a dot separated string as an accessor to navigate a series of nested dictionaries. My idea here was to use reduce to traverse the nested dictionaries. This gist came about from a conversation with @matthewcheok, who was looking for the best way to achieve this kind of functionality for use in JSONCodable.

i.e.
let key = “a.b.c.d”
let dict = [ “a”:[“b”:[“c”:[“d”:”Data”]]]]

1 – Reduce Without Initial Value

There are some cases where the requirement for reduce to have an initial value takes away from its usefulness. This is an implementation called list that doesn’t need one! Making it throwable was necessary for handling the edge case of calling list on an empty collection.

Cast-Free Arithmetic

Updates: 10/13/2015
I recently gave a presentation on this topic @Realm, available in video format here.

Cast-Free Arithmetic Part 1:

Two months ago when WWDC week was happening and while many attendees were going to lectures, mingling at parties, and networking, I was resolved to take a deep dive into Swift 2.0 as quickly as I could. I started with the idea of using protocol extensions to consolidate all of the repeated code I had in an extension on several number types for dot property number conversions here. After working through it with a friend we were able to quickly accomplish this with the addition of pattern matching here. Afterward, whilst entering the next session related to UI, just on the cusp of our small success, I suddenly had another idea. Why not use generics in conjunction with our newly created numberConvertible protocol to completely transcend the need for casting between number types? Essentially crushing the type checker and giving us the ease of arithmetic we remember from Objective-C and were initially annoyed by it’s lack of in Swift. Thus, below is the road I took in achieving this end.

Inter-workings of Number Casting

Number casting is nothing more than a series of initializers on each number type. That is, each takes in all other “castable” types as input on creation. So writing Int(4.5) is doing the same as Int.init(4.5). In fact we can see where it is defined in the stdlb if you write out let test = Int.init(4.5) in XCode and command + click on the init part. To save you some clicking here is what it leads to.

Constructing our Protocol

With this understanding we can construct a protocol that has these initializers and extend our number types to conform to them.

There is only one hiccup so far, CGFloat does not have this init(_ value: CGFloat) so we have to add it ourselves. We will just initialize CGFloat to a Double and then use CGFloat‘s init(_ value: Double).

Update 1: A better way for extending init(_ value: CGFloat) on CGFloat is to assign it to self. Casting to a Double first is inefficient – The original implementation was written for the first beta of Xcode 7, on which I am not sure this current implementation works.

Generics, Inference, and Pattern Matching

Now we will rely on the type inference of generics and extend our protocol with a universal convert method.

We define our function with the expectation that our return type T will conform to NumberConvertible, giving us access to all of the init functions defined in the protocol. We can use a switch-statement on self, to check which number type we are casting from in the form of case let x as numberType. Then use x to initialize to type T with T(x) which is actually T.init(x) and call fatalError if something unexpected happens. At this point we can now use convert() to cast to another type without specifying the type.

Cast-Free Arithmetic Part 2:

Mixed Type Arithmetic

Stopping now doesn’t get us much, but beyond this things got complicated fast with compiler restrictions leading us down winding paths. We will start off by solving a simple case and build up to harder ones from there. So our goal to start will be to use our convert() function in something implicit that works with mixed-type arithmetic. Let’s shoot for this:

Overloading FTW

We can accomplish this by overloading our + operator, converting both numbers to a Double type, adding them, and converting the result back to the expected return type.

This works because our (v + w) addition defaults to using the stdlb definition of + which is what we want. If we were to not convert to Double first, adding v + w would cause a recursive loop.

More Complexity

Our accomplishment is short-lived, as a third type breaks our solution and becomes our next goal.

The compiler can take care of a single pair of mis-matched types, but if we add a third type the compiler throws an error. It seems the result type of the first is not inferable to the input of the next operation.

When I reached this point it was around mid-week of WWDC, so I took my problem to the labs, where I sat down and got to ask for help from the all-Swift-knowing Dave Abrahams. His resolution was that the compiler is probably not up for the task at hand, but he could graciously attempt a hacky work around if we liked, even though it would probably not work. Of course we said, yes please, by all means let’s see this hacky work around. Dave started writing a promote class to get the compiler to figure out what type should come next, but in the end the compiler failed us just as he predicted.

Initially discouraged,… I settled for something that I thought would actually be attainable, a single common return type. This would allow us to still mix and match number types in our arithmetic, but only allow for a single return type.

And there you have it, as long as we are only expecting a Double in the end, we can mix and match number types across multiple operations.

Cast-Free Arithmetic Part 3:

Unsafe Arithmetic: The Return of Multiple Number Types

So if you are still following along we have a solution that returns a Double, but of course this isn’t always what we want.

My first thought for solving the situation above, is to overload the assignment operator =, but this is restricted, so let’s try for a new operator ?=.

This works, but as you may have already realized, these examples are a bit contrived, since it only works for values that have already been initialized.
For instance we cannot assign a value to let m:Int. Since the assignment operators that we are allowed to overload have this restriction, we have to take another route in solving our next goal.

We could try to use an infix operator that takes in the number type on the left, and the operation result on the right, our Double. If we change the precedence to always call this operation last, everything should happen in the correct order.

Now, this strategy is questionable, as it is not much better than just wrapping the whole operation into an initializer Float(w + x + y). This solution clearly falls short of our goal, which is at it’s core to make things easier.

So let’s re-evaluate our options, dive deeper into how we are defining our overloaded arithmetic operations, and get a bit darker here, as we venture to do something that is probably quite unsafe in terms of type-safety…

Very Unsafe Arithmetic

From my first attempts at WWDC up to this point I have talked and worked through several ways I could trick the compiler to do my bidding.
Alternating between types as such was suggested to me here, but this still doesn’t work exactly right for explicit return types and is quite exhaustive to implement. So what I came up with in the end is something a bit unsafe.

Let’s begin by uncoupling our convert function to work outside of our protocol as such:

This is the first step on our unsafe path, but let’s continue along these lines and define a summation function that looks quite similar.

Now let’s bring down the compiler’s expectation on the first item in the pair and no longer require that it conform to NumberConvertible.

Now that our left component is allowed to be a non-number type we begin to walk a fine line on type-safety, but it does free the compiler from having to infer a type, allowing us to combine number types and return to any other number type.

And more tests

So now for the most part our goal is achieved. Although it comes at quite a high price, since this is now being accepted by the compiler as well: let o:Int = "NOT A NUMBER" + 5.

Looking more closely, in-depth testing reveals this method still has a flaw, in that if you have exactly two operations, it will only work if the last number to be evaluated is the same as the return type or if the first two numbers are the same type. Appending + 0 to the end fixes the problem.

Double = Int + Float + CGFloat ---FAIL

CGFloat = Int + Float + CGFloat ---OK

Double = Float + Float + CGFloat ---OK

Update 2: After more beta releases and compiler improvements the original implementation now seems to be working equivalently well against this more unsafe version, suffering only from the same two operand potential compiler warning issue.

You can check out the whole project here and my work so far for this last solution on the branch NoPreferenceType

Recreating Defer Syntax in Swift 1.2

So, a few days ago, I had the bright idea that trying to recreate some of the shiny new Swift 2.0 features in Swift 1.2 might amount to a fun challenge. I first thought about recreating guard syntax, but quickly got stuck at finding a way of calling return in the scope of a function one level up (If any of you have an idea of how to work it out please let me know). So then I found something more attainable the defer syntax.

Here it is in swift 2.0:

Output:

    test1
    tested!
    test3 b2 c3
    test2 a1

So now we have a target, save several defer functions that capture variables from the current scope, and call them right when the scope is about to end. In Swift, the objects created in a scope will get released at the end of that same scope if it ends with nothing else holding a reference to it. So a sound strategy might be to create a class that stores functions to an array and piggyback on its deinit, where we will of course call all of these functions.

Now let’s see what happens if we call this function without assigning it to a variable:

Swift 1.2 Output:

    Start Deinit
    test1
    test2
    test3

Well, that is not the result we wanted ;( It appears that if an object is not assigned to a variable in Swift 1.2 it is deinitialized immediately. Another interesting thing I discovered in my testing is that this actually works the way we want in Swift 2.0 playgrounds, although the result is the same as 1.2 from within projects, and unfortunately we can’t get a printout with running code in xcode 6 playgrounds.

Swift 2.0 Playground Output:(print function adds \n in Swift 2.0)

    test2

    test3

    Start Deinit

    test1

So now let’s abandon our quest for an exact match to Swift 2.0 syntax and settle for something that takes an extra step.

Output:

    test2
    test3
    Start Deinit
    test1

Now that we have a simple case working, let’s add nesting function calls, and captured variables into our test, and finally make use of the fer function we defined.

Output:

    NestStart
    test2
    test4-c
    Start Deinit
    test3-b
    test1-a
    NestEnd

Output in Swift 2.0 w/ actual defer calls:

    NestStart

    test2

    test4-c

    test3-b

    test1-a

    NestEnd

Swift 1.2 defer syntax achieved!

Also, thanks @matthewcheok for giving feedback on this.

Swift 2.0 Type Introspection

I’ve been at WWDC this week and it has been a whirlwind. I am feeling quite overwhelmed, overloaded, and oversaturated with newness, but to that effect I have something small to share about introspection in Swift 2.0. Pre Swift 2 you may recall some talk of a mirrorType mentioned both here in this video and in this blog post. This is accessible from things conforming to the Reflectable protocol using the function getMirror(). Although, this is still available in Swift-2, it is limited, and according to an Apple engineer i talked to, never really intended for public use. With Swift 2, though, we can just init a Mirror struct with an Any as below:

And there you have it, type introspection!

First Post

 

Hi All,
This will be a blog to share my experience in studying Swift. I look forward to sharing the functional paradigms I have learned, the not so functional paradigms, and my experiences at WWDC.