All right, we've got Alex, he's going to present cell the common expression language
in Rust.
All right, so please give him a warm welcome.
I can't compare to clapping at the end and see how well I did.
Thank you so much.
So I'm Alex.
I'm a Dith Feetler at Redout.
And this project is not a Redout project,
but yeah, I'm a maintainer on the cell Rust implementation.
So here in the room, I guess you all rust developers.
Like how many of those are doing Rust professionally, actually out of curiosity?
Well, fair amount, that's great.
So how many people know about cell already in this way the best hands?
So that's good.
All right, so what is cell?
So it's a common expression language.
It's a language that has a few interesting properties that may or may not fit your use case.
So the ones out there probably else sound very, very good.
So fast, portable, sustainable, and safe,
are properties that probably we're all looking for.
The language that's more properties, it's not turn completes.
It has a cost model associated with an expression once it's being parsed.
So that you can know how costly evaluate into expression is going to be.
And yes, it avoids uses doing stupid stuff like looping forever,
and things like that are just not possible in that language.
So it came out of Google, I think around 2017,
that's when the first open source repo commits happened.
And they actually have three implementations like the go,
the Java one and the C++ one,
so that you can embed the parser interpreter in one of those languages.
There is also JavaScript, typescript, and other stuff that exists,
and they happens to be a rust implementation as well.
Those are community efforts though, so they're not.
And as far as I know, certainly for us,
there is no relationship with Google.
For others, as far as I can find, they're an online.
So cell reaches some of the goals I mentioned before in different ways.
Cell is a strongly typed expression language,
which I personally like.
I guess most people here do as well.
You get a bunch of types out of the box.
The ones you probably would expect,
maybe somewhat surprising is maybe bytes in there.
The timestamp duration ones are the ones that come from the,
what Google calls the well known types,
the protobuff stuff, supports maps, lists.
It actually is more types like din types,
so that when the type will only be known at evaluation time.
Then support structs, mostly through the Google protobuff message stuff.
It asks, what I call JSON interrupt, interrupt,
because JSON is not natively supported.
It is just a very well-specked how JSON is supposed to be transformed into a struct,
and then you can leverage that.
Because of all the types of these types of stuff again, right?
That we care about.
It has a spec like an actual language definition,
and even the conformant tests,
I'll get back to that later.
All right, so let's look a little bit at what cell looks like.
So I guess none of those need really any explanations.
They're probably all fairly straightforward.
We do string concatenation there.
Resource of naming that case is supposed to be a string,
and strings have some nice functions associated with them.
We're looking to more details how that works later.
So I guess none of that is too weird.
Maybe the last one, the very last line,
could be somewhat intriguing.
So the all is actually a macro.
And the first argument that you see there is actually
defining a binding R for all the for every single element
into the collection that we're looking on inside resources, right?
So that maybe is somewhat surprising.
But other than that, I think anybody can easily pick the language up
and start writing sad expressions for whatever they're trying to achieve.
I, wherever you embedded that run time inside your application.
This weird like, yeah, I'll explain where it comes from and a bit.
Another interesting syntax is the optional optional syntax
in the sense that that needs to be enabled by your runtime and your browser.
You don't need to necessarily support it and allow you to use it.
So I changed them there.
So that values we're looking at index thing 2 inside values.
This could be a string if that would be a map key by string, for instance.
In this case, it's in the right.
And we're asking, oh, is that thing actually there?
If it's not, that's going to return a option type, think of it.
That then.
So in this case, it's supposed to be a struct.
If it's not there, it returns none.
And eventually, I do something with this optional, right?
So in this case, we're changing them.
And at the end, I go, okay, if we couldn't resolve all this path,
just return the value zero, this or value at the end.
All right, so the big, like the way that I certainly was introduced to sell is
because I work on a product that leaves in Kubernetes land and whatnot.
And actually, sell is used in site Kubernetes for you to be able to do
advanced validation on CRS that uses would want to apply to a cluster.
And you would use expressions like predicate effectively to make sure that
let's say you need a value to be between 12 and 13.
Well, that's a shit number.
12 and 42, right?
And now you don't need to call it to a webbook.
We can do that that way.
That being said, sell is being used in very different context.
Like, I think a library is using an accounting software for something.
So it uses express sell to do something and then, I guess,
numbers come out there.
So we use it in site quadrant, which is the project I'm working on.
Mostly to do predicates and data retrieval on payloads as the three examples you saw before.
Most of that stuff is evaluated on the data plane.
So I need to be really, really fast.
Example given doing right limiting, making sure that this free question
go through depending on certain predicates and or attributes.
That needs to be fast.
And we live inside a, let's say, interesting ecosystem nowadays.
So I need to be able to run sell in the go context, in the rust context,
and in the rust context, but running on wasm.
All right, so getting started, that's probably very easy.
You probably all seen that, so that's all you need to do.
And this is how you would evaluate sell and like from a rust program.
So we simply compiled the program.
This could obviously fail, could it could not be valid sell.
We didn't create a so-called context and then execute the program passing in that context.
In this case, we're not doing anything with that.
I'll show in a bit what happens.
Again, it unwrap the result out there, because again, that could fail.
And now we're making sure that the value is actually true.
So the type of value is actually a sell value, and we provide all the,
well, the typing should go coding to make sure that you can go from either direction back and forth.
So that's the end to, at the end of the, the true there in case that wasn't clear.
Right, so obviously comparing one to one is not very useful.
So what you want to do is, so what you do is you use the context.
I actually provide, I guess, context to this set expression being evaluated.
So in this case, we're passing a variable in there with the claim variable,
and we do it as the value 10, and now I can do math.
And again, execute and full time series in the 20.
You can also provide functions, the clear functions for your program to use.
That's how you extend sell to do whatever may be appropriate for your domain.
So that's one example of adding a function, just providing a closure,
and it takes two arguments of, yeah, those are 64 back to the,
to the sugar coding that we do.
You don't need to care necessarily about the necessarily some case you will have,
but let's say for those kind of types that's straightforward.
So doing math, we can now do add 10, 10, 10,
and we get a 20 out of the there, so that works too.
So about that sugar coding, looking a little deeper how this works,
how this works, I'm adding a function now, is empty.
The function is declared where I'd be low.
There is this weirdo thing, this is supposed to be an arc of a string,
because yes, sell is, it's certainly thread safe.
It's not really concurrent, but you can run on concurrent stuff.
So if I don't need an expression one, share it with many threads.
The same is actually somewhat through with the context, just as much,
and then have that stuff being evaluated in different,
share the cost threads and evaluating over multiple places.
So that's adding a, is empty method on string, so add the function.
So this weird thing that I just talked about now, I can have this,
sell expression that just will, my string is empty,
will be through a false depending on the string value of my string.
So again, all that is was just a little bit more sugar coding,
that's actually everything being gone.
That's a function that always fails.
So it actually takes a function context that has all the information
that you really care about.
That's a glance into that.
And then you resolve, resolve, resolve to just resolve that,
either contains a value or an executioner,
and execute the thing you asked us to execute,
which in this case would be the case, because that function always fails.
All right, so back in 2024 is when I got involved with set rust.
Again, I was just looking for cell support and rust.
I found the scrape that was started.
Around 20, 20 something.
Then got somewhat a limbo for a time,
then came out of the ash as yet again.
And so I found a few bugs there,
started submitting and whatever.
And very friendly folks, all that went through.
And then one day one weird bug came up,
which was somewhat related to function dispatch code.
That wasn't really working, asked to go implementation was working.
And because we need those expressions to be able to
be the same regardless of the environment that you're running,
which I guess most people would want.
I was like, okay, so what is going on there?
I think that leads to the next thing.
Yes, I guess I can fix that.
So that was toward the end of 2024, I think.
And looking into it, actually the bug was related
that they use a different grammar than the other parsers.
So I'm like, okay, well, we should be able to fix that.
How hard can it be?
When you're not really young anymore, but I'm still stupid.
So as I go, okay, let's fix that.
So the actual grammar is an envelope for grammar.
That all the other implementation use.
So I'm like, okay, well, just generate rust code
from an after grammar, right?
That's what Hitler does.
Well, no, it doesn't.
It doesn't do it for rust.
So I found this antler rust rate.
I'm like, okay, that's great.
We'll just use that.
So I ended up actually doing, I had to fork this library
because the person who started it hasn't been active for
three years.
Actually, they come back somewhat last December for a few days
and then redistipured.
Anyways, I heard there's a war going on here.
So anyways, I don't know what's going on, but always been luck.
But so I ended up rewriting the entire parser,
fixing this antler stuff.
So we now have a different antler for rust rate
that people can use.
At the same time, we started running a fuzzer
on our implementation and that way
we found including bunch of bugs in the parser library
and the rust parser library.
So anyways, so you're like, why are you doing all this stuff?
That doesn't sound like the same things to do.
I probably could have fixed the grammar
as I did initially in 2024,
but actually spending more and more time
in the other implementations,
what cell is all about as those things, right?
And other than extensibility,
actually most of it is very much done at the ST level.
So I have the abstract syntax tree level that results from the parsing.
So I decided I want to align that
and this actually more reasons why we want to align that.
So the first one is fast.
So we want things to be fast.
And so that's shamelessly stolen from the Google website.
The way that cell works, the idea is
that you actually parse one,
store the ST, share the ST across your infrastructure
and then use that to evaluate your expression.
So we want to be able to parse and go
and then send it to Rust and wherever for evaluation.
So yeah, that's the story I was just telling, right?
So Antler has no target.
Antler Rust existed, but abandoned and whatnot.
So fix that.
So again, if you care that exists now,
I'll give many credits at the end of the stock on
why that actually even exists.
So with a conforming parser now,
like the ST that it produces actually
compliant with the ST that the other implementation
produces, you're like, well, we must be good, right?
So this Christmas, I had to excel.
So what do you do? You write code.
And I just decided to open up the interpreter
to be completely, well, it's not entirely yet.
Completely agnostic from the types you saw the beginning.
I actually tell as internally a trade system,
and it doesn't really care that your list is a list, first
there, right? There is a list third trait that itself
is composed of different traits.
So people can actually provide different implementation
of certain types, including the interpreter itself.
When it's example given resolving the macro that you saw
at the beginning, this all one that I used,
there's one that, for instance, map a list of strings
to a list of integers, for instance, right?
I don't know on many of you know about run times,
but it's quite a few tricks you can play
if you can control the list that's being mapped
in such a macro.
So, again, seeing things just send up
not as much as a large PRS, the other one,
but so this refactoring that has no impact
on any of the APIs that people have been using so far
ended up in this PR, but it was a good Christmas break.
So, but what am I doing, right?
Why am I doing all those things?
So, one issue that sells the Russ Center
but currently has today is it doesn't really
support what cell calls overloads.
So, did I put some highlighting there?
Yes, I did. Awesome.
So, here what we're doing is we're writing a quick program
that, and what we're trying to do is add a size function
to support a size function, right?
The problem that we have with this is that size
exists on containers, right?
So, on collections. In the case, here we're creating an array
with one and two.
A 64 in them, and that should return to, right?
So, if you execute that, that's actually going to fail now
because the right-hand side of the equal equal operator
will say, well, I don't know how to solve that
because your function expects a i64.
So, what you did is you overload the size function
that the default context comes with.
And so, back again on this graph, if you pay attention,
there is this yellow thing that says check.
Check is a very interesting.
It takes you ST in and applies many tricks on that
ST, including ending up transforming it.
Example given for making sure that those function exists.
So, now I can make sure that when somebody
calls size, that size function exists.
One is being called on a proper types, two.
Three, internally, you can do, you can avoid
resolving the dynamic dispatch.
You can now do it at check time.
I know the left-hand side was the one on the array, right?
So, we're coming in on the array, it's that function.
It's the same name, but I don't need to do a
more thick method called resolution, right?
I can know what we're talking about and be very quick
at evaluation time.
So, the check phase is something that we don't have right now.
And probably with the API that you saw,
it's going to be somewhat awkward at the very least.
You've right now solved it in a non-breaking way, right?
All these other things I've done that have not changed
any APIs, other than possibly the cell,
but now the cell is being parsed correctly.
Because what we're trying to do today,
I did put some highlighting.
So, again, what you saw before this program
compile is just nice APIs, but so, what happens
internally is you create a parser, you parse your thing,
hopefully that worked out, you create a context.
And so, before we were calling like resolve right away
passing that context, right?
The context actually can play sort of two concepts,
like the dysfunction registry and the variables.
And so, that's a bit of a problem.
So, that could be one, like let's say check there
as a magic function, wherever it lives.
We don't care, right?
That's all hypothetical, that doesn't exist.
So, we will need to fix those things in a now
breaking way.
So, I was trying to get all that stuff done,
what I called CDD.
It's a conference-driven development.
Yeah, it wouldn't necessarily recommend it
as a whatever.
So, I failed, I didn't get to get that done by yesterday.
I was hoping to release the new thing here.
But so, that didn't happen.
So, that's the road ahead and where we are
with cell rust, right?
So, and by the way, and by the way.
So, I'm wrapping up this overload problem.
Introduce.
Then we want to introduce the type checking,
making sure that now we can sort of guarantee
that nothing will ever go wrong.
Start implementing all the perf stuff,
which by the way has been going on already in parallel
with my den, vowel, all the things.
Some other contributor has been starting doing
like performance-driven work, but because some of the
endopinings have to change sort of put you in the
weird position.
And then eventually get to the protobuff and well-known
types support a transparent support.
So, that's effectively sugarcoding, right?
Again, the API, so that you can pass in
JRPC message that you get from somewhere
and just inject it in the context and we figure everything
out for you.
So, that's all the fun stuff.
If any of that sounds fun to you,
I think you should come and talk to me.
So, this is the legal disclaimer.
None of what we have today would exist
with a bunch of those people listed here,
and I think they all deserve credits.
So, a cleric is the person who invited me
as a second maintainer on the project.
Tom, I think as a person who started this many years ago,
Adam is actually a colleague of mine who implemented the
support, the optional support that you saw previously.
John Howard, if you're an Istio user,
you might know that person has been like
awesome in terms of contributions and making sure
that we become more performant.
So, the antifore rust stuff has happened with
the consenting base project.
Ken has been teaching me so much about
antler and parsers that I didn't know about,
and now I know, I don't know if you're about that part,
but at least we got it working
without this help, I wouldn't have been able to
fix the antifore rust crate.
Yeah, and then especially thanks to a person who wrote this
present term, I can run presentation.
My terminal, I think that's pretty geeky.
I think you should do it too,
somebody else do it the four cell ops.
So anyway, so that's that.
If you want to know more, sell dash rust on
GitHub, Quadron DiO's the project that I work on
if you have any interested in that.
So, thank you so much for listening to my nonsense
and if there are any questions.
Thank you.