github cue-lang/cue v0.4.0-alpha.2

latest releases: v0.9.0-alpha.5, v0.9.0-alpha.4, v0.8.2...
2 years ago

This release focuses on setting direction for the CUE API. This brings the overall API much closer to where we would like it to go. It also prepares the API for the query extension.

Note that this is deliberately marked as an alpha release to allow people to give feedback in the case we need to make some tweaks to the API.

A central piece in that are the cue.Path and cue.Selector types. Another key part is getting rid of the Instance type. This type proves to be unnecessary and not using it results in a considerably nicer UX.

The old functionality is marked as deprecated and will stay around until we provide a way to automatically rewrite them. We will just no longer support them and we use a trick mentioned in this tweet to hide most of the deprecated methods from the Go docs in the meantime (pending a "proper" fix in pkg.go.dev).

Other improvements include:

  • another big round of tuning error messages, most notably adding more line information.
  • a performance bug fix that caused significant slowdown when doing repeated calls of Fill or Unify on the same values.

API additions

The cue.Path model

The old API was designed before the existence of definitions. The fact that definitions live in a different namespace, broke the API at various levels, and patching this up resulted in a brittle and complicated API.

The cue.Path-centred API addresses these issues, resulting in a much smaller API surface while at the same time being less prone to error.

This new API also paves the way for the query extension.

Some deprecated types and methods:

The following types and methods all get replaced by LookupPath:

  • FieldInfo
  • Instance.Lookup
  • Instance.LookupDef
  • Instance.LookupField
  • Value.Elem
  • Value.FieldByName
  • Value.Lookup
  • Value.LookupDef
  • Value.LookupField
  • Value.Struct
  • Value.Template
  • Struct

Similarly, FillPath and ReferencePath replace (Value|Instance).Fill and Reference. The latter also is instrumental in getting rid of Instance. In the long run we will want to repurpose Value.Lookup and Value.Fill, but that will be a long way out.

The new Iterator.Selector method replaces:

  • Iterator.Label
  • Iterator.IsLabel
  • Iterator.IsOptional
  • Iterator.IsDefinition

Using Selector also makes it more explicit what kind of labels one has and is thus less error prone. The selectors can be used to construct paths for lookup methods without loss of information, making the API more precise.

Phasing out Instance

The Instance type was initially intended to allow enforcing certain constraints. The data model of the new evaluator allows doing so without the need for Instance.

Getting rid of Instance has some big benefits. Most notably, the need to link Value to Instance makes it very hard to avoid memory retention, even when a user believes a Value is no longer needed. This causes long-running CUE services to grow in memory usage over time.

Another issue is usability: aside for duplication of methods, it may be hard for a user to know when to use a Value or Instance.

Context to replace Runtime

There are a few reasons for this change. As part of removing Instance, we needed a new way to build Values. The Context type now defines a new set of Value constructors.

Another reason was to have a cleaner way to break the dependency cycle that existed for linking in the core builtins. Previously, the user had to add a import _ "cuelang.org/go/pkg" somewhere in the code, or use a package that already did so, to make the builtins available. Now the user is expected to create a Context using cuecontext.New(), which takes care of this.

Finally, the name Runtime was confusing to some. The Context maintains indices and tables that are shared between creations of values, but there is no inherent “running” state.

The Context now also makes it easier to resolve identifiers in another Value’s scope or to directly encode Go values and types.

Value.Allows

This method now enables querying whether a Value would support a field of a specific type if it were to be added. This also uses the Selector type to specify the kind of field.

This replaces IsClosed.

Backwards incompatible changes

The new APIs are just additions. In many cases, the old API has been implemented in terms of the new API, but should still function as usual. This did result in some bug fixes, however, so one may observe changes.

Value.Format

The one change that may cause backwards incompatibility is the standard fmt.Formatter implementation of Value, which now has a more principled implementation. The standard %v formatter now prints it as a value, but allows incomplete values. The %+v formatter, as before, prints the fully evaluated value and is similar to cue export. The %#v formatter, which previously printed an esoteric debug format, now prints an equivalent of cue def.

Many of the standard Go formatting verbs will now be interpreted as such if the Value is of a compatible Go type. See the documentation of Value.Format for more details.

There have been various bug fixes in the exporter code as part of this change.

cue/encoding

This package has been removed. It really didn’t do anything except from being a distraction. In the off chance that anybody was using this package, just deleting that code would probably solve it.

Changelog

9e34a41 cue/ast/astutil: export ImportPathName
50c137a cue/encoding: removed unused package.
dcb2a1f cue/errors: add Wrap
f044ad1 cue/format: expose indent option
6822433 cue: add Iterator.Selector
f14c9a4 cue: add Selector.PkgPath
c5c9125 cue: add test for filling empty path
17d4e16 cue: clean up Format
618c10c cue: deprecate Instance.(Doc|Fill)
790bed3 cue: get rid of NewRuntime
4937cb9 cue: hide deprecated methods from docs
421ead3 cue: introduce Context to replace Runtime
d76e2cc cue: remove MakeValue
908614e internal/core/adt: dedup errors
b8ce660 internal/core/adt: improve performance for repeated calls to Unify/Fill
276ce26 internal/core/adt: record more error positions
14ec6e2 internal/core/export: add real Final option
b5b0429 internal/core/export: bug fixes for exporting API-generated values
c62b750 internal/core/export: bug fixes in definitions
64ede63 internal/core/export: extract docs from root
b937727 internal/core/export: fix definition wrapping
c290772 internal/value: implement interface type that is both value and instance
1f78a8d internal: replace untyped functions with typed ones
d5ff672 pkg: clean up builtin errors

Don't miss a new cue release

NewReleases is sending notifications on new releases.