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

need alias type to support binding to embedded scalar #620

Closed
cueckoo opened this issue Jul 3, 2021 · 8 comments
Closed

need alias type to support binding to embedded scalar #620

cueckoo opened this issue Jul 3, 2021 · 8 comments
Labels
FeatureRequest New feature or request
Milestone

Comments

@cueckoo
Copy link
Collaborator

cueckoo commented Jul 3, 2021

Originally opened by @verdverm in cuelang/cue#620

In alpha-6


Bug with embedded scalars, we'd like to be able to do this, correct?

Seems like the definition is being evaluated to early. Adding default value to the let s = ... shows the value is being taken too soon (i.e. Cue is not lazy enough ;)

$ cat embed-scalar.cue 
import "strconv"

#portI: uint16 & >1024

#portS: {
        s
        let s = string & =~ "^[0-9]{4,5}$"
        #valid: uint & >1024 & strconv.Atoi(s)
}

#port: #portI | #portS

pi: #port
pi: 1234

ps: #port
ps: "1111" // or error on "1000"
$ cue export embed-scalar.cue 
error in call to strconv.Atoi: non-concrete value string
ps: empty disjunction: 1 related errors:

Using a default value takes that value not the one set on the last line.

@cueckoo cueckoo added the FeatureRequest New feature or request label Jul 3, 2021
@cueckoo cueckoo added this to the v0.4.x milestone Jul 3, 2021
@cueckoo cueckoo closed this as completed Jul 3, 2021
@cueckoo
Copy link
Collaborator Author

cueckoo commented Jul 3, 2021

Original reply by @mpvl in cuelang/cue#620 (comment)

Ah, I see the issue. The argument to strconv.Atoi is s, not the embedded scalar itself. So when ps binds the string to the embedded value s won't bind to that.

What we want is aliases. However, there are no aliases that allow one to do this easily now. We recently proposed two forms that may address this:

#portS: {
        S = string & =~ "^[0-9]{4,5}$"
        #valid: uint & >1024 & strconv.Atoi(S)
}

and

#portS: S={
        string & =~ "^[0-9]{4,5}$"
        #valid: uint & >1024 & strconv.Atoi(S)
}

Both would be equivalent. Syntactically it would make sense to support both.

Either way, it seems that with embedded scalars the need for aliases of embeddings or values has become more pertinent.

@cueckoo
Copy link
Collaborator Author

cueckoo commented Jul 3, 2021

Original reply by @seh in cuelang/cue#620 (comment)

#portS: {
        S = string & =~ "^[0-9]{4,5}$"
        #valid: uint & >1024 & strconv.Atoi(S)
}

There, within #valid, what says that uint and > 1024 refer to S? Is that because S is an embedded scalar, so all constraints implicitly would refer to that embedded value?

@cueckoo
Copy link
Collaborator Author

cueckoo commented Jul 3, 2021

Original reply by @verdverm in cuelang/cue#620 (comment)

My intention was that I could invalidate the definition when the constraints are imposed. I don't think we want them to automatically apply so that one could have an intermediate and want to apply constraints on that as well. The nice thing about embedded scalars is that it simplifies the "function" syntax

For example:

#calc: {
  Result = unit & intermediate
  input: int
  intermediate: input + 5 & <10
}

r: #calc & { input: -2 }

// instead of
// r: (#calc & { input: -2 }).Result

@cueckoo
Copy link
Collaborator Author

cueckoo commented Jul 3, 2021

Original reply by @myitcv in cuelang/cue#620 (comment)

@verdverm I think you intended input and intermediate to be definitions there, not regular fields?

Also related to the general discussion above (in the context of #valid) is cuelang/cue#575

@cueckoo
Copy link
Collaborator Author

cueckoo commented Jul 3, 2021

Original reply by @mpvl in cuelang/cue#620 (comment)

@seh

With field aliases, X in

X= foo: int
foo: 2

results in int&2 (so 2). IOW, it refers to the result of that field.

Similarly, for aliases to embeddings, X in

foo: {
    X=int
    2
}

refers to the embedded scalar int&2.

Note that we can use this notation to refer to the struct itself. So in

foo: {
    X=_
    
    a: int
}

X refers to { a: int }. Note that this is different from

X=foo: {
    a: int
}

which refers to the field looked up in the outer scope, which binds differently. It is this difference which is actually quite useful and a workaround to another problem.

@cueckoo
Copy link
Collaborator Author

cueckoo commented Jul 3, 2021

Original reply by @seh in cuelang/cue#620 (comment)

Thank you for the explanation. I'm trying to reconcile that with what you wrote here: cuelang/cue#620 (comment). Are you describing CUE as it works as of version 0.3.0-beta.1, or are you describing a proposed change in how it could work?

@cueckoo
Copy link
Collaborator Author

cueckoo commented Jul 3, 2021

Original reply by @mpvl in cuelang/cue#620 (comment)

Note that https://cue-review.googlesource.com/c/cue/+/9543/1 implements "field value" aliases, allowing:

foo: X=bar

So instead of writing

foo: {
    X=_
    a: int
}

one could write the following to achieve exactly the same:

foo: X={
    a: int
}

To the user this may be the same thing, and it may be weird we support one form, but not the other. The main reason why only this is supported is because the X=_ used to be what is now let X = _ and we are still phasing this out. The ultimate goal is to allow both to be equivalent.

@cueckoo
Copy link
Collaborator Author

cueckoo commented Jul 3, 2021

Original reply by @myitcv in cuelang/cue#620 (comment)

@verdverm @seh I think we're resolve here with the arrival of value aliases in v0.4.0 so I'll close this issue. But please shout if that's not the case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
FeatureRequest New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant