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.

