4 ms·
FWIW, the best intro to CUE I’ve found so far is: https://bitfieldconsulting.com/golang/cuelang-exciting https://bitfieldconsulting.com/golang/cuelang-exciting
by typical182 5y ago
FWIW, the best intro to CUE I’ve found so far is:
https://bitfieldconsulting.com/golang/cuelang-exciting https://bitfieldconsulting.com/golang/cuelang-exciting
…which does a nice job of starting from the problem, and building up from "how could we improve JSON for use as a config language" to arriving at CUE.
(Those types of explanations happen to resonate with me, including understanding the "why" first at least for me helps the mechanics and details later make more sense and feel more intuitive…)
- peterb 5y agoI really enjoyed the article. Thank you for posting it.
- angelzen 5y agoCUE is really promising and the article is a good first introduction to CUE. After reading it, there are a few things that don't fully click: * How does CUE compare with a standard structural typing system, i.e. Typescript. Specifically, what is the deep difference between john: #Person & { age: 29 hobbies: [ "physics", "reading", ] } and type Person = { age: number hobbies: string[] } const john: Person = { age: 29 hobbies: [ "physics", "reading", ] } * How do constraints relate with the rest of the language? Specifically, why a limited set of ad-hoc operators `>=18` / `=~ regex` vs (Scala) lambda forms `_ >= 18` / `_ =~ regex` * Where is the line between a data language and a full fledged programming language? For example, the list package, while (intentionally?) missing map / fold, indicates a strong demand for rich list processing capabilities. https://pkg.go.dev/cuelang.org/go@v0.4.0/pkg/list https://pkg.go.dev/cuelang.org/go@v0.4.0/pkg/list
- throwaway894345 5y agoI don't fully have my head around it either, but in my understanding you can have two mutually independent files that define `john: <constraint>` where <constraint> differs in each file, and in Cue these will be unified: the `john` value must satisfy both constraints. For example, one file might have the constraint "john is an int" and the other "john is between 1 and 7". If the constraints clash (e.g., john is an int and john is a string), then it's an error. That said, I think my disconnect is "when is this useful?" or "what can I do with this property?".
- paufernandez 5y agoI think you are right. I see it as a form of multiple inheritance, a new one which no other language has.
- throwaway894345 5y agoSort of. Inheritance extends (hence the keyword of the same name) while constraints restrict (or constrain).
- verdverm 5y agoInheritance also allows overrides, which is something CUE errors on. CUE has Go like embedding so you can reuse common schema or config. CUE's constraints are in the "middle" of the spectrum (lattice, partially ordered graph) from abstract types to concrete data.
- verdverm 5y agoIt's called unification and exists in many languages, Prolog is a well known one. CUE is in the logical language family. It uses Typed Feature Structures which originated in NLP before deep neural networks became capable. It is specifically not inheritance where overrides are allowed.
- angelzen 5y ago"When is this useful?" I can't comment on specific CUE design decisions, and speaking generally about data languages and not specifically about typing thereof. A canonical use-case for data languages is a cloud deployment consisting of many almost identical items, e.g. k8 pods, described as a series of data templates with the the property that the cost of overriding any (shared) configuration parameter over the entire deployment is O(1). In a standard function-based language this can be done by rewriting function arguments at runtime, i.e. some form of monkey patching. I haven't seen a good theoretical explanation on how data languages (GCL, jsonnet, CUE, etc.) avoid the monkey patching trap as opposed to embracing it with good terse monkey patching syntax & semantics. Perhaps there is a there there, but until the basic evaluation semantics is clarified, I have little hope of grokking higher level concerns like typing.
- Kinrany 5y agoI'd draw the line at having two-way relations instead of functions. But I don't think this is the way CUE went, which is troubling.
- verdverm 5y ago1. In CUE, types and values are equivalent and both live within the same lattice. You have a spectrum from the abstract to the concrete. See https://cuelang.org/docs/concepts/logic/ https://cuelang.org/docs/concepts/logic/ for a good overview. There are also definitions and structs, which have different semantics for closedness (ability to add fields). See https://cuetorials.com/deep-dives/closedness/ https://cuetorials.com/deep-dives/closedness/ for an overview. One really interesting aspect of CUE is subsumption which can tell you if your types or API are backwards compatible. 2. Generally CUE is a turing-incomplete language, which means you cannot program. No user functions or lambdas by design. There are a number of utilities provided in the stdlib which are idempotent. It is not possible to maintain the guarantees of the language with user define functions. There are list and field comprehensions which are like a map. You can fold be simulated with comprehension. A proper fold could be added at some point.
- angelzen 5y ago1. The subsumption rule is elegant, but doesn't answer the pragmatic question: for what use-cases is a naive structural type system (familiar to a large population of developers) insufficient? Logic theory has type towers, but for 99% of the use-cases values and types are interesting, rarely kinds. Not even sure if 'type of kinds' has a name by itself. Possibly constraints are an answer, but the constraint system feels ad-hoc. To rephrase, how would one describe Cue type system as a generalization of a naive structural type system? 2. Not sure what you mean by 'idempotent', perhaps 'pure' or 'no side-effects'? There is plenty of non-turing complete computations that can be done with pure functions.