-
-
Notifications
You must be signed in to change notification settings - Fork 415
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
Feature request: UNKNOWN type #666
Comments
Those unknow for the run step? |
@antonmedv Yep. Let's say, each The problem is that I want to chain some This problem is quite unsolvable, but at least I want to calculate the ceiling of price for these downloads. The problem seems to be a hard one because the ub for each opcode that returns boolean. For example, is |
I actually just finished a PR which brings What you can do to estimate upper bound is using visitor traverse AST of the expression and count how many times download() function were called. Take a look on, for example, on visitor which collects names of all used variables: https://expr-lang.org/docs/visitor |
@antonmedv Can you please share example to use these unknowns? Unfortunately counting "download" function in program code is not giving any information because it can be behind "if" not used branch (so no need to count it) or inside "map" (which can be called multiple times) |
I hope add a dynamic type, this expression is invalid as follows: out, err := expr.Compile(`value1 + value2`)
// err: invalid operation + (mismatched types string and int)
// | name + age
// | .....^ I hope add a option to enable dynamic support ( backward compatible while disable dynamic), program, err := expr.Compile(`value1 + value2`, EnableDynamicType())
// ok
output, err := expr.Run(program, map[string]interface{}{
"value1": 1,
"value2": 2,
})
// ok, err == nil and output = 3
output, err := expr.Run(program, map[string]interface{}{
"value1": 1.1,
"value2": 2,
})
// ok, err == nil and output = 3.1
output, err := expr.Run(program, map[string]interface{}{
"value1": "1",
"value2": "2",
})
// ok, err == nil and output = 12
output, err := expr.Run(program, map[string]interface{}{
"value1": 1,
"value2": "2",
})
// panic, err != nil |
@Virviil those are internal type checker structs. I'm actually working on something very similar: estimated expression costs. You can assign a cost for each field/array/function and Expr will calculate estimated cost:
Estimated cost will be: Maybe it makes sense to add "units" to this system, so we can calculate in term of different units.
|
I want to perform some dry-run calculations with dirty custom functions.
Sometimes i don't know the value that will be in real run, but i know that this value will be.
I cant use
nil
or any another value, because it can change the attitude of an expression.For example
foo ?? download(bar)
, when foo is nil will force to downloadbar
while it is not what's desired if foo is definitely known to be not nilMy proposal is to add type UNKNOWN and UNKNOWN_NOT_NIL, which will during computation propogate it's unknoness. These values can be used as any other type. At the same time, calling dirty custom functions can check if the value is UNKNOWN and perform accordingly.
Predefined functions, while being pure, can just return UNKNOWN as there result. Important to calculate UNKNOWN <-> UNKNOWN_NOT_NIL conversions properly.
This change is fully backward compatible, because not giving any UNKNOWN value to env will just work as is.
The text was updated successfully, but these errors were encountered: