00:27:43.760
Good news, everyone! There are no exceptions in Swift; there are just errors. The program just crashes. You can't recover from this. There may be an exception library or frameworks built into the language in the future; I don't know.
00:28:02.240
But right now, this is all we can do. We have to be very confident with the key that you're fetching out of your dictionary because if you fetch one that doesn't exist, the program execution ends.
00:28:18.720
Here it is; we will go through it piece by piece. It looks kind of crazy, but it’s not that bad. We start by opening or extending the dictionary type to define a fetch method on the dictionary type that fetch method has three parameters: a key, a default value, and a closure we’ll call it the default valuer.
00:28:37.680
You’ll note a couple types here that we haven’t seen before—the key type and the value type. These are actually generic types defined on the dictionary type, representing whatever key type and whatever value type were declared with that particular instance of a dictionary.
00:28:57.760
You also notice that the default value isn't optional, so we don’t have to specify a default value. We want to be able to call the fetch method without a default value.
00:29:16.160
And it allows that, so we declare it as an optional defaulted to nil. You also notice that the default value is forced internal, and this allows us to pass that parameter without an external name, wanting to match the Ruby hash fetch method.
00:29:30.320
Finally, the third parameter is the default valuer; the type of this parameter is a closure with no parameters coming in. The output is a value, so after that closure is evaluated, it must return the same type as the key type in the dictionary.
00:29:50.720
You should also note that it’s an optional closure type, and that’s so we don’t have to specify a closure when we call this method. We don’t have to specify a closure when we call this method, and it is optional to meet that robust type signature of the fetch method.
00:30:07.600
After you call the fetch method, you're going to get a value. You're guaranteed to get a value—some value or the error, of course. But we won’t return an optional; we always get some value from the fetch method call.
00:30:24.560
So, this is the body of the method. It’s actually just two lines. First we attempt to bind all these different optionals, either from the dictionary itself, from the default value passed in, or from the closure being evaluated, and then return that.
00:30:44.000
If it can’t, we raise an error. You’ll notice that we're using the coalescing operator here to sort of chain along those different optionals. The first try is just subscript. We’ll just subscript into the dictionary and try to fetch that key. The subscript operator in Swift returns an optional.
00:31:04.480
That's because a dictionary may not contain the key that we're subscripting, but since we’re using the coalescing operator, that evaluates first, and if it did contain a value, that value would be bound to the constant in this optional binding on the left.
00:31:26.720
If it didn't, evaluation would continue to the right side of the coalescing operator and the default value also an optional, if it’s present, it would be bound to the value on the left constant. If it's not there, execution would continue to the next coalescing operator.
00:31:42.720
Finally, it tries to execute the default value or closure. You’ll notice this weird question mark in the middle; that’s the optional chaining. Since the default value might be nil, it's an optional, and we need to chain the parentheses onto the end of it and call those only if that value is present.
00:32:04.960
If it is present, remember, we talked about optional chaining; it always returns an optional, so we can bind the result of that optional back over to the constant on the left. If any of those in that chain evaluate to some value other than nil, they would be returned by the block following the condition of the if statement.
00:32:24.640
Otherwise, there’s no way to find a default value, so we just error out, and execution ends.
00:32:46.560
As I pointed at all those things, here it is: the entire dictionary fetch method defined in Swift. It's really not that bad! I was intrigued that it was quite simple to define. One thing I did want to note is we could also define this as multiple.
00:33:00.720
Since we have a type system in Swift, we could define multiple fetch methods on the dictionary that all have the signature required instead of using these default values and optionals and stuff as parameters.
00:33:15.360
We could just have one that only has a key that would raise an error if the key is not found, but in this case, I really liked being able to exploit some of the different features of the language and see them in action for our implementation of the fetch method.
00:33:32.320
Here’s how it’s used. We have a dictionary with keys and values. We can fetch a known key, and it’s returned. If we fetch an unknown key, an error occurs; that’s that fatal error. If we fetch an unknown key with a default value, it returns the default that we defined.
00:33:48.480
If we fetch an unknown key with a closure evaluating to that value, it’ll just return the evaluated value from the closure. It’s pretty neat to see how close this is to the same thing in Ruby.
00:34:04.480
Here’s the hash fetch method, and really the only difference is that the hash definition is just slightly different. So that’s it! We made it! Woo!
00:34:20.880
So this is what we learned in Swift today. We learned about values and types, options, and conditions, and functions, parameters, protocols; there’s actually a lot more.
00:34:35.200
Obviously, we didn’t talk about custom types. We briefly saw classes in Swift, and there are different semantics between value types and reference types in Swift. That’s all things that you can learn more about on the Apple website.
00:34:53.239
Definitely check that out! I kind of feel like I'm pushing Apple a little bit, but it’s not my intention. I think Swift is a neat language, and I’ve had a lot of fun playing with Swift as a language. I haven’t done any iOS stuff with it; I’ve just been playing with it outside of their app development ecosystem.
00:35:10.240
Also, again I want to mention, we teach boot camps on this stuff at Big Nerd Ranch. They’re a lot of fun! If you like, we kind of go off in the woods and try to disconnect everyone from the internet to focus on learning for a week.
00:35:30.720
I also blog about this, and my blog is sort of similar to the talk in that it shows Ruby examples and their equivalence in Swift, but they go in a little different direction. So definitely check that out if you’re interested.
00:35:49.680
I also did a talk at a local meetup on Swift; this talk was more about just language stuff—it didn’t compare it to Ruby, just 'Here’s Swift, here’s what you can do.' So if you’re interested in Swift, this may be a good resource to check out.
00:36:06.560
And with that, that’s all I have to say! Thank you so much! I am happy to entertain questions if you all want to ask questions.
00:36:18.320
If you have any questions, I’ll tweet slides and examples and all that stuff if you want to look at them.
00:36:26.480
So, what's up?
00:36:37.440
I noticed that you had to do a forced internal for functions past like the first argument. Does that mean that by default you can only have one internal argument and the rest have to be external?
00:37:00.080
By default, on methods—which the distinction between methods and functions for whatever reason Swift calls functions defined on objects or structs or whatever—methods are functions that belong to some type.
00:37:16.880
The default semantics are that the first parameter is internal and all other parameters are external. You can force all of those to be internal, but they are all external; you have to do it explicitly.
00:37:34.080
The reason I think they did that at least at this point is that it’s very similar to Objective-C; in that, Objective-C the first parameter to a function or method is internal.
00:37:49.360
So you can name your functions like 'do this and that' kind of thing. I personally don’t like it. My opinion right now is that they should internalize all parameters and let you opt into the external thing.
00:38:03.040
Another reason for that is when you define a default value for a parameter, I didn’t go too much into it, but if you define a default value, it will force it to be external unless you force it back to internal.
00:38:20.960
The difference is that in functions, which are blocks of code defined outside of a class or struct or type, functions have all internal parameters by default. Functions actually do have all internal parameters.
00:38:35.760
The example I showed, the second one was an external parameter because it had a default value. It was really bizarre to me that just defining a default value makes it external. For reasons...
00:38:51.760
Does anybody else have questions?
00:39:08.960
Oh yeah, what's up? I'm going to use Ruby motion.
00:39:19.880
From what I've heard about Ruby Motion, I haven’t done much iOS work; I’ve really just been playing with this as a language.
00:39:30.080
What I’ve heard about Ruby Motion is you kind of have to know all the Objective-C stuff to use it very effectively. The thing of course that I'm most drawn to is the idea of Ruby Motion where you can breakpoint your iOS code and execute like a repl inline; that seems really cool.
00:39:45.680
But I haven’t used it personally.