Live data from Hacker News

Imperative configs are out; Declarative configs are in

prodvana.io

81–90 of 94 posts

Re: Imperative configs are out; Declarative configs are in

#81
post #67
post #64

Earlier quoted context omitted.

This is an important concept in my work. From experience, there is a pretty simple litmus test. It is pretty well understood that the word “imperative" denotes a system where the user describes a series of steps. The system executes the steps, in the end result bringing its universe to a desired state. The user does not need to describe what that is to the system, but a proof of correctness would decide whether that…

> Now, a declarative system is one where the user describes the desired end state and invariants on the admissible intermediate states of the universe. The system needs to figure out the current state of the universe, find the difference and find an admissible path to eliminate the difference. The litmus test to discern the two types of systems is whether the system concerns itself with the difference as a primary co…

> Declarative systems work by generating the desired state 'from scratch', often with some kind of efficient cache.

This is an option, but it is certainly not a requirement. If I say "I want cheeseburger", it is irrelevant to me if the cheeseburger is made from scratch or had been partially assembled ahead of time.

You are concerning yourself solely with configuration that can be generated not only declaratively, but also fully deterministically, but configuration systems can indeed exist where the environment isn't sufficiently deterministic. In such cases, taking the current state of the world, the user's request, and then determining the appropriate (and preferably minimal) actions to take to harmonize those without having to have them specified by the user is a declarative approach.

For example, I can go to the AWS console and turn up a job with a set of parameters, or I can have a configuration file and a daemon and if

    {
        cpu: 5,
        mem: 20,
        image: "my_docker_url",
     }
is present in that file, I can then assume a job meeting those specifications exists, and if not present the job will not exist. The daemon might do this by shutting down all the jobs and starting new ones every time the file is parsed, but that is probably not great. Approaches that only restart changed jobs, or which can dynamically resize jobs that support such things might lead to significantly better performance of th esystem as a whole.

Re: Imperative configs are out; Declarative configs are in

#82

"My dad switched from working with a map printout without knowing real-time conditions, the imperative flow, to Google Maps with turn-by-turn directions, the declarative flow." There is no such thing as an imperative or declarative "flow". By its very definition, declarative does not have "flow". It is just a statement. Imperative (in programming) literally means "describing steps that change state". Declarative (in…

If felt as hand-waving as reading that "Clean Code" guy.

> Before you say "what about template files! jinja2! go templates! hcl!", that is merely a DSL, which is no longer a configuration file; it is effectively a program in a crude programming language, interpreted by an interpreter (the program loading the file).

It will devolve into messy "imperative" code writing "declarative" "configuration"? or whatever using templates, so there's no point in being a purist about The One True Way.

Re: Imperative configs are out; Declarative configs are in

#84

"My dad switched from working with a map printout without knowing real-time conditions, the imperative flow, to Google Maps with turn-by-turn directions, the declarative flow." There is no such thing as an imperative or declarative "flow". By its very definition, declarative does not have "flow". It is just a statement. Imperative (in programming) literally means "describing steps that change state". Declarative (in…

Declarative would be "I want a cheeseburger." Imperative would be "Get me a bun, and some lettuce, and tomato, and mayo, and raw

Is there a reason it couldn’t be “Give me a cheeseburger”? This declarative camp narrative kills me sometimes.

Re: Imperative configs are out; Declarative configs are in

#85
post #64

Earlier quoted context omitted.

> Even when the configuration file "describes a series of steps to change state", it's still declarative, because the configuration file is still declaring to the program how to operate Not sure I buy that logic. With that reasoning, all code is declarative because it's "declaring to the interpreter/compiler" how to operate. I think he's making the same point you did. In one case, the config file is laying out a sequ…

This is an important concept in my work. From experience, there is a pretty simple litmus test. It is pretty well understood that the word “imperative" denotes a system where the user describes a series of steps. The system executes the steps, in the end result bringing its universe to a desired state. The user does not need to describe what that is to the system, but a proof of correctness would decide whether that…

This is also not declarative vs imperative. It is declarative with a functionalty vs imperative without it. A shell script could also check which parts are missing or outdated and do incremental build. I’m not any good at shell scripting so here is a similar pseudocode:

  import cc, ld, glob, make

  // make defined as:
  fn make(to, from, how) {
    if (exists(to) && mtime(from) 
It’s basically the same as Makefile, except that out “make script” doesn’t know about goals anymore, only steps to take. Do we need that goal-knowledge in a declarative format is an open question, because you can wrap these make() calls in a function named aout() and that becomes your declarative goal. However declarative your config/data is, you still pass it to some evaluator like `make` at the end of the day.

Re: Imperative configs are out; Declarative configs are in

#86
post #59
post #55

Earlier quoted context omitted.

Because "burn it all down and rebuild everything" is by far the easiest orchestration to create from a declarative config. And is almost certainly not what any technician is going to want to happen to their production system.

Sort-of a nitpick, but for stateless services that's _precisely_ what you want to happen!

The clients and network have state. If you kill every service, and set everything up from scratch, your users are probably seeing an error message. Their connections all died and the retries failed while you were spinning up the new version of things.

Re: Imperative configs are out; Declarative configs are in

#87
post #85
post #64

Earlier quoted context omitted.

This is an important concept in my work. From experience, there is a pretty simple litmus test. It is pretty well understood that the word “imperative" denotes a system where the user describes a series of steps. The system executes the steps, in the end result bringing its universe to a desired state. The user does not need to describe what that is to the system, but a proof of correctness would decide whether that…

This is also not declarative vs imperative. It is declarative with a functionalty vs imperative without it. A shell script could also check which parts are missing or outdated and do incremental build. I’m not any good at shell scripting so here is a similar pseudocode: import cc, ld, glob, make // make defined as: fn make(to, from, how) { if (exists(to) && mtime(from) It’s basically the same as Makefile, except that…

An important difference here is that your shell script executes the steps in the order you defined. Make performs a topological sort on the required rules, so in the general case, a Makefile doesn't explicitly define the ordering of the steps, but instead the make runtime figures out an order on its own based on the dependencies.

The Makefile is a (default) goal and a sea of possible actions from which make creates a plan of action.

The shell script steps are manually ordered by the programmer.

Re: Imperative configs are out; Declarative configs are in

#88

"My dad switched from working with a map printout without knowing real-time conditions, the imperative flow, to Google Maps with turn-by-turn directions, the declarative flow." There is no such thing as an imperative or declarative "flow". By its very definition, declarative does not have "flow". It is just a statement. Imperative (in programming) literally means "describing steps that change state". Declarative (in…

Most Java configuration files are a series of method calls laid out in XML or YAML. These are clearly imperative, the bun-and-patty imperative.

Re: Imperative configs are out; Declarative configs are in

#89

"My dad switched from working with a map printout without knowing real-time conditions, the imperative flow, to Google Maps with turn-by-turn directions, the declarative flow." There is no such thing as an imperative or declarative "flow". By its very definition, declarative does not have "flow". It is just a statement. Imperative (in programming) literally means "describing steps that change state". Declarative (in…

> let's write programs that are functional enough that we don't need to write configuration files that are mini-programs

...or procedural programs while we are at it.

I don't disagree with your argument, but the definition can be extended in this use case. If we assume the "configuration" of the software is the target destination. What you can configure imperatively perhaps is in contrast to that what roads to take or not and I believe the term fits reasonably well without it losing precision.

Re: Imperative configs are out; Declarative configs are in

#90
post #78
post #74

Earlier quoted context omitted.

Not when your infrastructure includes your data store, though Then the service is no longer stateless.

I mean, you aren't wrong. But I am challenged to think of a service that doesn't store state somewhere. And you ignore the other situation. Even a fully "stateless" service that literally just responds to things probably doesn't want an outage just to deploy a new version.

That's true. The way we solve it is by splitting our infrastructure deployments in two parts: a volatile part and a persistent part; the volatile part is versioned by buildnumber, so each deployment is side-by-side with the previous one. The drain/switchover is a manual process for now as we have a user acceptance step in the middle.

It gives us more confidence when deploying the stateless part, but sadly it also means that the persistent deployments don't get as much exercise as the stateless part and are somewhat more prone to bitrot.

Post reply on HN