Skip to content

Commit

Permalink
docs/concept: new FAQ: list arithmetic ops removal
Browse files Browse the repository at this point in the history
This adds an FAQ guide that explains the removal of list arithmetic
operators ("+" and "*") from CUE v0.11 and later. It requires the tip of
cmd/cue, upgraded in an earlier commit, in order to access a version of
`cue fix` that understands how to update the operators.

This guide contains several FIXMEs, which are a product of it being
written before the first 0.11 pre-release is available. They must be
updated and removed before publishing. Several commands are displayed on
the preview's rendered page with `missing.file.cue` arguments, in order
to prompt a failure where the current cmd/cue tip doesn't yet fail. They
must also be updated and removed; probably when the version of cmd/cue
installed earlier in this stack includes the as-yet-unmerged
https://review.gerrithub.io/c/cue-lang/cue/+/1200221.

DO NOT SUBMIT

Closes cue-lang/docs-and-content#178

Preview-Path: /docs/concept/faq/removing-list-arithmetic-operators-v0.11/
Signed-off-by: Jonathan Matthews <[email protected]>
Change-Id: I8d50c273ccedb7cf6ca5295917032d5aa822b413
Dispatch-Trailer: {"type":"trybot","CL":1200357,"patchset":7,"ref":"refs/changes/57/1200357/7","targetBranch":"master"}
  • Loading branch information
jpluscplusm authored and cueckoo committed Sep 2, 2024
1 parent e10cc6c commit b7a5543
Show file tree
Hide file tree
Showing 4 changed files with 606 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
---
title: Removing list arithmetic operators in CUE 0.11
authors: [jpluscplusm]
toc_hide: true
---

{{{with _script_ "en" "HIDDEN: set up access to CUE v0.11 before release"}}}
export PATH=/cues/$CUELANG_CUE_TIP:$PATH
{{{end}}}

In early versions, the CUE language explicitly allowed lists to be used with
the arithmetic operators "`+`" and "`*`".
This feature was removed from the language specification
[several years ago](https://review.gerrithub.io/plugins/gitiles/cue-lang/cue/+/172f0060cd405f30c5873b793e44300e1a3588cb%5E%21/),
and its removal is now being completed in CUE version 0.11.
This FAQ answers some of your questions about what's changed.

All the `cue` commands shown here use the following pre-release version:

{{{with script "en" "cue version"}}}
#ellipsis 1
cue version
{{{end}}}

## What's being removed, and from where?

**The list arithmetic operators `*`<!-- vim* --> and `+` no longer work
in CUE evaluated by the `cue` command and the Go API.**

These operators are affected **only** when used with a list value on their left
or right side - they will continue to work as expected in all other situations
(such as numeric arithmetic and string composition). For example:

{{<columns>}}
**This CUE no longer works:**
{{{with upload "en" "removed behaviour"}}}
-- list-arithmetic.cue --
A: [1, 2, 3] * 2 // Invalid CUE!
B: [1, 2, 3] + [4, 5, 6] // Invalid CUE!
{{{end}}}
{{{with script "en" "removed behaviour"}}}
#FIXME: this will start failing when the site's
#CUE tip is upgraded past
#https://review.gerrithub.io/c/cue-lang/cue/+/1200221
! cue eval missing.file.cue list-arithmetic.cue
{{{end}}}
{{<columns-separator>}}
**This CUE will continue working as before:**
{{{with upload "en" "existing behaviour"}}}
-- numbers-strings.cue --
C: 1 + 2*3
D: 2*"X." + 3*"O.."
{{{end}}}
{{{with script "en" "existing behaviour"}}}
cue eval numbers-strings.cue
{{{end}}}
{{</columns>}}

## Why are list arithmetic operators being removed?

The commit that removed them from the CUE language specification in 2021
[explained the project's reasoning](https://review.gerrithub.io/plugins/gitiles/cue-lang/cue/+/172f0060cd405f30c5873b793e44300e1a3588cb%5E%21/):

{{<quote>}}
List operators are confusing [and] unnecessary.
For instance, is the result of <code>[a,...]+[b,...]</code> open or closed?
What about <code>[a]+[b,...]</code>?
{{</quote>}}

## Why were list arithmetic operators supported until now?

The CUE project takes its compatibility responsibilities to its users
seriously. A capability that's made available in a released version of CUE (as
list arithmetic operators were) shouldn't be removed the instant that it's
deprecated, even though CUE is still pre-version-1.0 and such an immediate
removal might seem generally allowable under
[semantic versioning guidelines](https://semver.org/#spec-item-5).

Some users might have written working, supported CUE that relied on list
arithmetic operators, so the CUE tooling supported it up to and including
version 0.10 -- which was released over 3½ years after the feature stopped
being mentioned.

Enough time has now passed *without* it being mentioned in the CUE language
specification or official documentation that we believe we can safely remove
it, as it's unlikely still to be in use.

## Which versions of CUE don't support list arithmetic operators?

Any release or pre-release of CUE that has a version string which *starts* with
`v0.11` or later does not support list arithmetic operators.

This includes the 0.11 pre-release alphas (`v0.11.0-alpha...`), the 0.11
release candidates (`v0.11.0-rc...`), and all 0.11 patch releases including
`v0.11.0`, `v0.11.1`, and so on. It also includes all releases that come after
0.11, whatever version number they might be given.

## What are the replacements for list arithmetic operators?

In all scenarios:

- the "`*`" list operator can be replaced with
[`list.Repeat()`](/go/pkg/list#Repeat)
- the "`+`" list operator can be replaced with
[`list.Concat()`](/go/pkg/list#Concat) or a nested `for` loop

Here are some examples:

{{{with code "en" "replacements"}}}
exec cue eval replacements.cue
cmp stdout out
-- replacements.cue --
import "list"

// Rewrite "[1, 2, 3] * 2" like this:
A: list.Repeat([1, 2, 3], 2)

// Rewrite "[1, 2, 3] + [4, 5, 6]" like this:
B: list.Concat([[1, 2, 3], [4, 5, 6]])

// Alternatively, rewrite "[1, 2, 3] + [4, 5, 6]"
// like this:
B: [for i in [1, 2, 3] {i}, for i in [4, 5, 6] {i}]
-- out --
A: [1, 2, 3, 1, 2, 3]
B: [1, 2, 3, 4, 5, 6]
{{{end}}}


## Am I affected?

The easiest way to check if your CUE needs to be updated is to use the `cue`
command:

{{{with step}}}

**Use CUE 0.10 to confirm that your CUE is valid.**

Start by installing and using a previous version of the `cue` command that
**does** support list arithmetic operators (such as
[`v0.10.0`](/releases/v0.10.0)) to check that your CUE evaluates successfully.
Use the [`cue vet`]({{< relref "/docs/reference/command/cue-help-vet" >}})
command on your CUE packages and/or files.

If `cue vet` succeeds, continue with the next step.
If it fails, you *must* first fix any problems with your CUE.
{{{end}}}

{{{with step}}}
**Check if CUE 0.11 also validates your CUE.**

Install a version of `cue` that doesn't support list arithmetic operators, such
as FIXME, and run the same `cue vet` command as before. If your CUE contains
list arithmetic operators then you'll see errors like this, and you must update
your CUE:

{{{with upload "en" "cue vet error"}}}
#force
-- list-arithmetic.cue --
A: [1, 2, 3] * 2 // Invalid CUE!
B: [1, 2, 3] + [4, 5, 6] // Invalid CUE!
{{{end}}}
{{{with script "en" "cue vet error"}}}
#FIXME: error after https://review.gerrithub.io/c/cue-lang/cue/+/1200221.
! cue vet missing.file.cue list-arithmetic.cue
{{{end}}}
{{{end}}}

## I *am* affected! How can I fix my CUE?

The [`cue fix`]({{< relref "/docs/reference/command/cue-help-fix" >}}) command
can automatically check and update CUE files, packages, and entire modules.
It updates them to use current CUE syntax. Make sure you use a `cue` command of
at least version FIXME -- earlier versions didn't know how to update the list
arithmetic operators.

{{{with upload "en" "cue fix"}}}
#force
-- list-arithmetic.cue --
A: [1, 2, 3] * 2
B: [1, 2, 3] + [4, 5, 6]
{{{end}}}
{{{with script "en" "cue fix"}}}
#FIXME: error after https://review.gerrithub.io/c/cue-lang/cue/+/1200221.
# The file shown above contains invalid CUE:
! cue vet missing.file.cue list-arithmetic.cue
# "cue fix" is silent when it succeeds:
cue fix list-arithmetic.cue
# The file has been updated to use current CUE syntax:
cat list-arithmetic.cue
# The CUE now evaluates correctly:
cue eval list-arithmetic.cue
{{{end}}}

There are some scenarios that `cue fix` can't help with.

Specifically, `cue fix` can only replace the `*` and `+` list arithmetic
operators when they're used with literal lists, and not references. In other
words, `cue fix` only updates these operators when they are used *directly*
with list values such as `[1, 2, 3]`.

This means that when the following CUE causes `cue vet` to fail, it must then
be updated manually:

{{{with upload "en" "references"}}}
-- references.cue --
x: [1, 2, 3]
y: [4, 5, 6]

A: x * 2 // Invalid CUE!
B: x + y // Invalid CUE!
{{{end}}}
{{{with script "en" "references"}}}
# "cue vet" correctly flags the file as needing an update:
! cue vet missing.file.cue references.cue
# "cue fix" runs successfully ...
cue fix references.cue
# ... but "cue fix" didn't perform the updates:
cat references.cue
{{{end}}}

## Related content

- {{<linkto/related/reference "command/cue-help-fix" >}}
- {{<linkto/related/reference "command/cue-help-vet" >}}
- Standard library: [`list.Repeat()`](/go/pkg/list#Repeat)
- Standard library: [`list.Concat()`](/go/pkg/list#Concat)
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package site
{
content: {
docs: {
concept: {
faq: {
"removing-list-arithmetic-operators-v0.11": {
page: {
cache: {
upload: {
"removed behaviour": "NyfFI1WeUxZKK4dZqorCEcxydRpu9SWntUp+eTFomng="
"existing behaviour": "2gi8XBiobY0f6L+LkggBwMtCPFamg296pRYhmnOFV/c="
"cue vet error": "EL3MinbvU7NEPnlo4FXCcQyl/GirBGcRUa4wooQPMtc="
"cue fix": "Li+e1q5WjG30PqTPtD41YiuXbIGI9oS5AEFDL5q1ASY="
references: "ZnhV9LFkR6McnvVAE8puEQTjpFGf26JpDn0RIzcJALk="
}
code: {
replacements: "uvmUs/Dw7PATeKDTPEQUOBr4B4u7yCtjTD2etmWccB4="
}
multi_step: {
hash: "1EOOUBM897R574V91B9S1B5EGQ1UVU8422RGI6P8TGLC4ODQJVTG===="
scriptHash: "KJBEVVUPS5M0GAIB0LSR0GGULUUFO9FL0P75JLOCRVULNHECT63G===="
steps: [{
doc: ""
cmd: "export PATH=/cues/v0.11.0-0.dev.0.20240902110846-1440b9eae7fa:$PATH"
exitCode: 0
output: ""
}, {
doc: "#ellipsis 1"
cmd: "cue version"
exitCode: 0
output: """
cue version v0.11.0-0.dev.0.20240902110846-1440b9eae7fa
...
"""
}, {
doc: """
#FIXME: this will start failing when the site's
#CUE tip is upgraded past
#https://review.gerrithub.io/c/cue-lang/cue/+/1200221
"""
cmd: "cue eval missing.file.cue list-arithmetic.cue"
exitCode: 1
output: """
could not find file /home/runner/missing.file.cue: stat: stat /home/runner/missing.file.cue: no such file or directory
"""
}, {
doc: ""
cmd: "cue eval numbers-strings.cue"
exitCode: 0
output: """
C: 7
D: "X.X.O..O..O.."
"""
}, {
doc: "#FIXME: error after https://review.gerrithub.io/c/cue-lang/cue/+/1200221."
cmd: "cue vet missing.file.cue list-arithmetic.cue"
exitCode: 1
output: """
could not find file /home/runner/missing.file.cue: stat: stat /home/runner/missing.file.cue: no such file or directory
"""
}, {
doc: """
#FIXME: error after https://review.gerrithub.io/c/cue-lang/cue/+/1200221.
# The file shown above contains invalid CUE:
"""
cmd: "cue vet missing.file.cue list-arithmetic.cue"
exitCode: 1
output: """
could not find file /home/runner/missing.file.cue: stat: stat /home/runner/missing.file.cue: no such file or directory
"""
}, {
doc: "# \"cue fix\" is silent when it succeeds:"
cmd: "cue fix list-arithmetic.cue"
exitCode: 0
output: ""
}, {
doc: "# The file has been updated to use current CUE syntax:"
cmd: "cat list-arithmetic.cue"
exitCode: 0
output: """
import "list"
A: list.Repeat([1, 2, 3], 2)
B: list.Concat([[1, 2, 3], [4, 5, 6]])
"""
}, {
doc: "# The CUE now evaluates correctly:"
cmd: "cue eval list-arithmetic.cue"
exitCode: 0
output: """
A: [1, 2, 3, 1, 2, 3]
B: [1, 2, 3, 4, 5, 6]
"""
}, {
doc: "# \"cue vet\" correctly flags the file as needing an update:"
cmd: "cue vet missing.file.cue references.cue"
exitCode: 1
output: """
could not find file /home/runner/missing.file.cue: stat: stat /home/runner/missing.file.cue: no such file or directory
"""
}, {
doc: "# \"cue fix\" runs successfully ..."
cmd: "cue fix references.cue"
exitCode: 0
output: ""
}, {
doc: "# ... but \"cue fix\" didn't perform the updates:"
cmd: "cat references.cue"
exitCode: 0
output: """
x: [1, 2, 3]
y: [4, 5, 6]
A: x * 2 // Invalid CUE!
B: x + y // Invalid CUE!
"""
}]
}
}
}
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package site

content: docs: concept: faq: "removing-list-arithmetic-operators-v0.11": page: _
Loading

0 comments on commit b7a5543

Please sign in to comment.