Live data from Hacker News

Common Expression Language

github.com

61–70 of 111 posts

Re: Common Expression Language

#61
post #5

I remember seeing this used inside config files for the Caddy webserver. Google seem to like these executable config languages because they've got another open source one ("Starlark") a few notches up in expressivity.

"Executable" configuration languages (most "non-executable" configuration language parsers are push down automatons that execute the configuration) are handy, but without strong coding standards and good discipline, the line between business logic and configuration tends to blur over time.

Cartesian product, map, and reduce operations over finite sets and lists are really handy in configuration. ("For each server in SetA look at each path in SetB and ...") But, if you find yourself starting to write general loops (as opposed to loops implementing map, reduce, and Cartesian product in languages that don't have them built-in), it's a sign you're starting to blur the line between configuration and business logic.

Unit-testing configurations is difficult, especially if they can be non-deterministic (depend on data/time/random()) and aren't modular.

In some sense, all programs with configuration files are really interpreters for the language of their configuration files. (As mentioned before, many of these abstract machines are just push down automata.) Taken too far, the configuration becomes the real program.

I've seen a (now retired) automated trading system with a powerful XML-based configuration language where a few times people got themselves into trouble (and caused trading losses) when their complex tower of configuration fell over. Part of the problem was there existed a few people who weren't trusted to write application logic, but who were trusted to "just update configurations". When the only tool some of your people are allowed to use is a hammer, hammer marks start mysteriously showing up everywhere. Additionally, this was over 10 years ago, and prior to these trading losses, configuration underwent less stringent review. I don't think my experience was atypical.

I've also seen configuration loading get stuck because someone added some code to the config to hit a REST endpoint in the middle of the configuration file. Ideally, you'd leave any I/O to the main program logic, where it's easier to perform the I/O asynchronously, or otherwise non-blocking.

Deterministic non-Turing-complete immutable "executable" configuration languages (or at least ones where it's difficult to get unbounded recursion) tend to be a happy medium. Also, declarative rather than imperative configuration languages tend to be easier to read.

Back when I was a developer in web search infra at Google, I vaguely remember once or twice using a language (maybe Borg's config language, borgconfig) that completely lacked mutability and essentially used object prototyping (A is created as a copy of B, with differences specified at object creation time.)

Re: Common Expression Language

#62
post #56
post #42

Earlier quoted context omitted.

What about the option of just writing a regular, one-off program in a regular programming language , the output of which is your baked YAML config; and then having a pipeline that involves running that config-generator program, piping its output to your orchestrator of choice? Nearly every programming language has a YAML serialization library†. And before that serialization happens, your config can be expressed using…

At that point why use YAML at all? If it's generated by a program and fed to a program, you're better off using protobuf or something like that. In fact, since you're probably using the same language on both ends, why not just write a regular value in your language? This probably sounds like a strawman, but it's not. It's how a lot of e.g. Python projects are configured - the "config" file is just a normal bit of cod…

> At that point why use YAML at all?

Ideological answer: For the same reason HTTP/2.0’s binary protocol didn’t instantly obviate/deprecate HTTP/1.0’s text protocol. Text has advantages: text is debuggable, and prototypable. If the interface between two programs is a text based declarative language, you can audit that text, diff that text, edit that text to see how changes affect the result, mock one side or the other by producing or consuming that text, etc. “GitOps” style config management would never work if config was all opaque binary blobs. These are all reasons that major software projects standardize on YAML or other widely-supported textual data serialization formats for their config.

Pragmatic answer: because we’re talking about production configuration management, here, which is, 99% of the time, about writing configuring and managing the third-party black-box components in your stack, not your own components. Your own business layer usually can be configured conventionally, with minimal explicit config, for your use case, since you built it to work idiomatically for that use-case. It’s all the third-party stuff that has an impedance mismatch to your use-case assumptions, translating to needing tons of config to do what you need.

And, obviously, if you don’t control the other end, you don’t decide how the other end does its config. Usually, these days, it’s YAML (or TOML) — for the ideological reasons mentioned above.

Example: Kubernetes. Big consumer of complex YAML. Many people try to template that YAML. Much simpler and less error-prone to just write a program to generate said YAML. No reason to assume you’re writing in whatever language the k8s orchestrator is written in. (In fact, there are multiple orchestrators, written in different languages, and the shared YAML resource spec is the only formal interface they share.)

Re: Common Expression Language

#64
post #4

At the end of the README: Disclaimer: This is not an official Google product.

I'm a Googler, opinions are my own. A lot of the times engineers at Google will open source libraries or tools they have worked on, which go under the Google GitHub repo, but are attached with that language. This is basically saying that it is owned by Google but it is not something Google is officially supporting. It may continue to get updates, it may not. I've definitely seen some libraries open sourced from Googl…

> It may continue to get updates, it may not.

That basically goes for Google's official products as well.

Re: Common Expression Language

#65
post #62
post #56

Earlier quoted context omitted.

At that point why use YAML at all? If it's generated by a program and fed to a program, you're better off using protobuf or something like that. In fact, since you're probably using the same language on both ends, why not just write a regular value in your language? This probably sounds like a strawman, but it's not. It's how a lot of e.g. Python projects are configured - the "config" file is just a normal bit of cod…

> At that point why use YAML at all? Ideological answer: For the same reason HTTP/2.0’s binary protocol didn’t instantly obviate/deprecate HTTP/1.0’s text protocol. Text has advantages: text is debuggable, and prototypable. If the interface between two programs is a text based declarative language, you can audit that text, diff that text, edit that text to see how changes affect the result, mock one side or the other…

> Ideological answer: For the same reason HTTP/2.0’s binary protocol didn’t instantly obviate/deprecate HTTP/1.0’s text protocol. Text has advantages: text is debuggable, and prototypable. If the interface between two programs is a text based declarative language, you can audit that text, diff that text, edit that text to see how changes affect the result, mock one side or the other by producing or consuming that text, etc.

I can see the argument for using a textual format (although I think it's weaker than you say; if we're generating this config with code then we don't want to diff or edit the generated config), but YAML seems like a singularly poor choice if you want reliable diffs and editing; it's like picking tag-soup HTML. Straight JSON (ideally with a schema), TOML or even XML seems like a better bet if you're generating it programmatically.

> And, obviously, if you don’t control the other end, you don’t decide how the other end does its config.

Right, in that case it's all moot. I took GP to be talking about what formats these tools should use. IMO if the tool is intended to consume a machine-generated config then it would be better to use a machine-oriented config format. I think the option of something like protobuf (which is language-independent) is underappreciated, but even restricting ourselves to textual options, something stricter than YAML seems like a better bet.

Re: Common Expression Language

#66
post #5

I remember seeing this used inside config files for the Caddy webserver. Google seem to like these executable config languages because they've got another open source one ("Starlark") a few notches up in expressivity.

I'm an ardent supporter of executable config languages, especially for the infrastructure-as-code space (the only thing special about this space is that configs tend to be very large, so you're more likely to run into reuse issues), which markets itself as "it's just YAML!" but inevitably all of that copy/pasted YAML becomes unwieldy and you want reusability. At that point, you have a few distinct options: 1. Build a…

Completely agree. Executable configuration in a language with strong declarative programming support is superb. I've had great success embedding Lua into a C++ application for exactly this purpose.

The moment you encode alternation in the configuration file, its time to think about biting the whole Turing complete bullet.

Re: Common Expression Language

#67

This looks really similar to Open Policy Agent[0], wonder how they compare. [0]: https://www.openpolicyagent.org/

I use both in different projects. OPA (and its language Rego) is a good matching and policy engine with declarative blocks, modules, and expressive functions for HTTP headers, JWTs, etc. It's great for security. For building up abstractions and testing arbitrary JSON with complex, pre-defined policies. Testing is built in, and that's great. You can create "functions" and your own DSL for matching/evaluation.

If you want ABAC, use OPA. In every case.

CEL, and CEL-GO, is entirely different. It allows you to evaluate arbitrary expressions with random data. Think a search (eg. linkedin API's crappy search, or log searching, or random predicates).

You would not define complex policies in CEL like you would in OPA. Well, I would not - you can define arbitrary macros and functions in CEL but it is not made for that scale. OPA is more suited for that.

Some examples:

- In OPA, you can define a policy that matches RBAC, ownership/acl, and ABAC in one file. With multi-tenancy. Think: "as a patient, I can see my data", and "as the patient's guardian, if they're under 18, I can see their data". And "As a doctor in the patient's clinic, I can see their data". And "as a clinical director in sudo mode, I can see their data". All in the same policy package, with tests.

- OPA supports "partial evaluation". For example, if you only have a subset of data available, you can evaluate an OPA policy and have OPA tell you whether the policy evaluates to true or what data is missing. This is quite powerful for building up complex auth layers.

- In CEL, you can say "all users > 30 days old". Simple, easy, filtering. EG, with a custom date macro, `date(users.created_at) > duration("30d")`.

In short, use both. OPA for security and complex policies. CEL for user-defined "expressions".

Re: Common Expression Language

#68

I’m curious how this differs from Sentinel, hashicorps language for similar things. Too bad it isn’t open sourced. https://www.hashicorp.com/sentinel

Sentinel is basically OPA - openpolicyagent. OPA is open source and part of CNCF.

Re: Common Expression Language

#69
post #5

I remember seeing this used inside config files for the Caddy webserver. Google seem to like these executable config languages because they've got another open source one ("Starlark") a few notches up in expressivity.

They also have https://github.com/google/jsonnet and https://cue.googlesource.com/cue.
Post reply on HN