-
Notifications
You must be signed in to change notification settings - Fork 203
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
Proposal: add aliases to Alloy syntax #154
Comments
I'm in favor of this. This would also be very useful for #156.
I think this is a reasonable restriction for now, but I imagine in the future it'd be useful to have component-scoped aliases. It would help you reuse expressions without having to worry about colliding with the name of an alias used outside of the components. |
I am hesitant to add a new language-level concept at the top level. Would you have any thoughts on using a component to begin with and seeing how that goes?
We would organically get to show the values in the UI without making changes, and it's not quite as terse as native aliases but also not overly verbose. Also requires the least amount of change. |
@rfratto I agree it might be useful. The only thing I'm concerned about would be shadowing, but it's not something unique to Alloy syntax.
@mattdurham I was also on the fence about this. My main concerns were two Do you think these are important-enough to make us do this at a language level? |
Specifically, an alias can't conflict with the namespace of a component (You can't have an alias named Should aliases be prevented from colliding with any registered namespace? For example, can you name an alias |
I am for this. I think it could help a number of things that would get repeated in complicated fan-out scenarios. How would they interact with modules? I am assuming you could pass them into modules (or at least the value they evaluate to), but what happens if a module defines its own aliases internally? Presumably they are namespaced so there is no possibility of corrupting the root aliases. |
alias component with an address can be even better so if you have multiple block configured across configuration their 'fqdn' will never conflict
would make it easier to reduce the chance of conflicts and you will get the validation for free as components already cannot reuse the same address... |
One of my concerns is how we document this in a clear way. The way this works is that we introduce a syntax-level concept (aliases), but Flow has restrictions on where aliases may appear. If we can't find a clear way to document this, maybe it's worth finding a way to support aliases inside of blocks (i.e., components) to make it less confusing for users. |
I know the subject here is "expressions", but I'm wondering if it would make sense to alias blocks themselves as well? For example, I have a number of |
This issue has not had any activity in the past 30 days, so the |
The Alloy syntax may benefit from being able to define references to values so that they can be reused and shared across different parts of a configuration file.
These aliases can be helpful to reducing deduplication when repeating the same values or expressions when writing complex configuration and give a degree of certainty that all references are updated in one go.
At the same time, if overused, they can make a configuration file hard to read by hiding the actual values under one or more layers of indirection. For this reason, aliases should only be used in moderation, in situations where a single value or result is used in many places, or that should only be changed from a central place to help maintain a readable configuration file.
Proposal
I propose that we change the Alloy syntax to allow a new top-level statement that aliases, or assigns a name to an expression, so that it can be reused multiple times throughout a configuration file.
An alias should be nothing more than a shorthand to the matching expression, and would use pass-by-value semantics.
Defining aliases
Defining aliases can make use of the
let
keyword plus the alias name on the LHS, while the RHS must be any valid syntax expression.Such definitions can only appear as top-level syntax statements.
Each line can only define a single alias.
Aliases must be valid syntax identifiers.
Alias definitions cannot be recursive.
Aliases cannot conflict with any component or top-level block names.
The expression concept in Alloy syntax should now be changed to include references to aliases, similar to component exports.
Using aliases
Aliases can only be used in the context of a syntax expression.
My initial proposal is that we wouldn’t introduce any new symbols or a special way for referring to aliased values (for example, avoid having
$name
,locals.name
orvals.name
) but that they should be used as an IdentifierExpr, much like components exports do.Usage
Here’s how a configuration file that makes use of aliases could look like.
The first alias is a static value that can be reused throughout the configuration file. The second and third aliases are the results of expressions that make use of the Alloy syntax’s standard library and component exports.
Implementation
Aliases can be stored along component arguments and exports in the controller’s valueCache under a global NodeID.
We can either use that NodeID to detect dependencies to one or more components similarly to what we do for
ConfigNode
and update the result of expressions, or simply evaluate the aliased expressions after the entire graph is updated.Limitations - Concerns
One limitation of this proposed solution is that since aliases are the results of an expression, they cannot store blocks. Two features that could benefit from allowing aliases to represent blocks would be to reuse the same rules in multiple relabeling components, or to conditionally apply processing stages in loki.process once #157 is implemented.
Another limitation is that the pass-by-value semantics proposed here may include memory usage in cases where large values are passed around in multiple aliases.
Feature Naming
I’m partial to the name alias for this feature, since it best captures the idea of it being just another name for referring to an expression. Considering some alternatives:
Variables usually point to something that can be updated, rather than a shorthand for an already-defined expression.
Constants on the other hand point to something immutable, that is not the case with syntax expressions.
Stored values strikes a balance as a term, but is more verbose than I’d like.
Alternatives
Of course, one idea would be to "do nothing" and reason that it is easier for users to always write expressions in full.
Having some experience in writing configurations in these past months, I feel that this feature would be quite useful if used with care.
Another idea would be to avoid introducing aliases on a language level but have an
aliases
component or configuration block instead, where all shorthands would be grouped together. Personally, I think this somewhat takes away from the feature's power by making it harder to quickly define locally-used shorthands, as well as has the potential of wrongly propagating an unhealthy status (eg. mistyping an expression should not render the entire set or aliases as 'unhealthy'.)The text was updated successfully, but these errors were encountered: