Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added deserialization example to Bonsai serialization sample #125

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

WhitWaldo
Copy link

There's a really robust example with explanation about how to use Bonsai for expression serialization, but it ends without an explainer of how to deserialize the expression to use on the other side. Added a brief example at the bottom to illustrate this.There's a really robust example with explanation about how to use Bonsai for expression serialization, but it ends without an explainer of how to deserialize the expression to use on the other side. Added a brief example at the bottom to illustrate this.

@HowardvanRooijen
Copy link
Contributor

First of all, thank you very much for this contribution, and for exploring and expanding upon the examples in the notebooks.

I worked through your new example and made a few tweaks, which I hope makes it a bit more understandable. Firstly, I broke it into two cells, the result of the first cell allows you to pretty print out the bonsai tree, so you can understand what's happening in this step.

using System.Linq.Expressions.Bonsai.Serialization;

BonsaiExpressionSerializer ser = new();

//Serialize the expression below
Expression<Func<List<int>, int>> expr = x => x.Max();
ExpressionSlim slim = expr.ToExpressionSlim();
string json = ser.Serialize(slim);

//Pretty Print the JSON Bonsai Expression
string pretty = print.Visit(Json.Expression.Parse(json));
Console.WriteLine(pretty);

And then in the second step, I explicitly name the types:

//Deserialize and calculate a result
ExpressionSlim deserializedSlim = ser.Deserialize(json);
Expression<Func<List<int>, int>> deserializedExpression = (Expression<Func<List<int>, int>>)deserializedSlim.ToExpression();
Func<List<int>, int> exprDelegate = deserializedExpression.Compile();
List<int> data = new() { 1, 2, 3, 4, 5 };
int result = exprDelegate(data); // 5

Console.WriteLine(result)

I've also used the new() syntax to reduce the type duplication once you don't use var.

@WhitWaldo
Copy link
Author

WhitWaldo commented Oct 18, 2022

Both changes make sense to me. I typically prefer var, but found it trickier to follow in the context of the specific Expression<Func<>> mapping relevant to each of these examples, but new() is an excellent improvement to improve readability.

I think there's a great opportunity to expand further and demonstrate the expression binding as well outside of just the context of the Query Engine as it removes that need to expressly cast the Expression to one type or another, but I'll reserve that for a future PR when I've understood it better myself.

@HowardvanRooijen
Copy link
Contributor

I thought it was quite good to be clear about the journey of:

ExpressionSlim  -> Expression<Func<List<int>, int>> -> Func<List<int>, int> -> int

It just felt a little less "magic", even if you'd use var once you grokked what was going on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants