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

Exhaustive eval for map/list/object evaluation #1118

Open
3 tasks done
mneff-roblox opened this issue Jan 31, 2025 · 3 comments
Open
3 tasks done

Exhaustive eval for map/list/object evaluation #1118

mneff-roblox opened this issue Jan 31, 2025 · 3 comments

Comments

@mneff-roblox
Copy link

Feature request checklist

  • There are no issues that match the desired change
  • The change is large enough it can't be addressed with a simple Pull Request
  • If this is a bug, please file a Bug Report.

Change
Similar to how exhaustive eval of and merges the unknowns, I think there should be exhaustive eval for these types.

	// If any argument is unknown or error early terminate.
	for i, key := range m.keys {
		keyVal := key.Eval(ctx)
		if types.IsUnknownOrError(keyVal) {
			return keyVal
		}
		valVal := m.vals[i].Eval(ctx)
		if types.IsUnknownOrError(valVal) {
			return valVal
		}
	}

You can see in the map code that the first unknown or error hit short circuits and returns, but if I'm building a map out of two unknowns, it would be nice for this to evaluate to the merging of those two unknowns when using exhaustive evaluation. Same applies to list and object.

Example

{"foo": a, "bar": b}
evaluates to
a (4) (*types.Unknown)

Desired output should be the same as
a && b
evaluates to
b (2), a (1) (*types.Unknown)
@TristonianJones
Copy link
Collaborator

TristonianJones commented Jan 31, 2025

Hi @mneff-roblox, thanks for filing the issue.

Usually an unknown in the map/list/object prevents accessing that object unless you're using a non-strict function. The position of CEL is to be as conservative as possible with intent. If part of the map is unknown then functions like size aren't guaranteed to be accurate.

Is there a specific function that you'd like to see a more detailed unknown from? Or do you specifically mean for literal construction of map / list / object? In those cases we tend to terminate early since we know the value can't be successfully built, but I can see your position.

Cheers,

-Tristan

@TristonianJones
Copy link
Collaborator

@mneff-roblox If you'd like to try updating the exhaustive eval for createList, createMap, createStruct that's probably pretty useful now that I've had a little time to think about it. Most of this work would be implemented in the interpreter/planner.go and interpreter/decorators.go such that you would replace the standard evaluation step with an exhaustive one.

@mneff-roblox
Copy link
Author

Is there a specific function that you'd like to see a more detailed unknown from? Or do you specifically mean for literal construction of map / list / object? In those cases we tend to terminate early since we know the value can't be successfully built, but I can see your position.

Yes, I mean specifically for literal construction. The goal is to just have all unknowns in an expression that affect the final result bubble to the top unknown. (Goal is to use this to run data loading)

I'll submit a PR. Seems like just a matter of routing to new evalExhaustiveMap / List / Obj in interpreter/decorators.go and writing those methods in interpreter/interpretable.go. Not sure what would be changed in interpreter/planner.go but can be discussed on the PR.

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

No branches or pull requests

2 participants