-
Notifications
You must be signed in to change notification settings - Fork 9.5k
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
lang/funcs: "one" function #27454
lang/funcs: "one" function #27454
Conversation
Codecov Report
|
What's the motivation behind |
One other name I considered was output "example" {
value = only(aws_instance.example[*].private_ip)
} The fact that this function doubles as an assertion that there should never be more than one item in the collection -- along with a general desire to keep it short/concise for common use -- is what ultimately led me to |
🤔 If we're looking to bikeshed the name of this function, I might suggest I feel ambivalent about the function but in the end agree that this is a common pattern worth simplifying for users. |
I'd prefer the clarity of having the "or" clause in |
On a related note, there are some instances where I do:
Would be great if these type of expressions can be simplified too. If there was an Anyways, just some thoughts, not sure if this might be considered 🙂 |
Thanks for that feedback, @ktham. I think the treatment of dynamic "foobar" {
for_each = var.some_optional_string[*]
content {
foo = each.value
}
} The above will work only if the "empty state" for your If we were designing the language anew today then making nullability explicit is something I would consider, but I think it's too late in the life of the Terraform language for such a fundamental type system change now. Instead, I think we're stuck with the compromise of improving the ergonomics of the existing "everything is nullable" model, which this |
Ah! Oh I see, I hadn't caught that when initially reading your issue description 🤦 , my bad! That is neat, I didn't realize that the
(EDIT: Ah, nevermind, I saw that you added this tidbit in your doc page for the
Got it, makes sense 👍 |
f541185
to
dc608f9
Compare
Oh, whoops! We had a bit of debate about whether to move forward with this function and what it ought to be called and so I ended up forgetting to return to it after some other work. I only remembered it today when I was helping someone elsewhere who had encountered a situation like this function is intended to deal with. After the discussion here and some discussion internally I tried out a few different function names to see which ones seemed to (subjectively) "work best". The most compelling ones were Unfortunately we have a long-standing convention that function names are just strings of letters/digits with no word separators, and so that often hampers what would otherwise be nice and descriptive names. That seems to be the case with these options too, where too many of these words start and end with vowels, making the result feel like a soup of letters that it's unclear how to parse: "zeroo rone"? "on eor null"? 🤯 With that said, despite spending some time preferring This was originally intended to land for v0.15, and although it's now missed the window for v0.15-rc1/rc2 the addition of a function is orthogonal enough to everything else that it's relatively low risk to add in here. Since it was already reviewed and approved as |
In the Terraform language we typically use lists of zero or one values in some sense interchangably with single values that might be null, because various Terraform language constructs are designed to work with collections rather than with nullable values. In Terraform v0.12 we made the splat operator [*] have a "special power" of concisely converting from a possibly-null single value into a zero-or-one list as a way to make that common operation more concise. In a sense this "one" function is the opposite operation to that special power: it goes from a zero-or-one collection (list, set, or tuple) to a possibly-null single value. This is a concise alternative to the following clunky conditional expression, with the additional benefit that the following expression is also not viable for set values, and it also properly handles the case where there's unexpectedly more than one value: length(var.foo) != 0 ? var.foo[0] : null Instead, we can write: one(var.foo) As with the splat operator, this is a tricky tradeoff because it could be argued that it's not something that'd be immediately intuitive to someone unfamiliar with Terraform. However, I think that's justified given how often zero-or-one collections arise in typical Terraform configurations. Unlike the splat operator, it should at least be easier to search for its name and find its documentation the first time you see it in a configuration. My expectation that this will become a common pattern is also my justification for giving it a short, concise name. Arguably it could be better named something like "oneornull", but that's a pretty clunky name and I'm not convinced it really adds any clarity for someone who isn't already familiar with it.
dc608f9
to
b99a87a
Compare
@apparentlymart - I stumbled on this for the first time today in the release notes for 0.15.0 - exciting work! This simple update, I think, goes a long way to simplify a very common pattern terraform, and makes things very easy read at the same time! Congrats on the release, and thanks!! |
I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further. |
In the Terraform language we typically use lists of zero or one values in some sense interchangably with single values that might be null, because various Terraform language constructs are designed to work with collections rather than with nullable values.
In Terraform v0.12 we made the splat operator
[*]
have a "special power" of concisely converting from a possibly-null single value into a zero-or-one list as a way to make that common operation more concise.In a sense this
one
function is the opposite operation to that variant of splat: it goes from a zero-or-one collection (list, set, or tuple) to a possibly-null single value.This is a concise alternative to the following clunky conditional expression, with the additional benefit that the following expression is also not viable for set values, and it also properly handles the case where there's unexpectedly more than one value:
Instead, we can write:
As with the splat operator, this is a tricky tradeoff because it could be argued that it's not something that'd be immediately intuitive to someone unfamiliar with Terraform. However, I think that's justified given how often zero-or-one collections arise in typical Terraform configurations. Unlike the splat operator, it should at least be easier to search for its name and find its documentation the first time you see it in a configuration.
My expectation that this will become a common pattern is also my justification for giving it a short, concise name. Arguably it could be better named something like
oneornull
, but that's a pretty clunky name and I'm not convinced it really adds any clarity for someone who isn't already familiar with it.