-
Notifications
You must be signed in to change notification settings - Fork 302
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
Inconsistent evaluation of unification? #964
Comments
Original reply by @mpvl in cuelang/cue#964 (comment) Same issue as before: definitions are evaluated. So also when running export. So the In 3, it doesn't really wait, but rather just unify But I see your point. There is little one can do here without introducing a substantial language change. The problem is comparing against bottom, which is generally not a great idea. It is okay to have "incomplete" errors in definitions, that is, expressions for which not all values are available. But the result of comparing against bottom is always defined. Then once it obtains its concrete value, it will complete the other evaluations and generate an error.
It evaluates it when it can. A definition is evaluated by itself, and separately at any point it is used. So one cannot speak of evaluating too early here. As you can see, the usage of What exactly is it what you try to do here? One could just write:
if the value is required to be there, no? |
Original reply by @mpvl in cuelang/cue#964 (comment) Note that Proposal #822 introduces a concept of required fields, allowing to state explicitly that a field must have a concrete value. Is this perhaps what you are trying to do here? |
Original reply by @kumorid in cuelang/cue#964 (comment) First things first.
What I presented is a simplification of what I exposed in #955. And what I presented in #955 was itself an attempt to simplify a workaround for #951. Unfortunately, our application ends up relying in a set of complex cue files, which from time to time give us trouble. The areas that give us trouble gravitate around struct disjunctions (your suggestion to achieve our goal as posed in #955 , that is, force to give at least one among a set of fields), and repeated specification fo field restrictions (that lead to VERY LONG processing times) that we use to enforce constraints that fields should abide by. But along the way i bumped into the issue reported here. The reasoning is as follows given -- test2.cue -- #T: { a?: int isa: bool isa: a != _|_ valid: isa & true } d: #T & {a: 56} -- test3.cue -- #T: { isa: bool valid: isa & true } d: #T & {a: true} ( I fixed some incorrect values in the original post, sorry. Also I explicitly constrained field from the previous examples, in both cases field In my opinion, the error for I cannot understand the rationale for the observed behavior. |
Original reply by @myitcv in cuelang/cue#964 (comment)
@kumorid I think this is the key statement in @mpvl's response. One strange thing I have observed however:
evaluates to:
|
Original reply by @kumorid in cuelang/cue#964 (comment) Hi @myitcv, I assume by If it is committed to before even unification happened (which clearly it is not, as my Going to your example: yes, it is strange. Clearly, field Maybe comparison to bottom is trying to do too many things: report when a field cannot get any value AND report when a field does not exist, and this gives some trouble (just a speculation). In our application, I believe all cases of comparing against |
Original reply by @myitcv in cuelang/cue#964 (comment)
That is indeed the case, which is one of the mains reasons for cuelang/cue#943 |
Original reply by @mpvl in cuelang/cue#964 (comment) @kumorid: solving the processing time for disjunction problem is high on the agenda. It is a bit work, but it will consist of several solutions that each will have a big impact.
The value of Note that comparison against bottom checks whether the field is present and whether it is concrete. Optional fields (those with Also, the semantics of comparators require that their operands be concrete. So all in all, it is working as intended, that is not to say it is an ideal interpretation. The core builtins proposal is supposed to clean up the semantics of comparing against bottom. Another unfortunate thing: we ignore any errors in definitions that could be resolved by making a definition more specific ("incomplete" errors). So your test case 2 seems to satisfy this condition and thus it could arguably be expected that it does note result in an error. However, in this case, that mechanism does not apply as comparison against bottom is considered completed. Maybe we can find a way to carry the potential incompleteness forward and not fail in this case as well. That would be a language change, but arguably an improvement and not very impactful from a compatibility standpoint. So leaving this open for now. |
Original reply by @myitcv in cuelang/cue#964 (comment) Thanks, @mpvl - I've now wrapped my head around where my thinking was wrong. Your explanation above makes sense, and emphasises even more strongly the importance of #943. |
Original reply by @kumorid in cuelang/cue#964 (comment) @mpvl , Thanks for your post, it explains the behavior observed...
But, an I suppose this is a consequence of the decision that a In that case, I would be very much in favor of acting as I believe you suggest in your last paragraph, as the present behavior is confusing when compared with how everything else behaves, and gives the impression that CUE's main property (irreversible constraints) is not preserved: the behavior observed seems to indicate that field I assume the proposed builtin, -- test2.cue -- #T: { a?: int isa: bool isa: exists(a) must(isa) } d: #T & {a: 56} And get the expected output after { "d": { "a": 56, "isa": true } } instead of an error at #T. |
Originally opened by @kumorid in cuelang/cue#964
What version of CUE are you using (
cue version
)?Does this issue reproduce with the latest release?
Yes
What did you do?
Given the files below
I ran
cue export test1.cue
,cue export test2.cue
andcue export test3.cue
, consecutively.What did you expect to see?
The output of the first export:
The output of the second export
The output of the third export:
What did you see instead?
The output of the first export:
The output of the second export
The output of the third export:
Which in my opinion is inconsistent, as I will explain in what follows.
Export of
test1.cue
Here, on the one hand, as
d
provides a value fora
,a
is notbottom
ind
, andisa==true
, as expected.On the other hand, as
e
does not provide a value fora
,a
isbottom
ine
, and we getisa==false
.All very intuitive and expected!
Export of
test2.cue
,Here, all we introduce is field
valid
which should be valued as the result of unifyingfield
isa
and valuetrue
.We also remove top-level field
e
to avoid producing an error.Thus, the intuitive result is that the unification for field
valid
will dependon the value of field
isa
, which, for top-level fieldd
istrue
as seen in the export oftest1.cue
However we get the error reported above!
It looks like the unification for
valid
does not wait to evaluateisa
!!This is puzzling,... and, in the light of the next export, inconsistent.
Export of
test3.cue
In here, field
isa
is not computed, which seems to make a huge difference, as now, unificationseems to wait until the value of field
isa
is available before passing judgment.The text was updated successfully, but these errors were encountered: