Feature request: allow multiple expressions in a single program
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")
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 ;.
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")
I see. So, this request to add statements to Expr. I think this is nice to add via option: expr.AllowStatments().
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?
Statements support(or using ; to simply discard expression output) would be very helpful indeed. I'm currently having the following usecase:
assert(status_code == 0);
assert(status_message == "");
// normal expr stuff
1 + 1
Currently it's possible to work around this by
- Making
assertreturn anany.
- func assert(condition bool)
+ func assert(condition bool) any // always returns nil
- change the assert statement to assignments:
let _s1 = assert(status_code == 0);
let _s2 = assert(status_message == "");
// normal expr stuff
1 + 1
I’m working on adding multi-expressions available.
Done! Not this is possible to do in Expr! Expr support multiple expression separated by ;
let x = foo();
asd(x);
check();
x + 1