5 ms·
I think I get what the article is saying. I don't think they expressed it very well. Here's a concrete example of what I think they're complaining about. From
by derefr 5y ago
I think I get what the article is saying. I don't think they expressed it very well.
Here's a concrete example of what I think they're complaining about. From a Kubernetes Deployment manifest:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: db-conn
key: uri
That valueFrom.secretKeyRef.{name, key} structure is an "exploded AST" — something that in any programming language, you'd be chastised for writing out as a structural-initialization literal, because there's so much stuff there that it's easy to screw it up and forget something.
When attempting to express such a literal in most-any programming language, you'd expect to either have:
• the Java "literal factory function" approach — some static function to call, that takes either other literals, or a single literal string encoding an expression in a DSL, as arguments, and then produces an initialized value-object; or
• the Elixir "custom sigil" approach (there's probably a more popular language with this feature, but Elixir is what I know) — a macro or operator that takes in a raw string or lexemes encoding an expression in a DSL, and then codegens out to the appropriate structural-initialization literal. (Macros are better here, as incorrect DSL syntax can be caught at parse/compile time, just like incorrect syntax of the surrounding language.)
-----
To be honest, I don't think I would want YAML to support either of these. YAML shouldn't be arbitrarily extendable; a YAML document should be a YAML document, parsed by any compliant parser. (There could be some Avro-like "embedded schema" format for YAML that enables this, but that format would be better as a layer on top of YAML, rather than being part of YAML itself.)
What I would like in YAML, is support for built-in literal sugar for certain specific YAML structures.
This is different in concept from YAML having support for a type, where that type must have some 1:1 native type on the host language side for it to encode/decode to.
Instead, a "sugared structure" would involve
1. a YAML parser having a sub-parser for certain specific DSLs, where the output of this parser is a small, standardized-in-shape container structure, made out of regular YAML arrays, dicts, and scalars;
2. a YAML generator offering a configuration option to pattern-match on these standardized-in-shape structures, where recognized subtrees are swapped out in the emitted YAML for the appropriate sugared-literal representation.
Examples of where this would be helpful include: DateTimes, URIs, UUIDs, Intervals... and that's basically it.
There really aren't too many of these. The short list above represents basically the entirety of the set of types I've ever had YAML fall down on in the 10 years I've been generating/parsing YAML documents. For everything else, it works fine.
- travisjungroth 5y agoWhat do you mean by “exploded AST”? What’s a “structural-initialization literal”?
- derefr 5y agoStructural initialization is when you define a struct (as opposed to a scalar) by directly declaring the values of its (potentially-private!) named fields. For example, in Elixir, this is a structurally-initialized MapSet literal: %MapSet{map: %{}, version: 2} This is as opposed to a factory-method-initialized literal, going through a functional API that can hide the inner workings of the ADT produced: MapSet.new Or, compare and contrast a structurally-initialized literal with a DSL-expressed literal: %DateTime{ calendar: Calendar.ISO, day: 14, hour: 23, microsecond: {121432, 6}, minute: 57, month: 8, second: 22, std_offset: 0, time_zone: "Etc/UTC", utc_offset: 0, year: 2021, zone_abbr: "UTC" } vs. ~U[2021-08-14 23:57:22.000000Z] Note that in the first case (structural initialization), if there were any other complex non-scalar objects nested within the main one, you'd have to define those too. It's a forced encoding of an Abstract Syntax Tree representation of the structure of the data; but it's an AST that's "exploded" or "cross-sectional" — one that has no functions, no ability to encapsulate/abstract. Here's a snippet from https://yaml.org/YAML_for_ruby.html#perl_regexps https://yaml.org/YAML_for_ruby.html#perl_regexps: !perl/regexp: REGEXP: "R[Uu][Bb][Yy]$" MODIFIERS: i Wouldn't it be less annoying to both read and write that in a YAML document if it were expressed the way you'd expect — as: /R[Uu][Bb][Yy]$/i ...where YAML itself would know to parse the latter as if it were the former, and to generate the latter in place of the former (for this, and an exclusive few other common structurally-initialized types that constantly get represented in YAML documents)?
- travisjungroth 5y agoThanks for explaining. I'm not sure that's laughed at in every language. It's standard in Clojure to just define things as maps, lists, etc. I actually think it's a pretty good idea. Your examples, datetimes and regex, make the DSL option seem nice. In picking good examples you picked ones I'd be familiar with. But that's sort of the trick. If something is completely new to me, I'd much rather have it blown up.