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

Prototype: Namespaced functions #535

Closed
wants to merge 4 commits into from
Closed

Conversation

apparentlymart
Copy link
Contributor

This introduces a new syntax which allows function names to have namespace prefixes, with the different name parts separated by a double-colon :: as is common in various other C-derived languages which need to distinguish between scope resolution and attribute/field traversal. (For example: C++, Rust, Ruby, and Perl.)

Because HCL has separate namespaces for functions and variables, we need to use different punctuation for each to avoid creating parsing ambiguity that could be resolved only with infinite lookahead.

We cannot retroactively change the internal representation of function names to be a slice of names without breaking the existing API, and so we instead adopt a convention of packing the multi-part names into single strings which the parser guarantees will always be a series of valid identifiers separated by the literal :: sequence. That means that applications will make namespaced functions available in the EvalContext by naming them in a way that matches this convention.

This addition should change nothing for any existing applications that only place single-identifier names in the EvalContext function table, but allows applications to begin defining such functions when they are ready, with whichever namespaces they deem appropriate.

In the modern Go Modules-based toolchain we can avoid the need to globally
install this tool first by running it this way. As a bonus, the toolchain
will also install the version of the module we have specified in go.mod,
thereby locking us in to a particular version until we intentionally
upgrade.

The other third-party generator tools we use here aren't written in Go and
so we can't do the same for those right now, but maybe we'll find a nicer
way to handle those later too.
This introduces a new syntax which allows function names to have namespace
prefixes, with the different name parts separated by a double-colon "::"
as is common in various other C-derived languages which need to
distinguish between scope resolution and attribute/field traversal.

Because HCL has separate namespaces for functions and variables, we need
to use different punctuation for each to avoid creating parsing ambiguity
that could be resolved only with infinite lookahead.

We cannot retroactively change the representation of function names to be
a slice of names without breaking the existing API, and so we instead
adopt a convention of packing the multi-part names into single strings
which the parser guarantees will always be a series of valid identifiers
separated by the literal "::" sequence. That means that applications will
make namespaced functions available in the EvalContext by naming them in
a way that matches this convention.

This is still a subtle compatibility break for any implementation of the
syntax-agnostic HCL API against another syntax, because it may now
encounter function names in the function table that are not entirely
valid identifiers. However, that's okay in practice because a calling
application is always in full control of both which syntaxes it supports
and which functions it places in the function table, and so an application
using some other syntax can simply avoid using namespaced functions until
that syntax is updated to understand the new convention.

This initial commit only includes the basic functionality and does not yet
update the specification or specification test suite. It also has only
minimal unit tests of the parser and evaluator. Before finalizing this
in a release we would need to complete that work to make sure everything
is consistent and that we have sufficient regression tests for this new
capability.
@jbardin jbardin force-pushed the f-functions-namespaced branch from 0a5fcbe to 83c95d2 Compare October 27, 2023 19:05
Add a locals blocks to the terraformlike tests, with normal and scoped
function calls.
@jbardin jbardin closed this Nov 2, 2023
@jbardin jbardin deleted the f-functions-namespaced branch November 9, 2023 19:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants