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.