Skip to content

proposal: add downcasts #454

@cueckoo

Description

@cueckoo

Originally opened by @zombiezen in cuelang/cue#454

Is your feature request related to a problem? Please describe.
I have a configuration where I have a struct containing a mapping that is frequently edited. Different declarations across my mapping require different subsets of that mapping inside their struct, but frequently not the whole thing.

In this same configuration, I sometimes use template-like objects that have definitions and I want to convert them to a more basic type without the definitions. For example:

#Object: {
  name: string
}

#MyTemplate: {
  #foo: string
  name: "foo-\(#foo)"
}

// ERROR: does not unify
#Object & {
  #MyTemplate
  #foo: "bar"
}

In both cases, I have to write a rather verbose and hard-to-understand comprehension to get the desired effect:

#Object & {
  let #expanded = {
    #MyTemplate
    #foo: "bar"
  }
  for k,_ in #Object { "\(k)": #expanded[k] }
}

Describe the solution you'd like

I'd like a kind of "downcasting" conversion that removes any fields in a struct that aren't in another struct. I don't have an informed opinion about syntax, but borrowing from Go's type conversion syntax, something like:

#Object & #Object({
  #MyTemplate
  #foo: "bar"
})

Describe alternatives you've considered

As mentioned above, this is possible in the language already using comprehensions, but is not obvious to those who haven't already dived deep into CUE what this is doing. A lack of user-defined functions makes it difficult to abstract the operation, thus bringing me to ask for language support. I could do something like (untested):

#Downcast: {
  #value: {...}
  #type: {...}
  #output: { for k,_ in #type { "\(k)": #value[k] } }
}

#Object & #Downcast{
  #value: {
    #MyTemplate
    #foo: "bar"
  }
  #type: #Object
}.#output

But this doesn't add terribly much clarity IMO, it just adds indirection.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions