Expression evaluation not implemented correctly

This may have been brought up before so I apologize if it has. When is expression evalutation implement incorrectly\differently than every other language.

What I mean by this is take the following expression:

localVar = var.input != null && length(var.input) > 0 ? [“_enable”] :

This is a perfectly formed expression by any other languages standards, if var.input is not null and its length is greater than 0 then set localVar to [“_enable”] otherwise set it to . However in Terraform this is not the case as the above returns the error:

│ │ while calling length(value)
│ │ var.input is null

│ Invalid value for “value” parameter: argument must not be null.

This must mean Terraform ignores the logical operators and evaluates every part of the expression and then it must evaluate the results of each expression part using the logical operators. No other language I know of works like this and results in not only errors like above but also it slows down execution as parts of expressions are been evaluation in situations when they dont need to be.

Whilst short circuit evaluation of Boolean operators may be fairly common, you exaggerate by calling not doing it incorrect.

Short-circuit evaluation - Wikipedia documents choices for and against by various languages - and yes, more short circuit than not, but it’s hardly unanimous.

In any case, Terraform’s behaviour is documented: Operators - Configuration Language | Terraform | HashiCorp Developer

I don’t know why the authors of Terraform made this choice. I wonder if it might relate to Terraform’s automatic construction of dependencies between blocks, based on attribute references, and wanting evaluation to be consistent with dependency deduction, in regards to pieces of the expression used (always all of it).

I’m any case, your use case can be addressed with something like try(length(var.input), 0) > 0

Yes i was aware i could address it using a try however this is a bad programming practice as your are using errors as decision based logic, throwing errors in most languages is an expensive operation therefore should be used to make decisions.

I dispute your assertion that this is bad practice. It’s literally what the Terraform try function was created for.

In compiled languages which must switch to a significantly different method of controlling program flow, yes. Have you evidence to support applying this broad generalisation to an interpreted expression language which is doing something only slightly similar to conventional exception handling?

Anyway, if you feel like it you could just set a default for var.input so that it will never be null.