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
orUnify
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 Value
s. 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