spec: clarify wording around the dollar `$` being an invalid identifier
What version of CUE are you using (cue version)?
$ cue version
cue version v0.0.0-20240524171931-819223954d3b
go version go1.22.3
-buildmode exe
-compiler gc
DefaultGODEBUG httplaxcontentlength=1,httpmuxgo121=1,tls10server=1,tlsrsakex=1,tlsunsafeekm=1
CGO_ENABLED 1
GOARCH arm64
GOOS linux
vcs git
vcs.revision 819223954d3b61532a7451ef68cd997cd22824ee
vcs.time 2024-05-24T17:19:31Z
vcs.modified false
cue.lang.version v0.9.0
Does this issue reproduce with the latest release?
Yes
What did you do?
Read the spec.
Under the "Identifiers" (as of section of the spec it reads:
Identifiers name entities such as fields and aliases. An identifier is a sequence of one or more letters (which includes
_and$) and digits, optionally preceded by#or_#. It may not be_or$. The first character in an identifier, or after an#if it contains one, must be a letter. Identifiers starting with a#or_are reserved for definitions and hidden fields.
As of today, a naked $ has no special meaning, unlike _.
With _ we cannot used it as a label:
_: "test" // cannot use _ as label
With $ we can:
$: "test" // ok
This issue exists to clarify the wording of the spec. If $ is indeed special then we should:
- clarify what it will/might be used for
- move to make it an invalid label
If it is not special then we should fix the spec.
What did you expect to see?
Clarity on whether $ is a valid identifier, consistent with the behaviour of CUE.
What did you see instead?
The spec saying it's special whilst the implementation suggests otherwise.
cc @marcellanz
I believe this falls under the TODO category; https://review.gerrithub.io/c/cue-lang/cue/+/531168 added a commented out test case as follows:
// TODO: disallow dollar as label? This is according to the spec, but it
// will be a breaking change and $ was reserved for referring to the root of
// a file, which we very likely will never implement.
// disallowDollarAsLabel: {
// $: 1
// }
I cannot find any reference to $ being reserved for any purpose in the past. Perhaps it was an idea that Marcel had a while back, but it never got implemented in the spec or code.
FWIW I see the "It may not be _ or $" sentence as just a typo; it should just be "It may not be _." instead.
I don't think that $ has any special meaning at all.
@rogpeppe I do not think it was a typo. See the TODO that Marcel added which I reference in my comment above.
The spec disallowed $ to reserve this identifier for special purposes. For instance, some configuration languages reserve it to refer to the root of the file. Some JSON query languages use $ to refer to the "current value".
So there was a reason for the spec to disallow this, and the fact that the implementation does not enforce this restriction could be seen as a bug.
That said, making it easy to refer to the root of a file is generally a very bad idea. So we are very unlikely to ever want to support that, and if we do, we could come up with something else.
Similarly, we will probably not use $ to refer to the current value in the query extension.
Generally, though, to avoid confusion, I would argue it is generally inadvisable to use "$", especially in some commonly shared module, as it may be confusing to users.
All in all, I would suggest we reserve $ for special purposes at least until CUE reaches v1.
All in all, I would suggest we reserve $ for special purposes at least until CUE reaches v1.
As from my initial contact with this in Discord/Slack: we use this extensively for referring local scope in large amount of configuration, while we decide what this will be. Most of the times to access some context we conjunct into definitions, without explicitly to define them but have it in access: $.ctx.stage said context is part of an object and known to able to be resolved – while saying this, using $ at least as a user, lifts certain mental load to distinguish a character like $ to a name or symbol that for sure could be chosen for it.
I'm sure there is an another way to do its, while not language expert, it
we use this extensively for referring local scope in large amount of configuration, while we decide what this will be
@marcellanz thanks for the data point.
Just to confirm, are you suggesting that we should allow $, or simply observing that given the disagreement between the spec and the implementation, your usage has grown despite the spec?
As an alternative, you could use _$, recognising that there is effort on your part in refactoring.
recognising that there is effort on your part in refactoring.
Although I will note that if we fix the implementation to line up with the spec here, we would look to provide a cue fix to automate this change.
Just to confirm, are you suggesting that we should allow $, or simply observing that given the disagreement between the spec and the implementation, your usage has grown despite the spec?
We found the use of '$' just as a convenient way to express the an identifier (just as a user) the local scope. It made sense for our use cases and we use it for that convenience, where the convenient part is its visually/mentally easy to spot and make the connection what it is.
As an alternative, you could use _$, recognising that there is effort on your part in refactoring.
That's for sure acceptable – how would I disagree. The symbol is handy and might be used by others for other things.
@marcellanz - thanks for the response (I just edited it lightly to separate your response from a quote of my reply)
We found the use of '$' just as a convenient way to express the an identifier (just as a user) the local scope.
Makes total sense - it's a very nice visually distinct way of doing so.
The symbol is handy and might be used by others for other things.
Indeed, and that's the risk/cost of such a change!