expr-lang / expr

Expression language and expression evaluation for Go
https://expr-lang.org
MIT License
6.35k stars 408 forks source link

Feature request: allow multiple expressions in a single program #697

Open vmihailenco opened 3 months ago

vmihailenco commented 3 months ago

TLDR The following program should be a valid expr:

let x = 42
let y = 42
x * y

It should work like Ruby, where everything is an expression and the last expression is used as the result. Given that it works fairly well for Ruby, I guess expr-lang can be modeled just like it.

Currently what we do in Uptrace transformations, is just split the multi-line expressions into individual programs and then run them one by one. It works so far, but variables don't survive between programs and the performance is probably sub-optimal since each program requires a separate VM.

I believe OpenTelemetry does the same with multi-line OTTL so they would probably benefit as well.

A more realistic example what multi-line expressions can achieve:

let val = split(attr("foo"), "-")
setAttr("xxx", val[0])
setAttr("yyy", val[1])
deleteAttr("foo")
antonmedv commented 3 months ago

Well, actually this is possible right now as well if ; added at the let ends:

let x = 42;
let y = 42;
x * y

We can improve lexer and allow \n to be treated as ;.

vmihailenco commented 3 months ago

Well, actually this is possible right now as well if ; added at the let ends:

Yes, I know, but the real program looks more like this:

let val = split(attr("foo"), "-")
setAttr("xxx", val[0])
setAttr("yyy", val[1])
deleteAttr("foo")

I guess I can rewrite it like this, but it is not as readable and debuggable:

let val = split(attr("foo"), "-"); setAttr("xxx", val[0]) && setAttr("yyy", val[1]) && deleteAttr("foo")
antonmedv commented 3 months ago

I see. So, this request to add statements to Expr. I think this is nice to add via option: expr.AllowStatments().

vmihailenco commented 3 months ago

So, this request to add statements to Expr.

Maybe, but I explicitly say that "everything is an expression" so :) If we take switch in account, would it be a statement or an expression? I believe it should be an expression or it probably would not fit into the existing purpose of the language.

And if switch is an expression, why a function call or an assignment should not be?