WEBVTT captioned by gabriele
00:00:00.000 --> 00:00:02.359
Hello, I'm very excited to tell you
00:00:02.360 --> 00:00:03.679
about shared philosophies
00:00:03.680 --> 00:00:06.479
between the Julia programming language and Emacs.
00:00:06.480 --> 00:00:08.679
While Julia and Emacs might look like
00:00:08.680 --> 00:00:10.279
different pieces of software,
00:00:10.280 --> 00:00:13.439
I think there is profound commonalities between the two.
00:00:13.440 --> 00:00:16.359
Let's start by introducing Julia.
00:00:16.360 --> 00:00:19.719
Julia is a high-level dynamic programming language.
00:00:19.720 --> 00:00:21.679
Julia is free and open source software
00:00:21.680 --> 00:00:24.639
and is used primarily for scientific computing.
00:00:24.640 --> 00:00:27.039
The reason Julia is used for scientific computing
00:00:27.040 --> 00:00:29.679
is that while Julia is high level
00:00:29.680 --> 00:00:32.559
and has a syntax that looks like Python or MATLAB,
00:00:32.560 --> 00:00:34.559
Julia can be high performance.
00:00:34.560 --> 00:00:36.519
I use it to develop climate models
00:00:36.520 --> 00:00:38.479
that run on hundreds of GPUs.
00:00:38.480 --> 00:00:43.399
Models that are traditionally developed with C, C++, or Fortran.
00:00:43.400 --> 00:00:44.759
But how is this possible?
00:00:44.760 --> 00:00:46.799
How can Julia be high performance
00:00:46.800 --> 00:00:48.799
but also high level at the same time?
00:00:48.800 --> 00:00:50.424
What makes Julia, Julia?
00:00:50.425 --> 00:00:52.469
Well, what makes Julia, Julia
00:00:52.470 --> 00:00:54.719
is the idea of multiple dispatch.
00:00:54.720 --> 00:00:58.999
Multiple dispatch is the concept where a function call is resolved
00:00:59.000 --> 00:01:02.359
by looking at the types of every single argument involved.
00:01:02.360 --> 00:01:04.959
So, let's explore this with this example.
00:01:04.960 --> 00:01:07.719
Here, I define a function add that takes two objects
00:01:07.720 --> 00:01:09.159
and sums them together.
00:01:09.160 --> 00:01:11.879
And I call add with two different types.
00:01:11.880 --> 00:01:14.639
First with just integers and second with floats.
00:01:14.640 --> 00:01:17.559
So, let's look at what this produces.
00:01:17.560 --> 00:01:20.439
Here is the output of add in Julia.
00:01:20.440 --> 00:01:23.279
So, first we have add, a function with one method.
00:01:23.280 --> 00:01:24.839
I'm going to explain this in a second.
00:01:24.840 --> 00:01:28.719
And then we have our return values 12 and 12.0.
00:01:28.720 --> 00:01:30.799
What we cannot see here is that
00:01:30.800 --> 00:01:33.439
Julia has specialized code
00:01:33.440 --> 00:01:35.119
for the two different function calls.
00:01:35.120 --> 00:01:38.359
For integers and for floating points.
00:01:38.360 --> 00:01:42.239
Let's make this more explicit by specifically providing
00:01:42.240 --> 00:01:45.079
a new method for the case with floating point.
00:01:45.080 --> 00:01:47.599
So here, now I have an add function
00:01:47.600 --> 00:01:50.119
specifically for floating point. Instead of taking
00:01:50.120 --> 00:01:54.759
A + B, this returns A exponent B. Let's call this.
00:01:54.760 --> 00:01:56.799
And what we can see here is that
00:01:56.800 --> 00:01:58.319
now we have two methods.
00:01:58.320 --> 00:02:00.559
So, we add a new method to the same function.
00:02:00.560 --> 00:02:01.639
This is a method that is
00:02:01.640 --> 00:02:03.679
specifically for floating points.
00:02:03.680 --> 00:02:06.959
And instead of having the value 12, we have 100.
00:02:06.960 --> 00:02:09.039
And this is where the trick lies.
00:02:09.040 --> 00:02:13.879
Julia compiles the most, um, specialized version
00:02:13.880 --> 00:02:16.839
that can be compiled. So, a version with integers,
00:02:16.840 --> 00:02:19.199
a version with floats. And in this,
00:02:19.200 --> 00:02:22.679
compiling is an actual compilation with LLVM
00:02:22.680 --> 00:02:24.479
with optimization and so on.
00:02:24.480 --> 00:02:27.439
This is not just ahead of time compilation.
00:02:27.440 --> 00:02:30.719
Soon as the Julia knows the type,
00:02:30.720 --> 00:02:33.719
a function is compiled if it's not compiled already
00:02:33.720 --> 00:02:35.079
and then it's used.
00:02:35.080 --> 00:02:37.159
When types are stable and well inferred,
00:02:37.160 --> 00:02:40.079
this can lead to code that is as performant
00:02:40.080 --> 00:02:42.159
or comparable to C and Fortran.
00:02:42.160 --> 00:02:45.159
So, this is what makes Julia, Julia.
00:02:45.160 --> 00:02:48.439
Multiple dispatch with just ahead of time compilation
00:02:48.440 --> 00:02:49.719
of highly efficient code.
00:02:49.720 --> 00:02:53.439
So now, what makes Emacs, Emacs?
00:02:53.440 --> 00:02:56.679
Well, in my opinion, what makes Emacs, Emacs
00:02:56.680 --> 00:03:01.159
is interactivity, extensibility, and community.
00:03:01.160 --> 00:03:06.199
And I claim that Julia has the same three.
00:03:06.200 --> 00:03:09.079
Interactivity, extensibility, and community
00:03:09.080 --> 00:03:11.839
are three key pillars for Julia.
00:03:11.840 --> 00:03:14.599
More specifically, Julia encourages a
00:03:14.600 --> 00:03:17.079
REPL-driven, introspective, interactive workflow.
00:03:17.080 --> 00:03:19.879
It's largely open to extension and modification
00:03:19.880 --> 00:03:23.559
to the point that most of Julia is written in Julia.
00:03:23.560 --> 00:03:25.959
And Julia has a thriving and welcoming community
00:03:25.960 --> 00:03:28.799
with lots of packages. So, let me showcase
00:03:28.800 --> 00:03:31.079
a little bit of this REPL-driven, introspective,
00:03:31.080 --> 00:03:34.359
interactive workflow with the hope that commonalities
00:03:34.360 --> 00:03:36.759
with Emacs will emerge naturally.
00:03:36.760 --> 00:03:39.919
So, let's start by opening a Julia REPL.
00:03:39.920 --> 00:03:41.759
Here, I have a Julia REPL.
00:03:41.760 --> 00:03:44.399
Let me give you a tour of the Julia REPL.
00:03:44.400 --> 00:03:47.759
So, the REPL comes with lots of useful features,
00:03:47.760 --> 00:03:51.559
from a shell to a package manager.
00:03:51.560 --> 00:03:54.999
So, for example, let's add the random package.
00:03:55.000 --> 00:03:58.279
Um, yeah, I have the random package.
00:03:58.280 --> 00:03:59.279
I can look at what's inside.
00:03:59.280 --> 00:04:01.279
We have the statistics with random
00:04:01.280 --> 00:04:02.479
in this particular environment.
00:04:02.480 --> 00:04:05.719
Environments are fully declarative.
00:04:05.720 --> 00:04:08.039
So here we have the dependencies of this environment.
00:04:08.040 --> 00:04:10.239
And I can explore in this manifest,
00:04:10.240 --> 00:04:13.999
the specific versions that are used.
00:04:14.000 --> 00:04:17.719
So we have a shell, we have a package manager,
00:04:17.720 --> 00:04:20.559
and then we have a very powerful help system.
00:04:20.560 --> 00:04:24.199
So, for example, I can ask for help for length.
00:04:24.200 --> 00:04:26.639
And here we can see we have, well,
00:04:26.640 --> 00:04:30.999
the help for length. Lots of information about
00:04:31.000 --> 00:04:33.399
how to call length, the expected return values,
00:04:33.400 --> 00:04:36.119
examples. And now you can probably start seeing that
00:04:36.120 --> 00:04:37.759
this is not that different from calling length.
00:04:37.760 --> 00:04:42.119
So this is the output for length,
00:04:42.120 --> 00:04:44.999
or for help for length in in Emacs.
00:04:45.000 --> 00:04:47.959
So we have help, and we can do more.
00:04:47.960 --> 00:04:51.879
We can even look at the source code for length.
00:04:51.880 --> 00:04:57.079
So now, what we can see here is that now, well,
00:04:57.080 --> 00:04:58.919
we cannot see because it's zoomed in
00:04:58.920 --> 00:05:02.799
because the font size is huge, but in this page here,
00:05:02.800 --> 00:05:04.759
we can see the implementation of length.
00:05:04.760 --> 00:05:06.719
It's this line here in the middle,
00:05:06.720 --> 00:05:09.719
or these few lines here in the middle.
00:05:09.720 --> 00:05:12.079
And as you... Let's do this again.
00:05:12.080 --> 00:05:12.999
As we can see here at the bottom,
00:05:13.000 --> 00:05:13.799
what we are looking at,
00:05:13.800 --> 00:05:15.639
this is the source code of Julia.
00:05:15.640 --> 00:05:17.039
We can change this.
00:05:17.040 --> 00:05:20.039
There's even a macro edit
00:05:20.040 --> 00:05:22.759
if you want to change its length.
00:05:22.760 --> 00:05:24.599
And yeah, I use the word macro.
00:05:24.600 --> 00:05:28.639
Julia supports metaprogramming.
00:05:28.640 --> 00:05:30.359
And actually metaprogramming is
00:05:30.360 --> 00:05:32.079
one of the key features in Julia.
00:05:32.080 --> 00:05:33.639
It's used extensively in the core,
00:05:33.640 --> 00:05:36.399
but it's also used extensively in packages,
00:05:36.400 --> 00:05:40.079
both to extend the Julia ecosystem and functionalities,
00:05:40.080 --> 00:05:43.479
but also to develop full domain specific languages.
00:05:43.480 --> 00:05:47.239
Some of the useful macros are, well, I don't know,
00:05:47.240 --> 00:05:52.239
like time. Here, we have a built-in
00:05:52.240 --> 00:05:55.799
basic performance tool in in in Julia.
00:05:55.800 --> 00:06:00.479
And I want to showcase more introspection, macros.
00:06:00.480 --> 00:06:02.959
But for that, I'm going to do it slightly different.
00:06:02.960 --> 00:06:04.039
I'm going to open a file
00:06:04.040 --> 00:06:06.239
example.jl where I define a
00:06:06.240 --> 00:06:08.039
function, or our
00:06:08.040 --> 00:06:09.519
function add, there was an asterisk
00:06:09.520 --> 00:06:11.199
and I will go back to that in a second.
00:06:11.200 --> 00:06:15.239
So now, I am going to include this this file,
00:06:15.240 --> 00:06:18.199
and I can call my function add, one and two,
00:06:18.200 --> 00:06:22.639
and we get three. And now, what I can do is this.
00:06:22.640 --> 00:06:28.039
I can look at what code gets compiled
00:06:28.040 --> 00:06:31.359
when I call my when I call 1 + 2.
00:06:31.360 --> 00:06:33.359
And here, now we can see
00:06:33.360 --> 00:06:34.639
that there is some integer stuff.
00:06:34.640 --> 00:06:38.159
But if I make this floating point,
00:06:38.160 --> 00:06:40.239
now the compiled code changes.
00:06:40.240 --> 00:06:43.599
Now, maybe assembly code
00:06:43.600 --> 00:06:45.079
is a little bit too hard to read,
00:06:45.080 --> 00:06:48.639
so I can look at the LLVM IR representation.
00:06:48.640 --> 00:06:50.399
In this case we can see that there is promotion.
00:06:50.400 --> 00:06:52.239
The promotion will probably go away
00:06:52.240 --> 00:06:56.039
if I make everything float. So this we have F add,
00:06:56.040 --> 00:06:57.999
floating point add for a double,
00:06:58.000 --> 00:06:59.439
but we can also look at
00:06:59.440 --> 00:07:04.239
the Julia lowered representation
00:07:04.240 --> 00:07:06.079
after the abstract syntax tree is produced.
00:07:06.080 --> 00:07:07.919
The reason I put this in a file is because
00:07:07.920 --> 00:07:10.119
now what I can do is I can change this.
00:07:10.120 --> 00:07:14.079
And now, one and two will be two.
00:07:14.080 --> 00:07:16.879
So this to me is very reminiscent
00:07:16.880 --> 00:07:18.719
of how I work in Emacs,
00:07:18.720 --> 00:07:20.239
where there is a global state
00:07:20.240 --> 00:07:22.959
that I can access and modify any time
00:07:22.960 --> 00:07:27.159
with no restrictions. And this happens in in Julia too.
00:07:27.160 --> 00:07:29.559
Typically, we don't want to modify functions
00:07:29.560 --> 00:07:32.519
that are in other packages or they are in base,
00:07:32.520 --> 00:07:34.079
but we can do that. For example,
00:07:34.080 --> 00:07:37.639
I can change what is plus for integers.
00:07:37.640 --> 00:07:41.079
And if I change with this plus
00:07:41.080 --> 00:07:43.759
and make it so that any two integers return zero,
00:07:43.760 --> 00:07:46.319
well, I can do this. This will break Julia because,
00:07:46.320 --> 00:07:48.359
well, Julia is built in Julia.
00:07:48.360 --> 00:07:51.399
So if we break this, well, nothing will work.
00:07:51.400 --> 00:07:53.399
But I can do that. This to me is one of
00:07:53.400 --> 00:07:56.199
the signs of the powerful, introspective,
00:07:56.200 --> 00:07:58.479
and powerful interactive type of workflows
00:07:58.480 --> 00:07:59.279
that Julia enables.
00:07:59.280 --> 00:08:03.479
Finally, I want to talk about the general registry.
00:08:03.480 --> 00:08:06.399
This is the equivalent of Melpa.
00:08:06.400 --> 00:08:08.759
It comes with with Julia.
00:08:08.760 --> 00:08:11.119
But this is very akin to Melpa.
00:08:11.120 --> 00:08:14.479
It's built upon Git essentially.
00:08:14.480 --> 00:08:19.399
It's collaborative, as relies heavily on GitHub, GitLab.
00:08:19.400 --> 00:08:21.119
It's heavily automated.
00:08:21.120 --> 00:08:24.479
And comes with lots and lots of tools and packages.
00:08:24.480 --> 00:08:27.559
What's beautiful about all these tools and packages
00:08:27.560 --> 00:08:30.279
is that in the same way many of Emacs packages
00:08:30.280 --> 00:08:32.399
just play nicely with each other
00:08:32.400 --> 00:08:34.879
without any input from the developers,
00:08:34.880 --> 00:08:37.559
the same is true for Julia packages.
00:08:37.560 --> 00:08:40.679
The Julia packages are highly composable,
00:08:40.680 --> 00:08:42.879
so two developers can develop
00:08:42.880 --> 00:08:44.719
two distinct packages
00:08:44.720 --> 00:08:47.639
that end up playing nicely together for free
00:08:47.640 --> 00:08:51.879
because of the intrinsic structure, intrinsic way
00:08:51.880 --> 00:08:54.079
Julia objects are built.
00:08:54.080 --> 00:08:57.479
So, with all of this, I also want to mention that
00:08:57.480 --> 00:09:00.079
the community, in addition to have all these packages,
00:09:00.080 --> 00:09:02.599
is highly active, highly collaborative.
00:09:02.600 --> 00:09:06.159
The community meets regularly on places like Slack,
00:09:06.160 --> 00:09:08.199
as opposed to the Emacs community
00:09:08.200 --> 00:09:10.039
that I'd say maybe meets on Reddit.
00:09:10.040 --> 00:09:12.999
So, with all of this, I want to thank you
00:09:13.000 --> 00:09:16.560
for your attention, enjoy Emacs, and enjoy Julia.