WEBVTT

00:00.000 --> 00:15.600
Hello everyone, so today I'm going to talk to you about swifts and this is aimed at people

00:15.600 --> 00:20.240
who aren't really seen swift before, so I hope for the supplies to some of you at least.

00:20.240 --> 00:24.480
I'm going to explain to you why swift is the best language for building modern applications

00:24.480 --> 00:25.480
for back-and-services.

00:26.440 --> 00:30.760
So I'm Tim, as mentioned, I run a company called Birkenham to be the service host of

00:30.760 --> 00:36.360
Consultancy Helping Clients, deploy a main team, applications and services around the world,

00:36.360 --> 00:41.240
but I'm better known as being one-half of the vapor-court team, and vapor is a open source

00:41.240 --> 00:44.680
frame up for building APIs, web apps, back-ends in Swift.

00:45.720 --> 00:50.120
I see on a couple of workgroups of Swift, so the website workgroup, which is responsible for Swift.org,

00:50.600 --> 00:53.560
and the server workgroup, which I'll talk about later on in the talk.

00:54.520 --> 00:57.960
And as mentioned, I will come out as a service host of Swift, which is an annual conference

00:57.960 --> 01:02.840
based on service service, on Swift and the server, so you could say I'm a little bit invested in it.

01:03.960 --> 01:07.000
If you have questions, I'll be hanging around, but feel free to reach out to me.

01:07.000 --> 01:08.760
I'm 0x10, pretty much everywhere.

01:10.360 --> 01:17.080
So let's get into it, so Swift. Swift was introduced just over 10 years ago now, but Apple's

01:17.080 --> 01:22.600
developer conference. Back then, as a replacement for Objective C, as the language of choice

01:22.600 --> 01:29.640
for building applications on Apple platforms. And when it was first introduced, it had four key pillars.

01:30.360 --> 01:37.560
It should be fast, modern, safe, and interactive. And a little bit of kind of the unofficial fifth one,

01:38.120 --> 01:41.960
which was it must be one language to rule them all. It should be a language that should be

01:41.960 --> 01:46.920
able to target the entire stack with your building front-hand applications, or write it in embedded software.

01:47.800 --> 01:52.360
And I want to go through each of those five pillars to kind of explain why Swift is a great language,

01:52.440 --> 01:54.760
both in general and specifically for the server.

01:56.760 --> 02:02.120
So Swift has a ethos of progressive disclosure, so the easy stuff should be easy to do,

02:02.120 --> 02:06.040
and as you adopt more stuff, you can adopt more stuff and make it more complex.

02:07.240 --> 02:09.960
So if I want to define a function in Swift, use the honk key word,

02:09.960 --> 02:13.960
it looks pretty similar to most other languages, you may have seen it, and I can just print it.

02:14.920 --> 02:19.240
If I want to write this as an application, then I can just wrap this in my entry point, use the

02:19.240 --> 02:24.760
app main attribute with the main function, and this will generate a executable for me to build

02:24.760 --> 02:30.200
and run. Well actually because this is Swift, you can also do scripting and just have a print statement,

02:30.200 --> 02:36.120
and Swift will just print it out like you do, because it is really varied in how you can

02:36.120 --> 02:43.000
approach it. But let's get back to our function. If I want to return something and say print a message,

02:43.400 --> 02:53.400
I can return a string using the arrow key word, arrow syntax, and then if I want to use this API,

02:57.000 --> 03:01.480
I can call it with let message equals same message, hello Swift, hello world.

03:02.200 --> 03:06.520
And the idea is that Swift should be relatively easy to read as you scan code,

03:06.520 --> 03:12.760
almost like you're reading some kind of text, and makes it easy to see what's going on with your

03:12.760 --> 03:17.320
code and reason about your code. And that's one of the key talents of Swift is making it easy to understand.

03:19.400 --> 03:24.920
Let's say I want to make this a little bit more complex and have two variables, so I can say hello to

03:24.920 --> 03:31.800
me. Well let's just format this a little bit. For API calls like isn't great because I'm saying

03:31.800 --> 03:37.640
message to Tim, message is a bit redundant there because I'm going to pass an message. And inside the

03:37.640 --> 03:41.640
function I'm using two as a variable name, and that's not great either because it doesn't really

03:41.640 --> 03:47.320
make sense in the context of that function. Well Swift allows you to have different internal

03:47.320 --> 03:52.280
external variable names for your function parameters, so you can see the cool site down below is

03:52.280 --> 03:57.800
say hello to Tim, reads really nicely, easy to see when you're reading it, and internally I can call

03:57.800 --> 04:01.640
my other thing name, so I just prefer to name it, it makes much more sense.

04:04.040 --> 04:08.280
The clearing variables is pretty easy, I can just do let result fully equals true. That's

04:08.280 --> 04:14.920
declaring a boolean, I result with the value cube. Swift also has type inference, it's true,

04:14.920 --> 04:19.080
it's obviously a boolean, so we don't need a ball, let's get rid of that. You'll also notice there's

04:19.080 --> 04:24.200
no semi-colons because those are redundant as well, it really starts to clean up your code.

04:27.080 --> 04:33.320
I come on to kind of Swift safety later on, but generally be aimed for Swift to be for things to

04:33.320 --> 04:38.920
be immutable by default and only opt-in to mutability if you want them, so the lucky word means

04:38.920 --> 04:44.840
this variable is mutable, so if I try and assign to it I'm going to get a compiler error because

04:44.840 --> 04:49.560
it's immutable, so I just need to change it to a bar, and this is similar to like cotton and

04:49.560 --> 04:55.960
other languages as well. If statements look pretty similar to most other things, apart from there's

04:55.960 --> 05:01.960
no brackets, unless you need them, and then for loops also look pretty readable as well,

05:02.520 --> 05:07.080
there's no whole i equals 0, i less than something dot length i plus plus.

05:09.400 --> 05:13.400
We have a nice readable syntax of four name and names, and we can just loop through them,

05:13.400 --> 05:15.160
but you can also get the index as well if you need.

05:19.400 --> 05:24.040
So Swift is also a modern language, it's one of the kind of newer generations of languages that's

05:24.040 --> 05:29.960
coming in of the last kind of decade or so, and it's definitely learnt and taken and borrowed

05:30.040 --> 05:34.680
features and tools and power dynamics from other languages.

05:37.960 --> 05:43.720
More than is optional, so if you're lucky in C you're passing a point to round,

05:43.720 --> 05:49.960
if you know if it's no, not go quickly. In Swift, if I declare a string, this cannot be no.

05:49.960 --> 05:53.400
The compiler one for today is not known wherever you use it and wherever you pass it around.

05:54.760 --> 05:58.520
For what's it to be? No, we want it to be optional, I can mark this as optional with the

05:58.520 --> 06:04.600
question mark on the type, and then this can be noble. But what it means is that wherever I use that,

06:04.600 --> 06:11.080
I have to account for the fact where it can be no. So if I try and add a number to my optional

06:11.080 --> 06:16.200
int, this won't work because what you do in the case where it's no. Maybe for an integer,

06:16.200 --> 06:19.640
you might want to just assume it's 0, but maybe you want to assume it's minus one.

06:20.440 --> 06:24.360
So Swift makes you explicitly opt into these features, which provides really clear,

06:24.360 --> 06:31.160
concise code of what your code is doing. There are various ways of unwraping this in handling it,

06:31.160 --> 06:37.000
you can use guards, you can use iflets, you can use optional training, but if you deal with it,

06:37.000 --> 06:43.320
then the compiler is happy. Swift also has first class generic built-in from a language,

06:43.320 --> 06:47.160
so if I want to define a collection of ints, you can define it like so.

06:49.080 --> 06:52.360
And if I want to then define a collection of strings or collection of doubles or collection of

06:52.360 --> 06:55.640
floats, you don't want to be copying and pasting code and having the same code

06:55.640 --> 07:00.920
you've prepared throughout your purpose. So we can use generics and just have a generic collection

07:02.120 --> 07:06.600
with our items and interesting enough array is also generic under the hood as well.

07:08.440 --> 07:11.400
So it's very easy to reason about and very clear what your code is doing.

07:13.480 --> 07:19.560
Let's talk about strings. So strings in Swift look pretty much like any other string in most other

07:19.560 --> 07:26.520
languages. Define the string is the string, strings are UTF8 strings under the hood,

07:26.520 --> 07:31.720
natively, which is really great for the server world by your passing round strings H to P and things

07:31.720 --> 07:38.120
it UTF8 by default normally. But Swift has really powerful string processing.

07:39.560 --> 07:45.880
So what you do in this case, what's the result of count of that string there? Well for humans,

07:45.880 --> 07:50.600
we read that and go, well that's two characters there. But Unico is a habit of messing up pretty

07:50.600 --> 07:57.560
much everything. Thankfully, Swift gets this right and will print the count as two. But most of

07:57.560 --> 08:03.240
the languages actually really struggle with this. Do you have a script you get for, see you get eight,

08:04.840 --> 08:10.200
drive you get for as well. Because Unico is actually a lot more complicated than just regular

08:10.200 --> 08:15.320
kind of asky stuff. And Swift is one of the very few languages that gets 100 Unicoed and

08:15.400 --> 08:21.160
emojis right. And she's really important the back end because we want to be able to allow

08:21.160 --> 08:25.720
our users to have emojis in their titles for their peers and store those in the database and

08:25.720 --> 08:35.400
store those natively. So these gents add people coming in with their emojis. Swift has a

08:35.400 --> 08:41.320
concurrency model built into the language, which is really really powerful. So if I want to

08:41.320 --> 08:47.400
define a concurrency function that is asynchronous, I have to mark that function as async. You cannot

08:47.400 --> 08:53.400
do any asyncness work inside that without it. And then if I want to call another asyncness API,

08:53.400 --> 09:02.280
I mark that with the await keyword. Is my mouse going to work? Okay, but you can see up there

09:02.280 --> 09:07.240
that I use await and then call the async function. So when you're reading your code, it makes it

09:07.240 --> 09:13.480
very clear as to where the potential suspension points of your functions are. This Swift also

09:13.480 --> 09:19.960
goes slightly further with a think called structure concurrency. So if I define a task that I can

09:19.960 --> 09:26.120
get in capture, but there's some asynchronous work. If I want to cancel that on some condition,

09:26.120 --> 09:30.680
that cancellation will be propagated down to all child tasks automatically for you and cancel

09:30.680 --> 09:36.680
all subsequent tasks and do all the cleanup for you as well. So it is a very powerful feature.

09:42.120 --> 09:45.800
And there are hundreds of other language features that I really don't have time to get into,

09:45.800 --> 09:51.400
but makes Swift a really great fantastic model language, also make it a really nice language

09:51.400 --> 09:58.600
to use on the backend. So the safety and Swift is probably one of my favorite features around

09:58.600 --> 10:04.360
why it makes such a great language for the backend. So it has some relatively unique features

10:04.360 --> 10:09.480
that make it a nice safe language to use. As I mentioned, we have optionals, which ensure that

10:09.480 --> 10:15.800
things can only be in there if you want them to be. And you have to explicitly handle the cases

10:15.800 --> 10:20.920
whether or not they'll. And this means that non-pointed exceptions in Swift do not exist. We don't

10:20.920 --> 10:27.560
have non-pointed exceptions at all. They're just not the things in Swift. Swift is also got

10:27.560 --> 10:31.480
late memory checking, so it's a memory safe language. So other languages, which I'm not going to

10:31.480 --> 10:37.560
name, we'll just consume buffer until you do that stop. And if you forget that luck,

10:38.520 --> 10:43.000
where Swift has got really great memory balance checking, to make sure that standard kind of

10:43.000 --> 10:50.040
classic exploits like memory overflows and use afterfrees are possible. In Swift, you have

10:50.040 --> 10:54.280
explicit air handling. So like I mentioned with AC into weights, if you have a function that's

10:54.280 --> 10:58.280
going to do something that could potentially throw, you have to mark that cool flight with a

10:58.280 --> 11:03.480
tricy word. And your function has to either handle that with a due catch or be marked as throws

11:03.480 --> 11:08.600
as well. So when you're reading code, it makes it really easy to see where the potential points

11:08.600 --> 11:12.520
in your code that could throw errors. Which having done some correct script recently and having

11:12.520 --> 11:16.840
to look through a massive function trying to work out which these lines is throwing out are

11:16.920 --> 11:24.280
is a really nice little feature. There's been a real shift in the kind of industry over the

11:24.280 --> 11:28.920
last few years from moving towards pipe safe languages and Swift is no exception. Swift is type

11:28.920 --> 11:34.440
safe, aesthetically typed and strongly typed. Which means that if you're passing around something

11:34.440 --> 11:38.440
as a type, it can only be that type and nothing else. And if you want to cast it, you have to

11:38.440 --> 11:45.800
explicitly cast it and handle the cases where the cast fails. And the last one is something that's

11:45.880 --> 11:50.760
pretty unique to Swift, which is the day-to-day safety. So Swift has a concept of

11:50.760 --> 11:56.760
sendable, which allows you to only annotate types as being safe to pass across concurrent boundaries.

11:57.720 --> 12:01.400
In essence, you can kind of think of it as thread safe. I'm sure the Swift team at the back

12:01.400 --> 12:08.760
going, no, it's not, but it kind of is. That's the thumbs up, excellent. But what this means is that

12:08.760 --> 12:15.080
essentially with sendable turned on a concurrency checking turned on, databases are not possible.

12:15.080 --> 12:19.480
You'll get compile errors in your code if you're trying to do unsafe stuff. So we have all

12:19.480 --> 12:24.040
of these features in Swift that mean that you're going to get told when you're compiling your code

12:24.040 --> 12:27.880
that you have problems rather than when it's through a clock in the morning, you get page because

12:27.880 --> 12:35.240
your services gone down, which is a really nice feature. Swift is also very important. Is it quick?

12:37.160 --> 12:41.000
Yes, it's a compiled native language, which kind of gives it a bit of a head start over

12:41.000 --> 12:48.520
some of the other interpreted languages. This is a slide from Apple's developer conference this

12:48.520 --> 12:52.440
year. They used Swift on the server and handle millions of requests per second. So it is in

12:52.440 --> 12:59.640
use in production and use well. One of the kind of unique selling points of Swift is the user's

12:59.640 --> 13:09.160
reference counting. So some of the languages are garbage collected, which is quite nice sometimes.

13:09.960 --> 13:15.800
This is that whenever the garbage collector runs, your performance kind of just tanks at some point

13:15.800 --> 13:19.800
during your execution and you can't control it, you have no idea how bad it's going to affect

13:19.800 --> 13:24.520
it or when it's going to affect it. With automatic reference counting, you get a really

13:24.520 --> 13:29.480
nice deterministic performance. So you can predict how well your services can perform without

13:29.480 --> 13:35.320
having to rob about as garbage collector. And this also makes Swift extremely memory efficient as

13:36.120 --> 13:41.000
well. This is a client project I've got running in Fargate on AWS using the smallest

13:41.000 --> 13:47.080
instance that you can provision. And I'm yet to break 2% of memory utilization. So please AWS

13:47.080 --> 13:52.680
gives some small instances. But it's extremely memory efficient. And I work with clients

13:52.680 --> 13:58.920
moving from other languages to Swift, which I've saved, 75, 80% of the cloud server bills,

13:58.920 --> 14:00.920
purely because the amount of memory they don't need anymore.

14:01.640 --> 14:07.720
And this also applies to things like lambda where you're paying per megabyte per

14:07.720 --> 14:13.800
milliseconds. Swift has got exceptionally fast code start times, less than 100 milliseconds compared

14:13.800 --> 14:17.240
to some of the languages where you might be more than seconds. So we're talking orders of

14:17.240 --> 14:22.760
magnitude better. So it's more performance, it saves you money and it's nicer to use as well.

14:22.760 --> 14:32.840
Just to be clear about it. So as we've seen this morning as well continues to see, Swift is

14:32.840 --> 14:37.800
actually not just an application language anymore. You can use it for scripting and it's really

14:37.800 --> 14:42.200
nice for scripting, how they type safe language without having to resort to bash. You can do embedded

14:42.200 --> 14:46.200
development, you can do system programming, you can do server development. There's almost

14:46.200 --> 14:50.440
we'll see in a bit as well as well as application development. So it is now being used throughout

14:50.760 --> 14:58.200
the entire stack. In terms of platforms, as we've heard, supports macOS, it supports several

14:58.200 --> 15:04.760
flavors of Linux. So there's Centos, Fudore, Debbie and you've been to Amazon Linux and probably some

15:04.760 --> 15:11.880
others I've forgotten as well as Windows. But because it supports Linux, you can run it in Docker,

15:11.880 --> 15:16.360
which means it's just another Kubernetes pod. So there's no kind of hard things when having to do

15:16.360 --> 15:24.360
deployments, it's just another pod or container that you ship. One last thing I do on a

15:24.360 --> 15:30.360
start out is its language interrupt. So from the very beginning Swift have to have first class

15:30.360 --> 15:37.160
language interrupt with C and object to C, otherwise it wouldn't take off at all. This Swift also

15:37.160 --> 15:43.320
has now first class support for C++ where you can natively call Swift types from C++ and call

15:43.400 --> 15:49.800
Swift C++ types from Swift. And just last year at the end of last year, there was this Swift

15:49.800 --> 15:54.360
Java prototype release or repository list, which allows you to interrupt with Java directly,

15:55.080 --> 16:01.560
which allows you to slow your migrates, your services over. So we'll have a quick look at this

16:01.560 --> 16:09.480
server ecosystem. As I mentioned, I am on a recording of paper, it's a well established,

16:09.480 --> 16:15.400
very big, very large project that's been going for eight, nine years now, in nine years.

16:18.360 --> 16:21.480
It runs real applications. It has pretty much everything you want to do on a server.

16:22.280 --> 16:25.880
There's also a hummingbird, which is much newer, and probably has less tech deck at the moment.

16:27.320 --> 16:31.880
And there's Swift package index as well. So if you're looking for packages in Swift to do something,

16:31.880 --> 16:35.400
there's thousands of packages on Swift package index. There's probably something there for you.

16:36.200 --> 16:40.200
These days, when working with clients, it's very rare that I actually have to write third-party

16:40.200 --> 16:44.600
APIs or SDKs to talk to APIs and stuff like that, because they're really exist.

16:47.160 --> 16:50.440
As I mentioned, I'm part of the Swift server work group, and we're responsible for

16:51.080 --> 16:54.360
abocating for Swift and the server, making shorts as good as it can be.

16:55.480 --> 16:58.520
Whether that's working with the language team to ensure that we have language features,

16:59.240 --> 17:02.200
the compiler team to make sure it builds and the right platforms,

17:02.840 --> 17:06.360
or whether it's fostering an ecosystem and building packages or tooling.

17:09.000 --> 17:14.600
One of the things we have is that incubation list, or incubator packages, which is very similar to

17:14.600 --> 17:19.000
CNCF's process, or we have a list of packages that have been through an incubation process.

17:19.720 --> 17:23.800
So you start with sandbox, you're incubating, you're graduated. If you're looking for

17:23.800 --> 17:30.120
database drivers or security libraries or web servers or metric stuff, have a look at the

17:30.120 --> 17:34.120
stuff on there, the things in there have been battle tested, I'll well maintain, and I'll

17:34.120 --> 17:40.280
look after, and there are quite a few packages in there now as well. We also have a,

17:40.280 --> 17:44.360
I'll be servier at the org, which is a little plan on routes, I'll be there yet, which lists all

17:44.360 --> 17:47.960
of the kind of fun things that Swift and the server can do, as well as linked to loads of

17:47.960 --> 17:54.440
different packages as well. One of the things that I tend to get asked a lot when talking to

17:54.440 --> 17:59.000
months with people and generally back in people is what about observability. And I think one

17:59.000 --> 18:07.000
of Swift server's great legacies is the adoption of APIs for logging methods and tracing.

18:07.000 --> 18:12.680
So we have API or packages for logging, packages for metrics and packages for tracing that provide

18:12.680 --> 18:20.360
just an API. So all libraries and applications and packages in the ecosystem can just call through

18:20.360 --> 18:25.960
those APIs and then application developers can bootstrap whatever back and they want. So if you're

18:25.960 --> 18:30.280
working with metrics, all of the packages can call through to the metrics API and then as an

18:30.280 --> 18:34.760
application developer, you can choose do I want to use Premiere so that's the or CloudWatch

18:34.760 --> 18:39.480
metrics or whatever, and then our backends that you can plug the automatically work and the same

18:39.480 --> 18:43.400
works for logging and the same works for distribution tracing as well. So it's a real thing that works

18:43.400 --> 18:51.240
really really well. I'll do a shameless plug. The Swift server conference will be October,

18:51.240 --> 18:56.840
South October, this year in London, we have great talks from companies as big as Apple Amazon

18:56.840 --> 19:01.640
through to indie developers through to small apps, showcasing how they use Swift and the server,

19:01.640 --> 19:10.200
the website should be updated soon when tickets go on sale. And so to recap, Swift has an ethos of

19:10.280 --> 19:16.360
being fast, modern, safe and interactive and each of these make a really great language for

19:16.360 --> 19:20.600
back end development that provides you with a really nice language to use, it's easy to read and

19:20.600 --> 19:26.760
comprehend and very fast and very safe. And that's why I think it is the best language for building

19:26.840 --> 19:39.160
one of that occasions on the back end. Thank you.

19:41.320 --> 19:43.160
Yeah I'll take questions here.

19:57.640 --> 20:02.440
So the question was, Swift originally was from the Apple ecosystem, how well is it working

20:02.440 --> 20:07.640
Linux and what's the ecosystem like for packages and stuff, these days very very good. So

20:08.760 --> 20:13.880
the foundational libraries are exactly the same on the Linux and on the Apple platforms.

20:16.200 --> 20:23.640
We've been building packages for the ecosystem since 2016, so it's got a well established

20:23.640 --> 20:27.080
package processor. It works very well, you can do it again, you can do

20:28.360 --> 20:31.640
stack traces and do pretty much anything you want to do, is that?

20:35.640 --> 20:37.640
Any more questions?

20:44.200 --> 20:49.000
All right, thank you so much here for running out!

