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

chore: refactor EvaluationContext #235

Merged
merged 4 commits into from
Jun 28, 2023
Merged

Conversation

jaspervdj-snyk
Copy link
Collaborator

  • I wanted to make NewEvaluationContext take an options struct, so we could more easily add parameters without breaking call sites. Since this options struct ended up being the context itself, I removed NewEvaluationContext for now...

  • I tweaked the interface of functions, so all functions have the same shape.

  • Adjusted the visibility of Function/EvaluationContext so in principle callers can add their own functions

 -  I wanted to make NewEvaluationContext take an options struct, so we could
    more easily add parameters without breaking call sites.  Since this options
    struct ended up being the context itself, I removed `NewEvaluationContext`
    for now...

 -  I tweaked the interface of functions, so all functions have the same
    shape.

 -  Adjusted the visibility of Function/EvaluationContext so in principle
    callers can add their own functions
@jaspervdj-snyk jaspervdj-snyk requested a review from a team as a code owner June 28, 2023 15:45
@jaspervdj-snyk jaspervdj-snyk requested review from ricardo-snyk, craigfurman and a team and removed request for a team June 28, 2023 15:45
Copy link
Contributor

@craigfurman craigfurman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving because I have no objections to this, but I'm not understanding from the context here why these changes are improvements. I'm relatively inexperienced on this project of course, and I'm sure there's a good reason, but it would be good to see that in the commit message or elsewhere! 🙏

"concat": concatImpl,
"resourceGroup": resourceGroupImpl,
},
type Function func(e *EvaluationContext, args ...interface{}) (interface{}, error)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know you called this out in the commit message (all functions have the same shape) but why? I'm not quite seeing what it buys us.

This is super speculative, but having one eye on a future multi-pass parser/interpreter, there are some functions we won't be able to evaluate at non-final passes. For example, we could evaluate calls to parameters() and concat() in variable definitions (albeit probably returning a stub from parameters() given that we don't have "real" deployment context), but we can't evaluate resourceId before we've built the resource set.

Having a difference in function signature for these functions that depend on state other than their args made that distinction clear and (this is the speculative part) could possibly help us partition functions into which pass they are available in if/when we build that. This certainly isn't something I'm clinging strongly to, and I'm happy to wait until we actually tackle that work, and will likely come up with a code organisation pattern that suits us then - I just thought it was worth stating now, as a non-blocking possible reason to consider. 🙏

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is all a bit speculative--

In general, having the same shape for these allows you to manipulate them a bit more easy, e.g. have helpers like func memoize(f Function) Function.

On the other hand, it is useful to see which function depend on additional context. it's a bit of a trade-off though, does a function like variables() depend on EvaluationContext or do we go even more granular and depend on Variables only?

Tying them to the evaluation pass seems sensible, but in that case we'd want to propagate that type to the context, and I'm not really sure if Go's generics will make that nice...

As a middle way, I'll:

  • update the function implementations to not take any context if they don't have to
  • keep the Function type like this because it accurately describes "everything" a function can do which is useful

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think since we're both speculating, please feel free to adjust the types to whatever makes our lives easier today. We can always change them when we confront multi-pass!

funcs map[string]armFnImpl
DiscoveredResourceSet map[string]struct{}
Variables map[string]interface{}
BuiltinFunctions map[string]Function
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
BuiltinFunctions map[string]Function
Functions map[string]Function

If the idea is for callers to extend the function set, wouldn't it just be Functions?

But also, why is it desirable for callers to be able to extend the function set? Is this package not really just an internal dependency of pkg/input?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did the rename.

I wasn't necessarily thinking about extending it; more the other way around: restrict functions that aren't available in certain passes or replace them by dummies.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I think I see. Do you mean that in the parent package, in arm.go, we might in a multi-pass future add functions to the context that can now be meaningfully evaluated after passes? That makes sense if so.

@jaspervdj-snyk jaspervdj-snyk merged commit 0a06e6b into main Jun 28, 2023
@jaspervdj-snyk jaspervdj-snyk deleted the chore/refactor-eval-ctx branch June 28, 2023 16:27
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