cue-lang / cue

The home of the CUE language! Validate and define text-based and dynamic configuration
https://cuelang.org
Apache License 2.0
5.01k stars 283 forks source link

cue errors out on solvable cycles #622

Closed cueckoo closed 3 years ago

cueckoo commented 3 years ago

Originally opened by @Ereski in https://github.com/cuelang/cue/issues/622

What version of CUE are you using (cue version)?

$ cue version
cue version devel linux/amd64

I am not sure how to get the actual version, but I installed cue today with:

go get -u cuelang.org/go/cmd/cue

Master is at cefe38b12bc4df48f5bc100d0a45fc9ec563e36d

What did you do?

Running cue export on:

a0: X
a1: a0 * 2
Y: a1

b0: Y
b1: b0 / 2
X: b1

X: 5.0

What did you expect to see?

{
    "a0": 5.0,
    "a1": 10.0,
    "Y": 10.0,
    "b0": 10.0,
    "b1": 5.0,
    "X": 5.0
}

What did you see instead?

cycle error:
    ./example.cue:2:5

Comments

If I replace a0: X with a0: 5.0 (the value of X) I get the expected result.

cueckoo commented 3 years ago

Original reply by @mpvl in https://github.com/cuelang/cue/issues/622#issuecomment-752884547

This cycle may be mathematically solvable, but it is illegal CUE. CUE does not allow self-references other than the value directly. That is, it is illegal to have a cycle as an operand to an expression (like b0 / 2).

In general, CUE does not do any mathematical resolution, even if it is very simple. This is outside the scope of CUE. It could be solved with tooling build on top of CUE, but is it not something that should be part of the main evaluator, as it will have all kinds of undesirable consequences.

cueckoo commented 3 years ago

Original reply by @Ereski in https://github.com/cuelang/cue/issues/622#issuecomment-752915509

Then the issue is with cue's docs. Opened a new issue: #624

cueckoo commented 3 years ago

Original reply by @mpvl in https://github.com/cuelang/cue/issues/622#issuecomment-752984071

Ah, yes indeed. I stand corrected. There is an illegal cycle, but the 5.0 in

X: b1
X: 5.0 // this breaks the cycle and should allow CUE to resolve it.

should break it.

cueckoo commented 3 years ago

Original reply by @Ereski in https://github.com/cuelang/cue/issues/622#issuecomment-753342710

So I think I found a way to make this work. First I made all a* and b* fields definitions since they are just intermediary values:

#a0: X
#a1: #a0 * 2
Y: #a1

#b0: Y
#b1: #b0 / 2
X: #b1

X: 5.0

This still errors out, but inlining #a0 and #b0:

#a1: X * 2
Y: #a1

#b1: Y / 2
X: #b1

X: 5.0

and cue now computes Y correctly:

$ cue export example.cue 
{
    "Y": 10.0,
    "X": 5.0
}

I can even add more intermediary steps:

#a0: X + 1
#a1: #a0 * 2
Y: #a1

#b0: Y / 2
#b1: #b0 - 1
X: #b1

Y: 5.0
$ cue export example.cue 
{
    "Y": 5.0,
    "X": 1.5
}

So there's definitely something funky going on, but at least I can now make it work the way I wanted to.

cueckoo commented 3 years ago

Original reply by @mpvl in https://github.com/cuelang/cue/issues/622#issuecomment-754736443

Either way, your original example should work as well. We're working on some refactoring that makes fixing this easy(-ish) as well as improve performance (or at least prepare for improving performance).