WEBVTT 00:00.000 --> 00:07.000 All right, let's quiet down, please. 00:07.000 --> 00:09.000 We need to start the next talk. 00:09.000 --> 00:13.000 Let's give our attention to Terz, who's going to tell us 00:13.000 --> 00:18.000 all about calling Jit compiled scripts in the context of Roto. 00:18.000 --> 00:25.000 All right, hi, Barron. 00:25.000 --> 00:28.000 My name is Terz, and I work for a now-net-lapse, 00:28.000 --> 00:32.000 and I'm going to be talking to you about a little scripting language. 00:32.000 --> 00:35.000 But before I do that, very quick disclaimer. 00:35.000 --> 00:37.000 We kind of always have to do this at a now-net-lapse, 00:37.000 --> 00:41.000 because there's this other thing called a now-net 00:41.000 --> 00:43.000 that we have shums shared history with, 00:43.000 --> 00:45.000 but we are separate entities. 00:45.000 --> 00:48.000 And unfortunately, I cannot fund your project. 00:48.000 --> 00:50.000 No matter how much you ask. 00:50.000 --> 00:54.000 The thing is, they give money away, we take money, 00:55.000 --> 00:59.000 and then with that money, we make open source software. 00:59.000 --> 01:06.000 So, we make open source software for DNS and routing software. 01:06.000 --> 01:10.000 So, in routing is like RPKI and BGP, if you're into networking, 01:10.000 --> 01:13.000 we are a nonprofit organization, 01:13.000 --> 01:15.000 and we've been around for 26 years. 01:15.000 --> 01:17.000 Well, I say we, but I've been there for two years, 01:17.000 --> 01:22.000 because 26 years ago I was a baby, so that doesn't quite work. 01:22.000 --> 01:25.000 And we make loads of products, 01:25.000 --> 01:29.000 if you have ever tinkered with DNS, you might know things like 01:29.000 --> 01:34.000 NSV, an unbound, or some of our other products like 01:34.000 --> 01:37.000 routinator, or rotunda, or krill, or a bunch of other things. 01:37.000 --> 01:39.000 We have stickers. 01:39.000 --> 01:43.000 The one that I want to talk about now is rotunda. 01:43.000 --> 01:46.000 I wrote down it's a BGP route collector, 01:46.000 --> 01:49.000 but I'm not assuming that you have any knowledge about networking, 01:49.000 --> 01:52.000 so all you need to know is it's a database, 01:52.000 --> 01:54.000 and it takes in a lot of data, 01:54.000 --> 01:59.000 and the user needs to decide what data gets filtered. 01:59.000 --> 02:04.000 And we want to allow them to do that with a filter language. 02:04.000 --> 02:06.000 And that needs to be kind of fast, 02:06.000 --> 02:09.000 because we're talking about a lot of data here. 02:09.000 --> 02:14.000 So, my colleagues were scratching the heads around this around 2024, 02:14.000 --> 02:19.000 and then I met up with them at Boston two years ago, 02:19.000 --> 02:23.000 and I just finished my master's thesis in programming languages. 02:23.000 --> 02:27.000 And, incidentally, I was looking for a job. 02:27.000 --> 02:29.000 So, one thing from another, 02:29.000 --> 02:31.000 I was no longer looking for a job, 02:31.000 --> 02:34.000 and instead I was a software engineer at a Knowledge Labs 02:34.000 --> 02:38.000 hired to do some work on this language thing that they were thinking about. 02:38.000 --> 02:40.000 And then a little while later, 02:40.000 --> 02:44.000 I became an organizer of the Rustweek Conference. 02:44.000 --> 02:47.000 So, we have this thing called Rotanda, 02:47.000 --> 02:49.000 and now we're making a language for it. 02:49.000 --> 02:51.000 Okay, what do we call this thing, naming things as hard. 02:51.000 --> 02:54.000 We just get a skirtle at the last part, 02:54.000 --> 02:56.000 and we're going to stuck with Roto. 02:56.000 --> 02:58.000 Are there any Spanish speakers here? 02:58.000 --> 03:00.000 What does this mean? 03:00.000 --> 03:03.000 But also broken, right? 03:03.000 --> 03:04.000 Yeah. 03:04.000 --> 03:07.000 Okay, I promise it's not. 03:07.000 --> 03:12.000 Well, maybe it is a little bit. 03:12.000 --> 03:14.000 All right, so what it is, 03:14.000 --> 03:19.000 is it is a statically typed language that integrates really tightly with Rust. 03:19.000 --> 03:21.000 And the strange thing is, 03:21.000 --> 03:24.000 it gets jit compiled to machine code. 03:24.000 --> 03:27.000 So, there's no interpreter, there's no byte code. 03:27.000 --> 03:29.000 It's straight to machine code. 03:29.000 --> 03:31.000 And this is what it looks like. 03:31.000 --> 03:33.000 It looks a lot like Rust. 03:33.000 --> 03:35.000 With some like niceties, right? 03:35.000 --> 03:40.000 We have F strings here that you don't get in Rust. 03:40.000 --> 03:44.000 But otherwise, you know, you all can read this, you know Rust. 03:44.000 --> 03:47.000 So, how do we use this from Rust, right? 03:47.000 --> 03:51.000 How do we embed this thing in our application? 03:51.000 --> 03:53.000 What we do this? 03:53.000 --> 03:54.000 It's just four lines. 03:54.000 --> 03:55.000 We create a runtime. 03:55.000 --> 03:56.000 We compile the script. 03:56.000 --> 03:58.000 We get the function out of the script, 03:58.000 --> 04:00.000 and then we call that function. 04:01.000 --> 04:05.000 Now, notice that this script gets loaded at runtime of your application. 04:05.000 --> 04:09.000 So, you can actually change the script and start your application again. 04:09.000 --> 04:14.000 You can even reload the script if you set your application up that way. 04:14.000 --> 04:16.000 It gives you a lot of flexibility, 04:16.000 --> 04:23.000 but this whole compilation process happens at the runtime of your application. 04:23.000 --> 04:27.000 Now, I didn't want this to be a tutorial about roto, 04:27.000 --> 04:29.000 because you're all here for Rust, right? 04:29.000 --> 04:33.000 You want to know what's going on under the hood. 04:33.000 --> 04:36.000 So, let me tell you about that. 04:36.000 --> 04:39.000 Roto uses this thing called crane lift. 04:39.000 --> 04:41.000 Who sort of crane lift? 04:41.000 --> 04:43.000 Ah, almost everybody, lovely. 04:43.000 --> 04:46.000 For the people who don't, it is a compiler backend. 04:46.000 --> 04:49.000 A little bit like LVM, but written purely in Rust. 04:49.000 --> 04:53.000 So, the great thing is, you can just do cargo ad crane lift, 04:53.000 --> 04:56.000 and now you have a compiler backend in your project. 04:57.000 --> 05:00.000 Take some getting used to, but it is awesome. 05:00.000 --> 05:03.000 So, roto uses crane lift. 05:03.000 --> 05:06.000 It creates crane lift IR intermediate representation, 05:06.000 --> 05:11.000 and then crane lift has this thing that does the rest. 05:11.000 --> 05:14.000 It just compiles it down to machine code. 05:14.000 --> 05:19.000 Now, what it does is it just allocates a big chunk of memory somewhere, 05:19.000 --> 05:22.000 and it writes all the machine code there. 05:22.000 --> 05:26.000 And then it says, yeah, you know, I've written it there. 05:26.000 --> 05:28.000 Here's a pointer. 05:28.000 --> 05:32.000 A pointer to the machine code you have just generated. 05:32.000 --> 05:34.000 Okay, thanks. 05:34.000 --> 05:36.000 Now, what do I do with that? 05:36.000 --> 05:42.000 Well, it turns out we have to cast that pointer into a function pointer. 05:42.000 --> 05:45.000 So, we have a slice of machine code, 05:45.000 --> 05:49.000 and we just say, just pretend that is a function, please. 05:50.000 --> 05:53.000 And that is what happens. 05:58.000 --> 06:02.000 All right, so how do we make sure that this is actually sound? 06:02.000 --> 06:06.000 Well, the first thing we need to do is check that the whatever signature 06:06.000 --> 06:11.000 we had written in a rotoscript, that matches what we expected 06:11.000 --> 06:16.000 on the rust side, like the function point that we are transmuting it to. 06:16.000 --> 06:23.000 So, each argument and each return type needs to match to a rototype. 06:23.000 --> 06:27.000 And there are some easy cases we can knock off right at the bat, right? 06:27.000 --> 06:30.000 We can say, a bull is a bull and a UA, just a UA, 06:30.000 --> 06:35.000 like CraneLift knows how to deal with integers of different sizes, 06:35.000 --> 06:38.000 and it can generate the right things for us. 06:38.000 --> 06:41.000 So, that works, right? 06:41.000 --> 06:45.000 But then there are some more complicated types. 06:45.000 --> 06:49.000 Right? 06:49.000 --> 06:51.000 I'm skipping some stuff, but that's fine. 06:51.000 --> 06:54.000 There are some more complicated stuff like option. 06:54.000 --> 06:56.000 What does an option look like in memory? 06:56.000 --> 07:01.000 If we want to manipulate an option in our generated code, 07:01.000 --> 07:05.000 we need to know what it looks like in memory. 07:05.000 --> 07:10.000 The thing is that rust likes to be really fast, 07:10.000 --> 07:18.000 it likes to be vague about things so that it can optimize things. 07:18.000 --> 07:21.000 Like the layout of a type, right? 07:21.000 --> 07:24.000 This is a little bit from the rust reference, 07:24.000 --> 07:28.000 and it says, if you have the rust representation of a type, 07:28.000 --> 07:31.000 then there are only three things we guarantee, 07:31.000 --> 07:34.000 and the rest of it, we can just do whatever you want. 07:34.000 --> 07:38.000 So, if you have a first sample struct, then the fields are properly aligned, 07:38.000 --> 07:42.000 they do not overlap, and the alignment is the minimum of the element of the fields. 07:42.000 --> 07:46.000 But they can add like a gigabyte of extra padding if they like. 07:46.000 --> 07:49.000 They can reorder all the fields that they want. 07:49.000 --> 07:54.000 There's no way of telling, and you can't rely on anything you see happening. 07:54.000 --> 07:57.000 Because it might also change between compiler versions, 07:57.000 --> 08:03.000 or maybe even compilations, you should ask some of the rust compiler deaths about that. 08:03.000 --> 08:08.000 So, an option of T, like it could be anything in memory. 08:08.000 --> 08:12.000 So, what we have to do instead is we have to kind of make a run option type, 08:12.000 --> 08:15.000 that is actually very well defined, 08:15.000 --> 08:21.000 that we know what it looks like, so that we can interact with it from roto. 08:21.000 --> 08:24.000 So, we have this thing, a roto option, 08:24.000 --> 08:27.000 and I would like this thing from you. 08:27.000 --> 08:30.000 You don't need to see this thing when you're using roto. 08:30.000 --> 08:34.000 So, under the hood, we take an option, and we transform it into this thing, 08:34.000 --> 08:39.000 which has a wrapper C on it, so that has a very well defined layout. 08:39.000 --> 08:43.000 And then we can actually use it from roto, and then if you pass it back, 08:43.000 --> 08:47.000 if you return it from the script, we should do the inverse conversion 08:47.000 --> 08:50.000 back into a normal rust option. 08:50.000 --> 08:52.000 So, that's that. 08:52.000 --> 08:55.000 That's one more entry in our list. 08:56.000 --> 08:58.000 Okay, now we have a little scripted language, 08:58.000 --> 09:01.000 but we want to do more with this language, right? 09:01.000 --> 09:05.000 There are some types that roto just supports. 09:05.000 --> 09:08.000 It has strings, it has Boolean's, and it is an integer, 09:08.000 --> 09:11.000 and floating point numbers, and even IP addresses, 09:11.000 --> 09:14.000 and some other strange things, just because we needed them. 09:14.000 --> 09:16.000 But this doesn't have everything. 09:16.000 --> 09:20.000 It doesn't have everything that your application might need. 09:20.000 --> 09:22.000 So, how do we fix that? 09:23.000 --> 09:27.000 So, let's assume that your application needs to do 09:27.000 --> 09:30.000 some daytime handling, for example, right? 09:30.000 --> 09:34.000 So, you would like roto to know about daytime's. 09:34.000 --> 09:36.000 Okay, it doesn't. 09:36.000 --> 09:40.000 Like this code does not work out of the box. 09:40.000 --> 09:45.000 But we do have a mechanism that you can register your own types. 09:45.000 --> 09:47.000 It looks like this. 09:47.000 --> 09:51.000 You create a library of things that you want to add to roto, 09:51.000 --> 09:55.000 in a sort of DSL that looks kind of like Rust, 09:55.000 --> 10:00.000 in this library macro, and then you build a runtime with that library. 10:00.000 --> 10:04.000 Now, the Val thing there, you can basically just interpret it 10:04.000 --> 10:07.000 as like this is a custom type of something, 10:07.000 --> 10:11.000 and the clone means roto is allowed to clone this, 10:11.000 --> 10:13.000 but not to do a map copy on it. 10:13.000 --> 10:18.000 Like it can't assume that this thing implements copy. 10:19.000 --> 10:24.000 And the type that we're registering here is just from the GIF grade, 10:24.000 --> 10:28.000 which is a grade for, you know, daytime's and durations, 10:28.000 --> 10:31.000 and all sorts of other complicated time stuff, 10:31.000 --> 10:33.000 and it's really good. 10:33.000 --> 10:37.000 And we just expose that thing to roto. 10:37.000 --> 10:40.000 As kind of like an opaque type. 10:40.000 --> 10:42.000 So, now we can do this. 10:42.000 --> 10:47.000 We can take that daytime thing as an argument, 10:48.000 --> 10:50.000 and we can return it. 10:50.000 --> 10:51.000 So, that's great. 10:51.000 --> 10:54.000 We can also extract that function from, 10:54.000 --> 10:55.000 that we defined in roto. 10:55.000 --> 10:58.000 We can extract that back into Rust. 11:02.000 --> 11:04.000 Okay, so how does that work? 11:04.000 --> 11:07.000 We don't know, I've said before, like, for an option, 11:07.000 --> 11:10.000 we needed to know exactly what it looks like. 11:10.000 --> 11:13.000 How do we handle this kind of type? 11:13.000 --> 11:17.000 That we have no clue about whatsoever. 11:17.000 --> 11:20.000 Well, the first thing is we can't inspect it. 11:20.000 --> 11:22.000 We can't, like, look into it. 11:22.000 --> 11:23.000 We can't read its fields. 11:23.000 --> 11:25.000 We can't, like, if it's an enum, 11:25.000 --> 11:30.000 we can't see the discriminant of the different variants and stuff. 11:30.000 --> 11:32.000 So, it's kind of opaque to us. 11:32.000 --> 11:34.000 That means that we can kind of simplify. 11:34.000 --> 11:38.000 And we could just say, any time we see something like this, 11:38.000 --> 11:40.000 we have a pointer. 11:40.000 --> 11:45.000 And then we just kind of, we, we get the clone function 11:45.000 --> 11:47.000 and the drop function of that value. 11:47.000 --> 11:51.000 And that allows us to kind of move it around and clone it 11:51.000 --> 11:54.000 and do all the things that we need to do with it, 11:54.000 --> 11:57.000 just to be able to sort of pass this through different functions. 11:57.000 --> 12:01.000 It doesn't mean that we can do anything useful with it yet, though. 12:01.000 --> 12:03.000 So, to do anything useful, 12:03.000 --> 12:06.000 we need to add some methods to this type. 12:06.000 --> 12:08.000 Like this one. 12:08.000 --> 12:10.000 It's just this very simple method. 12:10.000 --> 12:13.000 This is not meant to be a full daytime library. 12:13.000 --> 12:18.000 But, you know, maybe you just want to add some days to a daytime. 12:18.000 --> 12:24.000 This is the, the code itself there is how you do that in, in GIF. 12:24.000 --> 12:28.000 But, you can see that still in this library macro. 12:28.000 --> 12:33.000 So, that means that Roto will be able to see this method that you're creating. 12:34.000 --> 12:38.000 And that whole thing works very similar to what I just described. 12:38.000 --> 12:41.000 So, this Roto function is how you extract the function. 12:41.000 --> 12:43.000 It's how you register a function. 12:43.000 --> 12:45.000 We use very similar transformations. 12:45.000 --> 12:47.000 We just go the other way, right? 12:47.000 --> 12:51.000 Where previously we had an option that we transformed it to a Roto option. 12:51.000 --> 12:54.000 Now, we go the other way, we go from a Roto option to an option. 12:54.000 --> 12:58.000 And we just flip the whole thing. 12:58.000 --> 13:01.000 And, and that allows us to do some, do some really cool stuff. 13:01.000 --> 13:04.000 You can add your own types. You can add your own constants. 13:04.000 --> 13:07.000 You can add your own methods and functions and all sorts of stuff. 13:07.000 --> 13:15.000 And that really allows you to tightly integrate this whole thing with your own application. 13:15.000 --> 13:18.000 Now, this is where it gets tricky. 13:18.000 --> 13:25.000 Because I would like Roto to have lists, right? 13:25.000 --> 13:27.000 Lists are great. 13:27.000 --> 13:30.000 What kind of language are you if you don't have any lists? 13:30.000 --> 13:33.000 That would be kind of silly. 13:33.000 --> 13:37.000 So, if we just follow whatever we were doing before, 13:37.000 --> 13:40.000 we just say, well, a list is a vet. 13:40.000 --> 13:43.000 And we just kind of register a vet or something, right? 13:43.000 --> 13:44.000 That should work. 13:44.000 --> 13:52.000 But the problem is that we run this entire thing after Rost has compiled, right? 13:52.000 --> 13:55.000 We don't know anything about the generics of Rost. 13:55.000 --> 13:57.000 That doesn't work. 13:58.000 --> 14:03.000 Because the generics have disappeared. 14:03.000 --> 14:09.000 We can't tell Rost to keep around the code for any possible vet 14:09.000 --> 14:14.000 that it could ever possibly find for any type. 14:14.000 --> 14:17.000 There are generic types do not have type IDs. 14:17.000 --> 14:19.000 They do not have a layout. 14:19.000 --> 14:22.000 If we can't get function pointers to their methods, 14:22.000 --> 14:25.000 we basically can't do anything with them. 14:25.000 --> 14:28.000 Because whenever we're inspecting these things, 14:28.000 --> 14:31.000 the generic type doesn't exist anymore. 14:33.000 --> 14:36.000 So, is that the end of the road then, right? 14:36.000 --> 14:39.000 Are we stuck here? 14:39.000 --> 14:41.000 Yeah. 14:41.000 --> 14:43.000 I want them, right? 14:43.000 --> 14:47.000 Can we not just fake it? 14:47.000 --> 14:50.000 Can we hack around this? 14:51.000 --> 14:57.000 So, this is what I mean with fake generics. 14:57.000 --> 15:00.000 If you have a list of T, right? 15:00.000 --> 15:03.000 You have a list of some element type. 15:03.000 --> 15:08.000 That is roughly equivalent to having a list. 15:08.000 --> 15:12.000 It's just a big buffer of bytes. 15:12.000 --> 15:19.000 And then, we have a V table of some methods that we can use to interact 15:19.000 --> 15:22.000 with the individual elements in that buffer. 15:22.000 --> 15:25.000 So, we know what the sizes of the type, 15:25.000 --> 15:27.000 we know what the alignment is of the type, 15:27.000 --> 15:30.000 and then we know what, for example, the clone that a drop is, 15:30.000 --> 15:32.000 so that whenever we drop our list, 15:32.000 --> 15:35.000 we know how to drop each of the elements in the list. 15:35.000 --> 15:39.000 So, we could just kind of pretend that we know what the type is. 15:39.000 --> 15:42.000 Now, of course, that is unsafe, 15:42.000 --> 15:46.000 because there's nothing stopping us in Rust now 15:46.000 --> 15:52.000 to create a list of U-8s and start adding U-16s to it. 15:52.000 --> 15:53.000 Right? 15:53.000 --> 15:56.000 Because the type parameters gone, there's nothing stopping us. 15:56.000 --> 16:01.000 But, at least, it allows us to do this in Roto. 16:01.000 --> 16:02.000 Right? 16:02.000 --> 16:07.000 It allows us to say something that looks like a list in Roto 16:07.000 --> 16:09.000 is actually this kind of thing. 16:09.000 --> 16:14.000 And we just tell Roto to pretend that there is a type parameter. 16:14.000 --> 16:17.000 And for every method that we register for it, 16:17.000 --> 16:20.000 we also say, now pretend there's an additional type parameter 16:20.000 --> 16:23.000 when you do your type checking on this. 16:23.000 --> 16:26.000 So, the Roto type checker actually enforces 16:26.000 --> 16:32.000 that the individual accesses that you are doing are actually safe. 16:32.000 --> 16:37.000 And that kind of leads to this, 16:37.000 --> 16:41.000 because we also then make a wrapper for that in Rust, 16:41.000 --> 16:43.000 which is safe. 16:43.000 --> 16:48.000 So, we go from a type wrapper in Rust to a race list, 16:48.000 --> 16:50.000 which has no type parameters anymore. 16:50.000 --> 16:54.000 And then we tell Roto to pretend that again has a type parameter. 16:54.000 --> 16:58.000 And that's how we work around the whole thing about the generics. 16:58.000 --> 17:05.000 And instead, we just say, that works. 17:05.000 --> 17:10.000 And that is kind of the most complicated that we've gone so far 17:10.000 --> 17:16.000 in terms of this whole F5 boundary. 17:16.000 --> 17:21.000 Now, let's type some loose threads. 17:21.000 --> 17:26.000 While implementing this, I have learned to not be too clever. 17:26.000 --> 17:29.000 This should come as no surprise. 17:29.000 --> 17:34.000 But I was dealing with the cloning and dropping things by pointer 17:34.000 --> 17:37.000 and doing all sorts of crazy stuff. 17:37.000 --> 17:41.000 And I didn't get that wrong a few times. 17:41.000 --> 17:44.000 But I learned to try the easy thing first, 17:44.000 --> 17:46.000 and only then optimize later. 17:46.000 --> 17:48.000 And there's still many things to optimize, 17:48.000 --> 17:51.000 but at least it works now. 17:51.000 --> 17:53.000 And then we have loads of tests, 17:53.000 --> 17:55.000 and we run Valgrind on these tests. 17:55.000 --> 17:57.000 Now, an interesting thing to note is that we can't run 17:57.000 --> 18:03.000 Mary on everything, because Mary can't run our generated code. 18:03.000 --> 18:06.000 Because we are generating directly machine code, 18:06.000 --> 18:10.000 and Mary interprets an intermediate representation of the press 18:10.000 --> 18:15.000 compiler, so it doesn't actually run machine code that well. 18:15.000 --> 18:18.000 But we can run our entire test suite on a Valgrind, 18:18.000 --> 18:21.000 and it will catch any leaks or double freeze or anything 18:21.000 --> 18:24.000 that my coach and my do wrong, it will hopefully still catch. 18:24.000 --> 18:29.000 Not anything, but many things. 18:29.000 --> 18:32.000 And based on this work that we've done for list, 18:32.000 --> 18:34.000 we want to do some more features, 18:34.000 --> 18:37.000 like we want to add maps or dictionaries, 18:37.000 --> 18:41.000 or however you want to call them to this language. 18:41.000 --> 18:45.000 And then we'd love to at some point be able to access 18:45.000 --> 18:48.000 fields or match on Rust Enems. 18:48.000 --> 18:51.000 But of course, I said before, 18:51.000 --> 18:54.000 like we kind of have to assume that any type you register 18:54.000 --> 18:56.000 is opaque. 18:56.000 --> 18:59.000 We can't look into it, so that will take some more 18:59.000 --> 19:01.000 problem-solving to make that work. 19:01.000 --> 19:04.000 And then we have other wild features planned, 19:04.000 --> 19:07.000 like first-class functions that you can pass in a function 19:07.000 --> 19:09.000 from Roto to Rust and then from Roto, 19:09.000 --> 19:11.000 and then from the Roto calls the Roto function, 19:11.000 --> 19:14.000 and it gets crazy. 19:15.000 --> 19:17.000 All right, that was all I had to say about Roto. 19:17.000 --> 19:21.000 But I'd like to quickly interject 19:21.000 --> 19:24.000 about this thing called Rust Week. 19:29.000 --> 19:32.000 It will be an awesome conference. 19:32.000 --> 19:35.000 There are many of the organizers are also here. 19:35.000 --> 19:37.000 There's Mara and Yana. 19:37.000 --> 19:39.000 There they are. 19:39.000 --> 19:42.000 And it's this May. 19:42.000 --> 19:45.000 It's going to be huge. 19:45.000 --> 19:48.000 It's going to be two days of three tracks. 19:48.000 --> 19:50.000 And you should definitely get tickets. 19:50.000 --> 19:52.000 Now to encourage you to get tickets, 19:52.000 --> 19:54.000 and to thank you for listening to my talk. 19:54.000 --> 19:56.000 There's a little discount code. 19:56.000 --> 19:58.000 For them to be six. 19:58.000 --> 20:01.000 We'll give you 10% off of any tickets that you think 20:01.000 --> 20:02.000 that you want. 20:02.000 --> 20:07.000 We also have some cards lying around. 20:07.000 --> 20:11.000 You can also get with a full schedule and everything, 20:11.000 --> 20:13.000 and you can go to Rust Week. 20:13.000 --> 20:16.000 We've got work to get all the information. 20:16.000 --> 20:18.000 That's all I have. 20:18.000 --> 20:19.000 Thank you. 20:30.000 --> 20:32.000 Any questions? 20:33.000 --> 20:36.000 Thank you for the awesome talk. 20:36.000 --> 20:38.000 I may have misunderstood, 20:38.000 --> 20:41.000 but it looks that you're implementing this list, 20:41.000 --> 20:43.000 essentially with dynamic dispatch. 20:43.000 --> 20:46.000 That you then have like kind of a list of 20:46.000 --> 20:48.000 retailers and each one just represents the function 20:48.000 --> 20:50.000 you can call on that. 20:50.000 --> 20:52.000 I'm just wondering, wouldn't it be more natural 20:52.000 --> 20:55.000 than to also on the Rust site represented as this? 20:55.000 --> 20:58.000 On the Rust site, I don't see like a list which is generic, 20:58.000 --> 21:01.000 but instead like a list which actually contains straight objects, 21:01.000 --> 21:04.000 and then this is also what you have on the road to site. 21:04.000 --> 21:05.000 Yes. 21:05.000 --> 21:09.000 So the question is, could we instead just implement this list 21:09.000 --> 21:11.000 as a list of trade objects, right? 21:11.000 --> 21:16.000 The problem is that that almost works in many cases, 21:16.000 --> 21:20.000 but you can also define your own road to types. 21:20.000 --> 21:23.000 And then I would have to generate trade objects 21:23.000 --> 21:25.000 for those road to types. 21:25.000 --> 21:28.000 Whereas if I have my own VTable implementation, 21:28.000 --> 21:30.000 I know exactly what's in it, and what it looks like, 21:30.000 --> 21:34.000 and I can generate that for any type that I have in Roto. 21:34.000 --> 21:37.000 And so you can even declare a type in Roto 21:37.000 --> 21:39.000 then add that to a list, 21:39.000 --> 21:42.000 even though the list is implemented in Rust. 21:42.000 --> 21:45.000 And that makes it a little bit more complicated. 21:47.000 --> 21:48.000 Okay? 21:59.000 --> 22:04.000 Thank you for the very interesting thoughts. 22:04.000 --> 22:10.000 So what about the performance that you measured 22:10.000 --> 22:12.000 by integrating Roto into Roto? 22:12.000 --> 22:14.000 What were the findings, 22:14.000 --> 22:19.000 and what do you plan to optimize for the project and in general? 22:19.000 --> 22:22.000 So you want to know what the performance measurements are. 22:22.000 --> 22:24.000 What did you get out of it? 22:24.000 --> 22:25.000 Right. 22:26.000 --> 22:31.000 So the performance is pretty good right now. 22:31.000 --> 22:36.000 If you stick to, especially if you stick to numbers. 22:36.000 --> 22:37.000 Right? 22:37.000 --> 22:41.000 So in the German population, a arithmetic, that kind of stuff. 22:41.000 --> 22:42.000 Yeah. 22:42.000 --> 22:44.000 Then it's really good, 22:44.000 --> 22:46.000 and it beats Lua easily. 22:46.000 --> 22:51.000 But what many of these scripting languages do, 22:51.000 --> 22:52.000 that we don't, 22:52.000 --> 22:55.000 is they are very clever about their data structures. 22:55.000 --> 22:57.000 So if you have lists, for instance, 22:57.000 --> 23:00.000 like JavaScript run times are crazy about this, 23:00.000 --> 23:03.000 they will pull all sorts of tricks under the hood 23:03.000 --> 23:06.000 to make those things faster. 23:06.000 --> 23:09.000 And we are liking behind in that. 23:09.000 --> 23:11.000 So if you do lots of string manipulation, 23:11.000 --> 23:14.000 you'll be a little bit slower. 23:14.000 --> 23:16.000 But if you stick to simple stuff, 23:16.000 --> 23:18.000 it will be a lot faster right now. 23:18.000 --> 23:25.000 And that's just something that we'll have to chip away at over time. 23:25.000 --> 23:33.000 Yeah, like copy on rights or like if you. 23:33.000 --> 23:38.000 Yeah. 23:38.000 --> 23:40.000 I have a syntax question. 23:40.000 --> 23:44.000 Is there any particular reason why you chose the square brackets 23:44.000 --> 23:46.000 for the genetics? 23:47.000 --> 23:50.000 Why I chose the square brackets for the genetics? 23:50.000 --> 23:53.000 Because I wanted to avoid the turbofish. 23:53.000 --> 23:54.000 Right? 23:54.000 --> 23:58.000 So the angled brackets in the parts that I kind of conflict 23:58.000 --> 24:01.000 with comparison operations. 24:01.000 --> 24:05.000 And that's why you need colon colon angle brackets 24:05.000 --> 24:07.000 for in rust usually. 24:07.000 --> 24:10.000 And then I figured if I use the square brackets, 24:10.000 --> 24:11.000 then I kind of avoid that. 24:11.000 --> 24:15.000 Although it does kind of conflict with list indexing now, 24:15.000 --> 24:20.000 but that's it there. 24:20.000 --> 24:23.000 You mentioned JavaScript run times. 24:23.000 --> 24:27.000 Do you do anything clever in terms of the just-in-time compilation? 24:27.000 --> 24:29.000 I say you have something in the loop. 24:29.000 --> 24:33.000 Will you only compile it once and then use the machine code 24:33.000 --> 24:35.000 in all the other loop iterations? 24:35.000 --> 24:38.000 Or would you do the jitter compilation every time? 24:38.000 --> 24:43.000 So we don't do super clever stuff because we already have the type 24:44.000 --> 24:45.000 information. 24:45.000 --> 24:48.000 We are already pretty good out of the box. 24:48.000 --> 24:52.000 We could indeed in the future do more like constant propagation 24:52.000 --> 24:55.000 or like other optimizations. 24:55.000 --> 24:57.000 But that is we currently don't. 24:57.000 --> 24:59.000 No. 24:59.000 --> 25:01.000 It's nice to thank you. 25:01.000 --> 25:02.000 Thank you. 25:02.000 --> 25:03.000 There's a really nice talk. 25:03.000 --> 25:04.000 Thank you. 25:13.000 --> 25:15.000 Thank you.