Cue – A language for defining, generating, and validating data
cuelang.org
cuelang.org
Cue seems like an e2e solution so it's not only an alternative to Jsonnet, it also removes the need of JSON Schema, OpenAPI, etc. so given that it's a 5 months old project, still has too much time to evolve and be mature.
We're heavily using Jsonnet for our data modeling (https://github.com/rakam-io/recipes) and pretty happy with it. We also have plans to add support for JSON Schema which is adopted by many of IDEs so that VSCode makes us feel like we're writing Java, not a Jsonnet file.
Cue is Google's 6th attempt and given that Jsonnet already has traction and works well out of the box, I would invest my time into Jsonnet at this time.
Here is my understanding of the basic concepts:
- It allows a schema-like set of constraints to be declared for JSON (and therefore for YAML & TOML) in a syntax that is an extension of JSON.
- Cue deals with types (sets of values) where JSON deals with single values. Ordinary JSON syntax for a primitive value denotes a set containing that one value. For example, `a: 1` means that the set of possible values for `a` is {1}. Cue calls this a concrete definition.
- Cue provides operators for union (`|`) and intersection (`&`) of sets, and inequalities for ranges of numbers, and so on. `1 | 2` denotes `{1, 2}`.
- Built-in names provide the types `int`, `float`, `string`, etc.
- Cue "struct" types look like JSON objects, associating names with sets. Each name/value pair is a constraint, and all constraints must be met. For example, `{a: int}` denotes "the set of objects that have a property `a` with the value in `int`".
- Properties can be referenced by name; this allows a property defined in one place to be used a type (set) definition in multiple places.
- When a name is bound more than once, the sets associated with each binding are intersected. This means that enforcing a schema reduces to simply combining the schema definition with the "concrete" bindings and throwing an error when an empty set is encountered.
BTW, if I do have it all wrong and what I've described above is not an accurate description of Cue, then I think I'll have to go build what I've described.
Some reasons I'm afraid I'm off-base:
- What's with the lengthy discussion of lattices, and related terminology? Sure, we can construct a lattice from the set of possible types and a "subset of" operator, but that's another level of abstraction away from the necessary concepts, so I don't see what value it adds.
- The `|` operator is described as constructing a sum type, when it seems to me it must actually be a (non-discriminated) union. Elsewhere the `|` operator is described as "computing the join", which to me would mean finding an element in a lattice, but for this to make sense to me I have to think of it as adding an element to the lattice (again all the lattice or poset terminology serves only to obfuscate things).
It's how the author thinks about the values. All the operations move a value up (|) or down (&) the lattice and those operations are associative, commutative, etc. Moving down past the concrete values gets you bottom, the error value, so 1 & 2 is _|_. It fits into things like default values where (using # for * because HN formatting doesn't do escape sequences) a: int | #1 and a: int | #1 unify to 1 because #1 & #1 = #1 but a: int | #2 added would result in a: int because #1 & #2 = _|_ so there is no default anymore.
I don't think the extended discussion on lattices is particularly useful. A much better intro is the tutorial [1] plus the concepts page [2]
[1] https://github.com/cuelang/cue/tree/master/doc/tutorial [2] https://cuelang.org/docs/concepts/logic/
The motivation is clearly to build a tool for configuring kubernetes but I see the combination of data, validation, and order independence as being valuable outside that use. I've definitely had projects where it'd fit. The main reason I'd think twice is because it does add a LOT of concepts for something that can be pretty simple on most projects.
This should have its own word. Murid is too close to 'lurid'. Tumky, perhaps, though it lacks a certain heft and judginess.
I used the following command on the cloned repository to find it[1]:
find . -iname '*.cue' | xargs ls -l | tr -s ' ' | cut -d ' ' -f5,9 | sort -n
[1] Note that 'find' has a '-printf' option which could have been used to simplify this one-liner.In this file, there is no constraint describing non-negative number or non-empty string, or ill-formed URL, or invalid number ports.
EDIT : found it in the doc : https://cuelang.org/docs/usecases/validation/
I get what you're saying and it can be neat, but I don't think it's universally applicable
And some projects have multiple backend services written in multiple languages.
Because you want to write a config file, not a program?
What next, config files, build systems and unit tests for your config files?
No thanks.
When you consider the use of this language within a distributed system it's pretty freaking brilliant. https://cuelang.org/docs/concepts/logic/#the-value-lattice
I highly recommend reading about some of the internals, it is making me rethink a lot of how configuration should be done.
https://news.ycombinator.com/item?id=20362951
Looks like there is a nice new web site.
It seems a bit too feature laden to take off IMO.
The most important part of any programming language website is a short example snippet: put it above the fold on the front page!
Edit: Ah, the code example only appears for desktop browsers (or at least, browser windows wider than a phone screen).
And it's one of those trendy shitty live-typing demonstrations instead of just letting you read some text.
So if you add a field, you break existing code that doesn't know about the field.
Even for those that you choose to close, it’s a matter of having different code for different definitions. The claim that it just automatically breaks isn’t true even when closed definitions are used.
BTW, this feature speaks to CUE’s intended purpose as a configuration language. It is (or at least can be) nice to ignore unknown fields in transmitted payloads for forwards and backwards compatibility. But if I’m trying to configure some software and misspell a field, I probably want the configuration file to fail validation, not have the software run with an unintended configuration.
I couldn't find anything after like a minute of searching. Unless we're counting the gif that slowly shows you an example project letter by letter.
* https://github.com/cuelang/cue/blob/master/doc/tutorial/basi...
* https://github.com/cuelang/cue/blob/master/doc/tutorial/kube...
That's cool!
could you expand on this? i don't understand how you get this from grammars.
(on a side note, i think that dependent types usually mean you can write functions from values to types, not type -> type?)
InfiniteListOf = Type ->
Type & InfiniteListOf Type
That function just morphs a simple grammar into another grammar. Imagine now if we could calculate something in between: IncrementingInfiniteListFrom = number ->
number & IncrementingInfiniteListFrom number+1
That's where the dependent types come in, naturally.I've always thought that a more restrictive and simpler version of yaml would be a good alternative.
Both Jsonnet and CUE have their origin in GCL internally at Google. Jsonnet is basically GCL, as I understand it. But CUE is a whole new thing.
The Cue docs talk about jsonnet explicitly.
Is it true that there are dozens of internal language and DSLs? Why does G have so many?
2. find a use case where you want a config with ~700 lines, most of it just a repeated variant of something
3. add more fields to your config to reduce the verbosity
4. realize that your configs are now obscenely complex, and build a limited-purpose DSL
5. five teams now use your limited-purpose DSL and make more feature requests
6. cry because you now maintain a DSL
7. ???
8. promo for cross-team impact
1: https://github.com/cuelang/cue/blob/master/doc/tutorial/basi...
This is what Facebook does: Python emitting JSON.
Disclaimer: was borgcfg owner 2016-2019.
But GCL made it so whatever variable was actually being used by borgcfg was obscured by layers upon layers of imports.
Unfortunately there was no formal spec of the GCL language, so the new impl was based IIRC on reverse engineering the spec from the first implementation of the interpreter. It turned out our configs hit several cases where the original behaviour was either unsound (and thus the new impl sacrificed backwards compat) or we hit a bug in the new impl.
The main problem with the language (as opposed as issues with the implementations) was that finding the root of those behaviour differences was very hard. It was very hard to follow where the variables came from. The GCL scoping rules (and lazy evaluation) were indeed very unfriendly for debugging.
This was an extreme case of a pain that was felt on a daily basis by a lot of people I've been talking to.
A few executives are not friendly to borgcfg. Their agenda, appeared to me, has been to deprive it's resources so it can die from rotting. That's bad engineering and totally unnecessary. A healthy BCL/borgcfg will die easier, because they'll allow an easier path migrating to something new.
FWIW I'm the current maintainer of https://github.com/bitnami/kubecfg whose name is shameless xoogler bait.
If its for a technical individual to configure your software I don't know that such a gui would be superior to your favorite editor.
The title certainly made me think that it was the former, even though it's the latter.
This seems to describe very few Google products. Almost daily, I have the following thought: "Has anyone at Google actually even used this product?"
(Most often with Assistant, but definitely with other products, too)
Most Google services (off the top of my head: Voice, Talk, Reminders) seem to reach v1 and then stop dead in their tracks. They're online, but that's it. Thousands of people request fixes or features, and they go completely unheard.
Google employees on HN have confirmed this, saying that the company rewards new products that drive ads, but not the work involved in improving and maintaining existing products. That explains why Google's released the following products for messaging, and none has been amazing: Talk, Hangouts, Voice, Wave, Allo, Hangouts Chat, and Messages/RCS.
Most of these overlapped at some point, and if you've used any of them, you wouldn't describe them as "maintained". They're more like "abandoned without publicly announcing anything".
If there's a VP or PM vision anywhere at Google that lasts for more than a year, I'd love to know what it is. It seems like a company with a thousand committees and no real creative leadership.
One of the things they bring up in the docs is lessening boilerplate. And it's hard to get more boilerplatey than XML.
Disclaimer: Was owner of borgcfg 2016-2019.
:(
GCL, used outside borg, is a much more pleasing experience, because there is a decent tool. And the team have done good job to innovate continuously.
FWIW Piccolo has also leaked into the industry in the form of Pystachio.
> CUE is an extension of JSON. This improves familiarity and makes it easy to get going quickly.
> In its simplest use case, CUE can substitute for a more pleasant way to write JSON.
Let’s raise a glass to our blue eyed comrades who’ll adopt this fully, only for google to decide in 2-3 years to completely and aggressively kill it again for no apparent reason.
Any named examples? I’m sure there are-and likely they just elude me at present, maybe seeing their names will jog the memory probably?
Examples include: AngularJS (replaced by a rewrite of angular effectively), GWT (donated as 'open source' with minimal continued google involvement), basically 90% of all 20% projects by googlers that weren't official google stuff (too many examples to name, practically all of them), the xmpp api for google talk (and all associated library code, including some open source xmpp extensions, libjingle), tons of chrome and android libraries that were killed/deprecated as part of new versions not using them, ARC (https://en.wikipedia.org/wiki/Google_App_Runtime_for_Chrome), the caldav API for google calendar and any associated libraries...
I could go on, but the majority of the relevant examples are the 20% projects that never made it, and I'd rather not list any of those since they're largely single-person projects and it's kinda personal to comment on any of em.
With that as the worst case scenario, it's more than worth the try.
What i want to see, is a company which will provide as a service, basically devops deployment, monitoring and provisioning regardless of the cloud provider.
Such that i can say “deploy this” and it will eval, track and monitor the cost of the deployment across aws, azure, gcp, etc and i can click controls to see/kil/scale wherever...
Thus, i dont care about cloud provider deployment language, etc...
If the authors would like to discuss how Tree Notation may be a better syntax for this language, please feel free to get in touch: breck7@gmail.com or yunits@hawaii.edu.
Here is a demonstration of what a Tree Language for config files could look like: https://treenotation.org/designer/#standard%20config
Fact: my post is very relevant to the OP and I'm offering to help them.
Fact: I've been a member of this site for over 12 years, and never comment on a post unless I think it adds value to the discussion or would be helper to the parent.
I like the idea of a git based database. Please don't take a single person's opinion as that of the entire community.
That's a good suggestion. I didn't think of that. But thinking about it, I guess I don't want to bother the OPs inbox. If they are interested, they can get in touch.
> added literally nothing to the discussion.
I disagree. When I post a new language, and someone shares a link to a related language, those are often the most valuable comments.
Validating, defining, using data: sound like things Tree Notation syntax is perfect for. Cue's semantics are great, and presentation and execution, I just think potentially a syntax switch is worth exploring. I understand the strategy to be able to parse JSON as cue, and that's probably the way to go for now, but in the future Tree Notation syntax might offer compelling advantages.