>> [MUSIC PLAYING]
>> DAN AMRMENDARIZ: Everyone, welcome to the CS50 seminar,
iOS App Development with Swift.
I'm Dan Armendariz, and I'm a preceptor of computer science here at Harvard.
>> And the next hour is going to be a whirlwind tour of as much stuff
about this topic as we can fit.
I will post all of the source code that you will see today online.
We might not be able to actually go over everything
that I'm that I'm showing you in this hour.
But at least hopefully through the comments of the source code,
you'll be able to try to figure out what exactly is happening for those things
that we don't quite get to.
>> Overall, the structure of today's talk will be as follows.
We'll start out doing some basic syntax with the Swift language,
going into some of the more advanced syntax of the Swift language.
Because the language is really modern and it
has a lot of high level features, things that we haven't
seen in C throughout CS50, or even some the other languages
that we've started using in CS50 like PHP,
so I am going to have to try to introduce also some topics that
are related to higher level languages that you may not see in depth in CS50,
but you will see in later computer science classes.
So it's going to be a tightly packed hour.
And please feel free to let me know if you have any questions.
So if you're interested in doing development
with Swift, or really any iOS app development,
there are a couple of requirements.
First of all, you have to be using a Mac, running in the examples
that we are going to be using today, a relatively new version of OS
X. In this case, I'm running X 10.5.
You can be running 10.11 if you want.
But everything that you're going to see is involving Xcode 7 and later,
which has the latest version of Swift, which is Swift 2.0.
This is actually a pretty important distinction.
A lot of the syntax has changed pretty significantly
in some cases from Swift 1.0, which was released last year,
to Swift 2.0, which just came out this fall.
So we're going to show Swift 2.0.
A lot of the things that you search for online
when you're trying to get additional information about a variety of things,
you may want to explicitly search for Swift 2
rather than just plain old Swift to make sure that you get the syntax correct.
>> In fact, this is generally true.
There's a rapid amount of development happening in the Swift language
ever since Apple released it, I think what, it's been a little over a year
now.
And things have changed dramatically in that time.
And so don't be frustrated if, when you're looking around
for topics on Swift or how to accomplish something using some example code
or something that it doesn't actually work on Swift 2.0.
Make sure you are looking specifically for that version
to try to minimize effects of different versions and those sorts of things.
>> I'll try to point out just some things that are different to older versions.
But it's something to watch out for.
That's probably going to be one of the biggest headaches
that you will have with Swift is finding example code that is older, even just
by a few months, trying to use it in your more modern project.
And it just simply doesn't work.
You're getting compiler errors, syntax errors, all sorts of crazy stuff.
So just be patient with that, and you will hopefully
have a pretty nice experience with Swift overall.
>> Now you can actually join-- and I hope we actually still have this this year--
CS 50's Apple app development team, which
will allow you to install any apps which you create on your iOS devices.
So take a look at this URL if you are interested in doing that.
>> So just a couple of things about Swift itself.
It is a compiled language.
But you will see that some of the features that we use
allow it to be used also in a bit like an interpreted way as well.
>> A lot of the syntax is borrowed from C. It's based and written in C.
And so we will see that there are a lot of takeaways
from your existing knowledge from C that we can port to Swift.
>> But there are things that make it very different from C.
It is very strongly typed.
There's automatic memory management.
You're not going to have to use malloc or free anywhere.
It's designed for generality.
So in other words, you can use it in all sorts of contexts, from Apple Watch
to iPhone all the way up to OS X, and even some servers, even some scripting.
But we'll see that the support for scripting
isn't quite there yet as it is in other languages.
So most likely you'll be using this exclusively for development
on your Mac or your iPhone.
>> And it has a lot of modern features.
And a lot of these things are stuff that we're going to try to address today,
but also our topics that frankly, we can devote entire courses.
In fact, CS 51, which is offered next semester,
focuses a lot on these topics that are described below.
So you can spend an entire semester understanding these things.
But we're going to try to get through them
at least enough that you can understand what's
going on when you look at a Swift program
and be able to hack your way through it for the final project.
>> Now one of the best ways that you can get additional information on this
is frankly just through Apple's provided documentation for Swift.
There's a lot of APIs that are available.
And this is a good home base for you to look for, specific things that you
want to do with an API involving iOS.
If you want to use the camera for example, you can start looking here,
and also use Google and Stack Overflow as you would normally.
>> Any questions on this before we jump right in?
All right.
Let's move on.
>> So first, I have a number of example files.
And I'm going to try to step through them relatively quickly.
This is the Hello World file for Swift.
It's very simple.
There's way more comments than there are actual code.
Notice the actual code is at the very bottom on line 14.
It says print.
And then it's a function call.
We're passing into it a string called Hello cs50.
Notice that there's no semicolons.
Notice that there's no int main.
There's none of the cruft that we had with C.
When we are using Swift in this way, which is just written in a text file
and stored on my computer, then I can compile it and run it.
>> Notice that here I'm not using the CS50 IDE.
This assumes that I am running and that I'm on OS X,
and that I have Xcode already installed on this machine in order for this
to actually function.
But this is just a normal text file that we can then compile and edit.
So let's see how this actually works.
What if I want to compile it?
swiftc 1.swift.
After a moment or two, it will see that we have now
compiled this into a file called 1.
And now we have printed our CS50, our Hello World application rather.
>> Notice one other thing as well is that by default,
we didn't have to input a /n to print a new line.
By default, the print function in Swift will print a new line for you.
You can pass an optional additional parameter to tell it not to do so.
But Google for more information on that.
By default, it will do the print line.
>> All right, so let's move on then to some other things.
So how can we actually define variables?
We can do that's using one of two methods.
And the one that I want to tell you about first is this let definition.
And this is important because effectively
what we're doing is defining a constant.
We are going to create a variable, or rather a constant called name,
provide to it some data-- in this case, the string Dan.
But by using this let keyword, we are saying
that this variable-- or again constant-- called
name is never going to be changed.
It's going to be immutable throughout the duration of this program
or throughout the duration of the context
that that variable is available.
>> This is really important that when you have some data that is not
going to change in your program, and you'll see a variety of examples
about when we want to use let versus the other syntax,
it's important that you use let wherever possible because this notifies
the language that it is not going to be changed,
and it can actually perform a lot of optimizations
to improve the speed and the safety of your program.
And by safety, I mean not let it crash with crazy errors
that we might be accustomed to seeing in C.
>> Then we can use string interpolation to encapsulate this within a string.
So we can see in this print line, print hello,
and then using backslash open parens, and then the name of my variable,
in this case constant, close the parentheses.
I'm essentially then putting the contents of this variable called name
inside of the string and then printing the result there.
>> There's one other change to this file which is that I have, at the very top,
put in a shebang line, which basically just specifies
that I want to use the Swift interpreter, which
means that I no longer have to compile this particular program.
I can just run it like its own script.
But this is, in this case, behind the scenes being compiled and then
being run.
It's just invisible to us.
>> All right, so let's move on.
So there's a bit of trickery that just happened before.
I showed you that I could define a constant.
And I could provide some data to do it.
But in this case, notice that I didn't actually specify the type of data
that it is.
And that's because the compiler, Swift can
infer the type of data just based on the data that I put into it.
Because it knows that by evaluating this variable right here, this data right
here, it knows that it is a string.
And so this constant name is therefore going to be a string as well.
>> But we can also be explicit about the type that's
we are going to use for constants or variables
by using this syntax instead-- let name colon String equals
Dan, which in this case means we're going to define a constant called name.
It's going to be of type String.
And the value is going to be Dan.
Now the other way that we can create variables--
and these are mutable variables, which means that we are, in fact, going
to change their contents sometime in the duration of the context
that that variable is defined-- we use the var keyword instead of let.
But again, by default, unless you know that you need to manipulate that data,
try to use let for performance improvements.
>> In this case, I can then specify the type of data
that we expect to be inside of this new variable called label.
It's going to be a string.
And we're going to then concatenate two strings together, the string hello,
and the string represented by the variable, or rather the constant name.
>> So this is nice because this is somewhat PHP like in that we
have very easy string concatenation.
We don't have to automatically use any sort of memory management
to increase the size and do any sort of funny things there.
This works as we would actually expect.
>> All right, any questions on this?
>> Now the other reason that we need you have the ability
to be able to define what type of data variables are
is because sometimes we don't want to initialize variables
with some data at the point of definition.
So in this case, let's say that I want to start inputting
some grades into a grade book.
Well I know that one of the variables that I want to be
is going to be a mutable grade.
And we also know that we want it to be an integer.
But maybe we don't yet have that grade available.
>> In Swift, you have to define the type of data
that is associated with a variable or a let constant
before you can actually use that variable.
Because it is strongly typed, you have to associate a type
with these variables.
>> So in this case, if I've not properly initialized the first with some value,
then I need to tell Swift what I expect the data type to be.
And it's going to remain that same data type
throughout the history of this program.
>> Now you might be tempted as soon as I have created this grade variable
and provided it an integer of 100, now if I
want to try to concatenate a string with that integer,
might be tempted to still use that string concatenation operator
like we did just a few lines before.
But unfortunately, this will actually not
work, because you are essentially performing
an operation on two different types.
>> Now this is very different from other languages like PHP which are really
loosey goosey with their sort of types.
They're just like, yeah, whatever, I don't care.
Just give me one type, and maybe I'll do the right thing.
>> In this case, Swift is extremely strict about the types
that you are dealing with.
This summation operator or concatenation operator
has essentially a couple of different possible options.
You can do summation with integers, or you
can do string concatenation, and perhaps some other things as well.
But if that operator doesn't recognize what is on either side of it,
or rather the combination of those two types, isn't what it's expecting,
then it's going to cause a failure.
>> So in this case, what does it mean to have a string plus an integer?
Well in the context of this, we probably want
to do a string concatenation operation.
But of course the computer doesn't have that sort of context.
And so we need to provide that additional information
to let it know what it is that we want to do.
>> So in other words, the fact that Swift is strongly typed
means you have to do a little bit of additional work
to get it to operate the way that you would want.
But as a result, it is safer.
And once you have take into account those types,
things just frankly start to work pretty well.
>> So in this case, we then would perform string concatenation
by explicitly casting the integer to a string
by wrapping it in this capital S String function,
and then using the string concatenation operator to modify our label variable,
and then print it out.
>> So far, so good?
All right, let's move on.
>> Now there are a variety of data types that we can use in Swift.
As you have become accustomed to, we can create a mutable array.
And that array can only contain a single type.
>> So in this case, we're going to create a mutable arrays of integers, which
we will call grades, and we will be able to store that in this square bracket
format as you've grown accustomed to in a variety of other languages.
But notice that here we're defining a couple of things.
grades is a mutable variable-- we not use the let keyword.
So that means we can then modify the contents of this array.
It is of type Array Int, and we can tell that
based on these square brackets here.
>> Now one of the nice things about this is that we
have access to a lot of additional information
about the array just using some simple dot notation.
So for example, grades.count provides to us
the number of items that exist in that array, which we can then access pretty
easily simply using that dot notation.
>> If you want to add additional items to this array,
you cannot do the PHP style where you just explicitly define,
at a given index, some value that you want to insert.
Instead, use the append method in the array type
to append that item, 95, to this list.
>> So now this array has the following contents-- 100, 0, 90, 85.
And now we've appended 95 to that as well.
>> There are other ways we can append things.
You can actually use a summation operator,
which will be interpreted as an array append operation.
And you can then append another array, whose contents are 70 and 80,
to that array.
So now we have the contents in this variable
grades-- 100, 0, 90, 85, 95, 70, and 80.
This is just a nice little syntactic sugar that Swift provides to us.
>> So if we want to sum the grades, we're perhaps
going to want to iterate over every item in this loop.
And we do have, in Swift, the notion of a for loop as you would expect.
But the way that we indicate a range is slightly different.
So in this case, to sum everything, we'll
going to create a temporary variable called sum in order for us
to maintain this count.
>> And notice our for loop construction here.
For index in 0..<grade.count.
So this construction, 0..<grades.count is a range operation where we are
saying that we are going to create a range of integers from 0 up
to but excluding grades.count.
So this will be 0, 1, 2, 3, 4, 5, up until however many one
before grades.count.
>> So this is different than how we would typically used for loops
where you would have some index variable, set it equal to 0 at first,
and then integrate that until some value less than the count of items
in that array.
>> So there is a modification to this, actually,
which allows us to very easily set different types of ranges.
If you change this range to three dots, 0...grade.count,
this represents the range 0 to grades.count inclusive,
meaning that that number is also then included in that range.
>> But this is very handy for these exact things,
when we have to perform iterations over loop
because those indexes are zero indexed, as we have seen in other languages
as well.
Any questions on this for loop?
>> So there's implicit definition of this index variable,
whose value begins at 0, and continues at every loop iteration
to increase by 1 up until a point that is equal to grades.count,
at which point, the loop aborts.
>> Notice that in our string interpolation here,
we can actually perform some simple manipulations to those values.
So index plus 1 will actually perform a summation of that value
because index is, in this case, an integer.
And at that point, it will then be converted into a string
and interpolated into this string here, and printed out as we would expect. .
>> And the nice thing about the arrays here is
that we are also able to have fetching values and setting values
using the square bracket notation as we've seen in other languages as well.
>> All right, so from here, we now compute our sum of all of our grades.
Now sort of the next logical step would be
to do a division operation to find out the average of those grades.
But something important here is happening which
is that this sum is perhaps an integer.
But we need to perform some sort of double division.
And this is going to be extremely important when
we want to perform this operation, because what we are saying
is that we need to actually perform division on two doubles.
And again, because Swift is very strongly typed,
we must explicitly set all of the items to doubles before we actually
perform that operation.
>> So in order for us to perform double division,
it's not sufficient for just one of those items to be a double.
Both of them have to be a double in order for swift
to be sure that this is what we want to do.
So we will then explicitly typecast the sum which we've computed above
and the count of grades to doubles, and then perform that operation and store
that into this new variable, or rather this new constant called average,
which will have what type, you imagine?
Double, yeah.
So in this case, we don't have to specify it
because it can be inferred from the operation what type of data average
will be.
And Swift is generally pretty good about being able to infer the types.
>> Do you want to see this run, or can I move on?
I want to keep going.
Any questions on any of this?
Great.
>> Now we're going to start to get to the good stuff-- defining functions,
and a couple of other types that are unique to Swift that you have not
seen in other languages up until this point,
but they are present in other languages that you might find later on.
So first if you want to define a function,
you define it with the funky word function, and then the function name,
and then in parentheses, the arguments that you want that function to accept.
The arguments must also specify-- generally--
must also specify the type of data that they are, unless they can be inferred.
And we'll see that little caveat in just a little bit.
>> So in this case we have a function called printGradeCount.
We're going to accept a variable-- or rather in this case,
a constant-- called gradebook.
And it is going to be of type array of integers.
Now there's something that's really important here
that I want you to understand.
That is that by default, these arguments that are inputs to this function are
defined with an implicit let keyword, which means that I cannot modify this
gradebook variable here.
And that sort of makes sense, because you're passing data in.
And you perhaps don't want it to be changed from under you.
It is possible to explicitly mention that this is a variable by putting
the var keyword here.
But that is a gotcha that we've noticed people have done in the past
is that they assumed that it's going to be a variable when, in fact, it
is a constant.
>> All right, so here then, in this case, we are not specifying any return type.
We'll show you how to do that in just a moment.
But notice that here we have just a simple if condition.
If the gradebook is empty, which in this case
is just the property of this integer array, then we print out something.
Otherwise we do something else.
>> Pretty straightforward so far I think.
But stop me if you have any questions.
>> Now this function, average, also takes some arguments, or rather one argument,
which is the gradebook, and this time is going to return a double type.
Because it is computing the average and it's
going to actually return that computed average to the calling line.
>> In this case, we specify the return type after an arrow.
And this might feel kind of weird at first.
You've grown accustomed to setting the return
type before the name of the function.
But if you think of this in terms of mathematics,
like when you have mathematics that define a function,
you have a function with some inputs, and it produces an output.
And that's exactly what this is supposed to mimic.
And there's a couple of other languages that have similar syntax as well,
but probably none that you've seen in CS50.
But still don't be confused by it.
The arrow means what is going to be returned in this case.
OK, so how are we going to compute this average?
Well, if the gradebook is empty, well then we're
going to return 0, which maybe a reasonable way to treat this.
I don't know, let's come back to that in a little bit.
This may not actually be a reasonable way
to compute an average if we have an empty gradebook.
>> Then we'll just perform our summation.
Notice that here we actually have an alternate version of a
for loop, which allows us to iterate over every single item in an array
and place each element into its own variable.
By specifying for grade in gradebook, what we are saying
is that we're going to implicitly create a new constant called
grade that is going to represent every unique item in the gradebook
every time that the for loop iterates.
So the first time that it's run, grade will
be the first item in the gradebook.
The second time it'll be the second item, so on and so forth
until gradebook has exhausted itself of elements.
Then we will be able to sum that grade into our summation variable
and return our average as we've seen before.
OK, any questions?
Yes?
AUDIENCE: I have two questions.
Number one, hypothetically, can you run integer on this one?
Doesn't have to be a double, is that correct?
DAN AMRMENDARIZ: Can you repeat that question?
AUDIENCE: Can I do integer as the average?
DAN AMRMENDARIZ: Can you do integer as an average?
So return an integer average instead of a double?
>> AUDIENCE: Return-- you have that right now below.
DAN AMRMENDARIZ: Right here, return 0.0?
AUDIENCE: Yeah, just return 0.
So it will be either 80 or 85, but not 85.2.
>> DAN AMRMENDARIZ: So in that case, so there's a couple different ways
to answer that.
Let me answer them in order.
So if I just make this return 0, a 0 is an integer value.
And so that will cause a type error for this case
because it is expecting a double but is then returning an integer.
If I want to return an integer, I can.
I can set the return type to int, return 0 here,
and not perform double division.
But then we would be doing integer division.
And so we then wouldn't get the average that we would possibly expect.
But yes we can modify the types in that way.
>> AUDIENCE: And secondly, you have the one Double on the top.
But down below, when you do return Double Double,
that's already automatically returning Double format.
Why do you still need to define it with arrow on top with a Double?
>> DAN AMRMENDARIZ: So in case, this is part
of the-- so to repeat the question, because it's implicit from the return
types here, what type this actually is, we need to be explicit with Swift
about what we want to return out of this function
so that when it performs type checking, it can make sure
that what we have actually written down below actually conforms to that.
So it's sort of like a check with yourself sort of situation.
But there are--
>> AUDIENCE: [INAUDIBLE] arrow?
>> DAN AMRMENDARIZ: There are cases when we can specify that we can implicitly
set the return type.
But in this case, I don't think that would work.
There's some other syntax that we'll see later.
>> All right, so this source code is a little bit different
because this parses arguments from the function that we're calling.
Let me show you how it works before we actually move on
to some interesting things that's happening in Swift.
>> So in this case, if I just run this code, notice that what it is doing
is-- while, it kind of gives me a weird error.
I need to pass it a couple of integers as a command line argument.
So let's see, 150 and 80, and hit Enter to find out what it's actually doing.
It's accepting each of these values as integers.
It's inputting them into a gradebook.
And then it's performing that average calculation
and outputting that as we would expect.
>> But obviously there's something going on with this rejecting something
something as an integer.
As you might recall from when we were dealing with command line arguments
in C and other languages, the very first 0-th item in that command line argument
list is the name of the command that we actually executed.
So in this case, I'm just looping over all the command line arguments.
But I'm not doing any sort of fancy check to skip over that first one.
I'm just explicitly or I'm implicitly checking which of these types
are integers before I actually perform this computation.
>> And that's essentially what's happening here.
For every argument in the process's arguments,
I'm going to perform some check.
And in this case, I'm going to try to first convert
that argument into an integer by performing an explicit typecast,
because it is, on input, a string and not in fact an integer.
>> But this is kind of a weird syntax, if let grade equals Int(argument).
What is actually happening here is extremely
important to your using Swift.
This is using what's called an optional type.
>> So this function, Int(argument), returns not just an integer, but returns
what's called an optional integer.
And so this is sort of a type on top of a type.
You can sort of imagine it like it's returning like a package.
And when you open that package, it either
has an integer, which is the result, or it has absolutely nothing in it at all.
And this is useful as an error checking mechanism, because in this case
we can find out, was this type conversion successful?
If it was, then it is in fact going to have an integer inside.
Otherwise it's going to have some value that we'll call nil, which
is representative of no integer at all.
It's really representative of nothing.
>> And so this if construction allows us to unwrap that package,
that optional binding.
And if we are able to unwrap that package and find an integer inside,
then what we are saying here is that we will then
allow that value to be set into this constant called grade.
And this portion of the if statement, the top portion of the if statement
will run, because that unwrap was successful.
>> If it just so happens that there was an error perhaps
in this explicit type conversion from a string to an integer, maybe
it's the value ABC for example.
And that's actually not going to convert to an integer.
Then it will return nil, which is not an integer.
And this if statement well then fail.
grade will not exist because it has no integer content.
And it will run this else block instead.
Yes?
>> AUDIENCE: Nil is N-I-L?
DAN AMRMENDARIZ: nil is N-I-L, yes.
>> So this is maybe one of the hardest things about Swift,
especially when you're in the weeds on an iOS app
and you're actually trying to do some development there.
It's going to be yelling at you about optional.
It's going to be asking you for question marks and exclamation points.
But once you figure out-- if you devote some time to figuring out
what is going on with optional types, you'll save yourself a lot of headache
as you are trying to write an app in Swift.
>> It's actually a very powerful feature.
And you'll just have to take my word for it for now.
But we'll see this construction and some others like it
in some of the other source code that we'll show you in just a little bit.
>> Are there any initial questions here?
So the important takeaway is that an optional type is sort of a metatype.
It either has a value, and if it does, then it
will perhaps have that value associated with it, or it has no value whatsoever,
and it is represented by nil.
The rest of this is perhaps as you would expect.
>> So let's ramp up the difficulty yet again.
And this time, let's take a look at some other data types that actually exist.
One of them is dictionaries, which is very similar to Python dictionaries.
It's somewhat similar to a hash table in C. It is essentially a mapping of keys
where keys can be strings.
And when you look up those keys, those keys will have a value.
So it's not quite an array, but instead, more closely associated
to a hash map or a hash table.
>> Let's see how this is supposed to work before we actually
go into the source code itself.
If I just run this, nothing really happens.
It's telling me that I'm expecting some parameters of the following type.
So I'm going to provide to it some problem set names,
so pset0, maybe I got 100.
And pset1, I got a 5.
And then on the exam, I did really well and got 30.
And oops, I hit a space here.
>> When I hit Enter, you can see it performs some computation.
It says gradebook is three grades, pset1, pset0, exam.
And the gradebook has this specific average.
So again, we're working with this gradebook idea,
but we're going to continue iterating with the complexity of our function.
>> So at the onset, we're just going to create a function that
is responsible for printing the usage.
And there's this exit function which will just
forcibly quit the application.
This is not something that you will use in iOS app.
This is only, in this case, with a command line argument.
Next we'll start moving towards Xcode.
But this is specific to a command line style program in Swift.
>> Let's take a look at some of the interesting things here.
Let's see, only a couple of interesting things to mention perhaps
is that in my function of printing the number of grades,
you might recall that I had that list of items-- pset1, pset0, and exam.
You can actually quickly and easily do this
by taking the gradebook, which is a dictionary which has keys and values.
Find all of the key is through the dot keys method here,
and then use this joinWithSeparator, which will then take all of the keys
that we had typed in, pset1-- or sorry, pset0, pset1, and exam--
and concatenate them together using a comma and a space
to create one long string.
This join operation is just phenomenally useful in a variety of contexts.
And so it is this joinWithSeparator.
>> And this is one thing that's changed from Swift 1 to Swift 2.
There used to be a Python style-- if you're
familiar with Python-- a Python style join method on strings.
But that is no longer the case in Swift 2.
You want to use this if you want to concatenate an array of stuff
together with a string.
>> So perhaps then in our discussion of average before,
it makes a little bit more sense for us to set the average function
to be an optional double rather than just an explicit double.
Because we had that unusual condition where,
what if gradebook actually has no values within it?
What should the average return?
>> Well maybe in C you would have done something
like provided a sentinel value, like 0.0, or maybe a negative number,
or something just representing the fact that there was some error condition
and you perhaps do not actually have the ability to compute that average.
Well the beauty of specifying an optional type would be to do that.
And I'm now saying all these words, but this actually does not use optionals.
But we'll see that in just minutes where we can set average
to be an optional data type so that if it actually returns some data, then
we will return that data.
Otherwise we will return nil, saying that this
has no meaningful computation.
>> Let's move on to something else.
So from here, we've been looking at all these examples in the command line.
But really what you're going to be dealing with is Xcode.
And one of the nice things about Xcode is, and specifically in Swift,
is that we have this thing called a Playground.
And a Playground is not at all an iOS app.
But it allows you to experiment with Swift in a very easy way.
You can type all of your code.
It's nicely syntax highlighted here.
When you create a new file, it will ask you if you want to create a Playground.
But the nice thing about the Playground is that on the right of your window,
does it actually show you output from your code.
So if I scroll down, we can see what the output of various lines of code
actually happens to be.
>> So in this case, we're going to change directions just a little bit
and talk about something that's really important to this high level way
that Swift operates, and it is this idea of closures.
And you've probably seen this a little bit in JavaScript.
For those of you that are in CS50, closures
are very popular, very good way of doing high level things in modern languages.
But it's also kind of difficult to wrap your head around the first time.
So if you looking at this first time, that's OK.
Just look at the source code and see if you can figure it out at home.
>> So in this case, let's say that we want to create a lot of exponents
with some fixed value.
So in this case I can create a function.
I'm going to call it power of 2 whose sole purpose in life
is to take some input and double it, and return that value.
Notice that here I am accepting one type of data.
It's going to be a variable called x.
It's of type Double.
And I'm going to return a Double here.
And I'm just going to do a very, frankly, pretty
naive way of doubling this value.
And I'll show you why this is useful in just a second.
>> Notice that here we have this range again. for something in 1, dot
dot dot, 2, which means that this loop will run twice.
But this represents a dummy variable.
It means I'm not really going to be using that variable anywhere
inside of this loop.
I just want this line of code to run twice,
without needing to know the value of that range.
>> So in this case I'm running result times x twice, which essentially
means that I'm squaring this value.
And this happens to work as we would expect.
Power of 2, passing a value of 2.0 gives us an output of 4.
3.2 works for 10.24.
>> Now we can do a similar thing for power of 3.
But now change only the range.
For dummy variable in 1 through 3, multiply 3 times,
and do the same thing.
>> So this might feel a little contrived.
But there's an important thing here which
is that looking at these two functions, there's
only one thing that's different, which is this value in the range.
Everything else about these two functions, power of 3 and power of 2,
are, in fact, identical because they work in the same way.
>> So at this point, a little alarm bell should be going off.
Hopefully what you're saying, you know, this feels a little bit
like duplication of effort.
Perhaps there's a way that I would be able to encapsulate all of this
and provide a function or create a function that
does exactly what I want without needing to type it out explicitly.
And this is what the power of a closure allows us to do.
So let's take a look at this.
And I'll spend a couple minutes on this, because this
is pretty important for Swift.
We see this all the time.
We're going to define a function.
It's going to be called powerOf.
It's going to accept a parameter called y of type Int.
But take a look at the return type.
The return type is, in parentheses, Double arrow Double.
Which means that this function, this function powerOf,
is returning a function.
That is accepting a Double and returning a Double.
So that might sound kind of crazy, but let's scroll down a little bit
and look to see what happens.
We're inside of this function powerOf.
We're creating a new function called exponentiator,
but it doesn't matter what it is.
>> Notice that this has an input value of x.
And it is taking in a Double and returning a Double.
And this is the same code that we saw above, except that the value of 2
or the value of 3, that upper bound in that range,
has been replaced with this value of y, which
was the initial parameter of our powerOf function.
And at this point, we return exponentiator.
We're returning the function.
>> It's kind of like a little mind blowing.
But let's imagine what happens when I call this function powerOf
and pass into it some value like 2.
What this means is that I now have the value
2 for y, which means that this value y in this exponentiator function
will be that value 2.
But I'm returning this exponentiator function.
>> So notice what Swift says I have created in this case.
let square is a definition, it's a function that accepts a Double
and returns a Double.
I have created a function that squares something
using this mechanism right here.
And really what's happening is that it is returning this function
exponentiator, but this value y is wrapped inside of it.
And so now every time I use this variable or this constant called
square, it it's going to behave as a function.
And so I can then call that variable like I would call a function,
and pass into it a number, like in this case 3.
And I will then square this value.
So 3 squared will then become 9, as we can see here.
>> Really crazy, but this now allows me the opportunity
to create other powerOf functions.
Like I can say, OK, well now I want to create a new function, powerOf(3),
and store that into a constant called cube.
And now cube is going to be a separate function that will then
take some value as input and cube that value as we can see in the bottom line
here.
cube of 2 is going to result in 8.
>> Hopefully pretty neat stuff.
You've never seen this before.
I encourage you to look into closures and investigate this a little bit more.
It's really powerful stuff we see a lot in JavaScript and some other languages.
It's really vital to understanding APIs as well
that we'll get to in just a second.
Yes?
>> AUDIENCE: When you do powerOf(2), parenthesis, and then
another parenthesis, another input-- you're basically replacing the square.
DAN AMRMENDARIZ: So look at the very last line here.
It is actually totally possible to do that chaining as you suggested.
So powerOf(5) means that we're going to have an exponentiator of 5 up here.
So this is essentially going to be the same thing as 4 to the fifth power,
because we've created an exponentiating function to the fifth power,
and we're passing into that function the value 4.
And we get that value that we expect, 1024.
AUDIENCE: And it's not a name, so it makes it easier
to read, the square whatever.
>> DAN AMRMENDARIZ: Right, exactly.
So before I just put it into a constant here so
that it made it easy to use that name.
Yes?
>> AUDIENCE: In this context powerOf, it's part
of the programming language as opposed to the way you
think of powerOf in [INAUDIBLE]?
DAN AMRMENDARIZ: So in this case, powerOf
is simply the name of the function that I defined up here.
So it's not inherent to the language itself,
but instead, it's just a function that has
that name because I give it that name.
Any other questions?
All right.
>> Now this is great.
But you're not going to see a lot of closure functions that
are like this where you define, inside of one function, another function.
And you can do it.
But it's kind of not really necessary, right?
Like why do I define this function called exponentiator
and then immediately return it.
Why can't I just immediately return this function?
>> And in fact, this is precisely the idea behind a concept called
anonymous functions, where anonymous functions do not actually
have a name because they don't need to have one.
And so in this case, in 7B, we can find precisely that.
It's all the same code, does exactly the same thing,
but now we've changed it slightly so that this powerOf function immediately
returns a function.
Notice that after return, there's an open curly bracket.
It's expecting this input Double.
It's expecting that output Double.
And then the in keyword separates the code itself.
So this is an anonymous function.
It doesn't actually have a name, whereas before it was called exponentiator.
But as we saw, just really didn't refer to exponentiator
outside of that function.
So it didn't matter.
So this anonymous function is so-called because it is nameless,
but it's still being used in the context of this code.
>> The next couple ones I'm going to continue hopefully
blowing your mind a little bit.
We can simplify this even more.
Because as was astutely pointed out earlier,
perhaps we actually know, by inferring from this code, what
the output of this code is going to be.
And in fact, in this anonymous function, we can in fact infer the types of data.
>> So in this one, we no longer need to explicitly define
the type of data that's being input and output from this function
for a couple of reasons.
One is that we've defined, up at the prototype of the enclosing function,
what type of data this anonymous function should input and output.
And from the other, we can infer from the code
down here that we are accepting input that is of type Double
and returning a Double.
>> Notice that here we have not explicitly defined the names of the arguments
that this function is accepting.
And so we see we can refer to those parameters using $0, $1,
so on and so forth, depending on the number of that parameter used
in this function.
>> This is something that you are going to see a lot is this open curly bracket
definition followed by a $0, and then some operation,
and then a closed curly bracket.
That is an anonymous function that performs this operation.
It has this parameter where it's type is inferred.
That first parameter is $0.
And some operation is happening on that $0.
>> AUDIENCE: So the dollar sign means parameter basically,
and 0 means the first one?
DAN ARMENDARIZ: That's correct.
So the dollar sign basically means parameter, and 0 means the first one.
But it works specifically in this case where I have not named
the arguments in my anonymous function.
>> AUDIENCE: Does Perl or something have this dollar sign, dollar 0 in there?
DAN ARMENDARIZ: Does which, I'm sorry?
AUDIENCE: Does Perl have this dollar 0, dollar 1--
DAN ARMENDARIZ: I'm not too familiar with Perl,
but PHP what defines variables based on dollar signs.
And there may be some languages that have features like this.
In fact, Swift borrows a lot of features like this
from a lot of other languages.
We see hints of Python in it.
This definition of type seems to come from OCaml.
And we have just a whole bunch of stuff from lots of different languages.
That's one of the nice things about Swift
is that it takes a lot of the best ideas from a bunch of languages
and shoehorns them all together into one super language.
In fact, if you allow me to continue blowing your mind,
so we've been doing all of this.
We can perhaps simplify this a little bit by realizing that, of course,
Swift has an exponentiating function built in.
If I import Darwin, which is just the library that
features this function called pow, now I can simplify my power of function
to be the following.
It is going to be returning this anonymous function.
>> But look at how simple this is now.
This is an anonymous function that is accepting some type of data,
and it is going to be one argument specifically,
referenced at $0 that is of type Double.
It is going to return a type Double.
But the return statement is now implicit.
>> And it is this exact style that is very, very prevalent in Swift,
all over the place.
We're going to see this all the time in Swift.
So I'm showing all of this to you because of this syntax.
This is very common to see, which means it
is an anonymous function that is performing
some operation on these arguments.
And there is an implicit return.
So it is absolutely the same thing for us to say this, right here.
>> Because this curly bracket is a function,
we're perform this operation on the first argument.
We're going to return that.
But this outer return is returning that whole function,
that whole anonymous function that we've just created.
Any other questions?
All right, I don't know if you guys are ready for this,
but we can go even crazier with Swift.
You ready?
OK, this is great.
>> Now we actually have the ability to, in Swift, because of how modular
and how protocol based it is, to define our own freaking operators.
Like in this case, we had no operator for exponentiation-- well,
for performing powers of something.
But I can, in Swift, define a new operator that does precisely that.
So in this case there's a bunch of syntax here.
And I'll allow you to look at it at home when you look at this.
But we are defining this infix operator, **, which will then allow us,
by defining what that function ** actually
does, to accept a left hand side and a right hand side,
and then to return the exponent of that left hand side to the right hand side.
>> And so now all of a sudden I have created a new numerator.
So 2**3 means 2 to the third power.
[MIND BLOWING SOUND] This by itself should make you be like,
OK, screw C. I'm going Swift all the way.
This is great.
This is pretty fantastic.
>> Though this is a great example.
But I have never once outside of this example actually
defined my own operator.
But still, it shows a lot of the power of Swift
and why this is actually really very cool.
OK, yes?
AUDIENCE: If you're defining your own operator,
how do you know you don't accidentally try and create an operator that's
in somewhere in C, like hidden somewhere in Swift,
like an obscure one that you may not have seen before.
>> DAN ARMENDARIZ: So if you're trying to define your own operators,
there is the risk of defining one over an existing operator.
That goes into a level of detail that I don't think we have time to go over.
But that is a risk.
And that is in fact the very reason why I didn't use the caret symbol, which
when we're typing out power, we usually use 4 little caret 5 or something
like that, just when we're Gchatting buddies or whatever.
But in that case, that actually would have caused a collision.
And so I avoided it just because I happened to know in this case
that that would cause that collision.
>> All right.
Now unfortunately, for the last seven minutes,
I have to keep blowing your minds a little bit.
So allow me to show you some other things as well.
>> We've shown you this idea of having these anonymous functions,
these closures that allow you to kind of pass functions around.
You can return them.
You can manipulate them.
You can do all sorts of crazy stuff.
>> But one other thing that happens to be useful
is the ability to, as opposed to returning those functions
in a function, to pass a function as a parameter to another function.
You might be thinking well why on Earth would I want to do something like that?
>> Well, let's say that I want to take this operator that I
worked so hard to create and apply it to a bunch of different numbers
in an array.
So in this case I have an array of integers-- 1, 4, 7, 2, 5, 10, 56.
And I want to double them all.
The way that we would typically do it is to just write
a simple for loop that iterates over all of them
and perform some sort of square operation over them,
inputting those new values into a new variable, or rather, a new array here.
And the value of the output of result is then all of those arrays,
or rather all of those elements now squared.
>> And we could do the same thing for cubing it,
but a little alarm bell should be going off
saying that maybe there's some way that we would
be able to simplify this a little bit.
And in fact there is.
What if we could create a function that allows us
to accept, as a predator, a function?
So in this case, take a look at these arguments.
We're going to accept a list of doubles.
And then we're going to accept a function
in a variable called f that is going to take a Double and return a Double.
And the whole output of this entire function
called mapper is going to return an array called double.
>> What this would then allow me to do is to iterate over that list
and do the same thing, but now apply that function on each
of the individual values in that list.
So I don't really know what f is.
It doesn't matter to me.
But so long as it takes in a Double, performs some operation on it,
and then returns a Double, I would then be
able to map that function across every single element in the list.
>> And this type of programming is called higher order functions,
where we're passing functions around as parameters
and doing things with functions.
It's sort of like taking all of these ideas that we've learned in CS50
and taking them sort of to the next level.
And this is all CS51 style stuff.
And so we'll go in depth more in classes like that.
>> But this is also important here because we
see a lot of functions that are used in Swift
that essentially does this, where we have
some numbers, some array of numbers.
We're going to pass that array into our mapper.
And we're also going to pass some function, which
we've already defined up here.
It's going to be square.
And we're going to then square all of those numbers
and store that into this result here.
>> So this case we've defined our own function called mapper.
But this exact thing is, in fact, built into Swift.
There are a variety of functions called map.
There's a map function, there's a reduce function,
and there's a filter function, which essentially apply functions
to every single element in a list to modify them in some way.
>> AUDIENCE: So since you are transforming the data into another format
through a function--
DAN ARMENDARIZ: Right.
Yeah, so the function that we're accepting
is transforming the data in some way.
In this case, we were either squaring it, or we were cubing it,
or really, we could perform no operation on it at all.
>> But let me show you then how this is going to look in practice.
And again, I'm running a bit of time. so I'm not
going to be able to go over all of the source code here in detail.
But I encourage you to do that.
We'll post it as soon as possible after this talk.
>> But if you take a look at this, assume that we have a list of numbers,
an array of numbers in this variable called numbers.
Then we want to perform this filter operation on those numbers.
So filter is a higher order function that
accepts an array and also a function.
And on every element in that array, it performs that function.
>> If that function returns true, it keeps that item.
If that function returns false, it throws away that item.
And then it returns a list that is then made up all
of those items that have been filtered.
>> So in another words, this is the same idea, the gradebook.
We might have a variety of grades into this value called numbers.
Could be 100, and 70, and 40, so on and so forth.
What this filter does is notice that this is that syntactic sugar
for an anonymous function.
This is an anonymous function saying that the parameter that I'm accepting
is going to be, if it is greater than 70,
then this will return true, meaning that that item will be kept in this filter.
So let's be a little bit more concrete about this.
If I have this array of numbers and it consists of 100, 70, and 40,
I perform this filter operation on each one of those.
So that first one is this value of 100.
100 greater than or equal to 70 is true, which
means that 100 is kept in this new copy of this array.
70 also passes.
But 40 does not.
So what is returned in passingCount is the array of elements 100 and 70--
100, comma, 70.
Those were the only two items that were kept.
And so the reason I quickly went through a lot of these kind of high order
things are because this is that common thing that you will see in Swift pretty
frequently, is performing some operation using this anonymous function syntax.
>> There's some cool stuff.
Switches are really powerful in Swift, I mean just like crazy, crazy powerful.
You can use switch, and you can actually apply them
to ranges, which is kind of crazy, and do fancy stuff like that.
>> But in the last few minutes, I want to skip ahead quite far
and show you a specific example of how we can create in iOS app using Swift.
So when you're doing this, you'll have to take
a look at-- on Apple's documentation, they
have a lot of really good tutorials for creating your first application.
And I encourage you to do that because they take you
through all the steps of what exactly to click on to create an iOS application.
>> But here we have this iOS app.
And it's a pretty simple app really.
If I run this, let me show you what it looks like.
All it essentially does is it pulls from the internet a JSON file
that I have stored on a server.
And that JSON file defines images that allow
me to then cycle through, on my app, images from my web server.
>> So I have here getNextImage.
It loads an image from the internet, and then displays it on the screen.
>> So it's pretty simple.
But the goal here is to show you how we can combine things
from the latter few weeks of CS50 into an actual iOS application.
In other words, perhaps one of the things that you will want to do
is to have an iOS application that can pull data from the internet
and show the user some information.
That is entirely the point of this source code here.
>> So there's a lot to be said about how to do actual iOS development.
There is a lot of crazy syntax that we haven't seen quite yet
like a class, what a class actually is.
We can largely ignore that for the time being.
>> But notice that we have contained within this a variety of things
that we've already seen like functions that have specific names.
And when we give those functions the correct names
that are expected by iOS, in fact this feels a little bit magical.
But when you create an iOS application, there
are specific function names that are called by the phone itself
as the application is loading to try to create the process that actually
runs your application.
So again, there's a lot of things that I have to gloss over here in order for us
to talk about this specifically.
But I encourage you to look at perhaps the other iOS seminar, but also some
of the tutorials online which do a much better job of describing
the specific information.
>> But we can see a couple of things that are interesting from the code here.
Notice that we have if statements.
By the way, one important thing about if statements
is that the parentheses around the Boolean expression are optional.
But the curly braces are not optional, no matter how few or many lines of code
you have in an if statement.
You cannot have an if statements without curly braces in Swift.
>> And this is, well, sort of silly.
But there's historical reasons for that.
It's supposed to save you from yourself.
Like this for example, you cannot eliminate the curly braces around that
if statement.
Those are in fact required.
So I encourage you to take a look at this.
But there's one more construct that I want
to show you about Swift that is new to Swift 2.0 compared
to older versions of Swift, which is the following.
Let's see where did I put it here?
>> So in this function called fetchJSON, this function
is responsible for pulling that JSON file from a URL, which just so happens
to be running on my CS50 IDE.
I just started Apache, put my JSON file there,
and I'm able to then pull that data from the internet using
this function and this URL, which is provided by the phone.
It's provided by a library that you use when
you're doing some iOS app development.
>> Notice here that there is this unusual syntactical construct called guard.
And really all this is in Swift is a way of verifying
that some things have been met before you
proceed with the rest of the function.
So I could have, using this optional type,
I could have found the URL by running this NSURL function
and storing that into a URL constant, and then checking
to see if URL was nil, because it was going to return an optional type.
And if it was nil, then I would print out an error and then return.
>> But instead, what guard lets us do is that very thing,
but ensure that it is actually the case that url
has been properly set by NSURL.
And if it is, then it skips over this, and it
will allow you to proceed with url having been properly defined.
But if it is the case that url is not properly defined,
if this function returns an error or some other unexpected thing
actually occurs, this guard construct allows us to then output that error
and return immediately.
Yes?
>> AUDIENCE: So it's kind of like an if then else?
DAN ARMENDARIZ: It's kind of like an if then else, yes,
except that this url is then defined for everything below this.
If it passes this guard, then it will actually be filled with data
and usable in the remaining source code in your function.
So I suspect that you're going to start to see this guard as well.
And be mindful of that.
>> So just looking at a couple of other things, this right here is what,
do you think, just based on what we were talking about before?
>> AUDIENCE: Think it'll run in the list?
>> DAN ARMENDARIZ: So that's close.
This is a function that we are defining.
And we are inputting that function as an argument to this function here.
>> AUDIENCE: [INAUDIBLE] if not nil.
So it's in the list, right?
>> DAN ARMENDARIZ: If error is not nil, so that is-- so I have to scroll.
Well, let's see, I can't really scroll to the right here.
error is an argument that is being passed to this anonymous function.
This is an anonymous function.
It has no name.
But we are accepting these three arguments, data, response, and error.
And it is going to return void, so it's not going to return anything.
And this is the contents of that function.
And then we have access inside that function to each of these arguments.
>> So it's a whirlwind tour of the language.
But I hope with this, hopefully as you take
a look at some of the tutorials specific to iOS development with Swift,
especially if you go to Apple's developer web page--
they have a lot of really good tutorials to get you started.
But hopefully just this hour of talking about the syntax itself has given
you enough to get started with that.
>> We will post all of this source code on the seminar website
as soon as possible, and also the slides so you have a reference for all those.
But good luck with your projects.
And thank you all very much for coming.
>> [APPLAUSE]