9 ms·
>The author contrasts this with K8s by saying that K8s is declarative. This is not the important distinction. I feel like declarative is some kind of technical
by carlmr 5y ago
>The author contrasts this with K8s by saying that K8s is declarative. This is not the important distinction.
I feel like declarative is some kind of technical manual meme for the last few years. I don't know at this point how often I've read that something is better because it's modern and declarative. Why it's easy to understand because it's declarative, etc.
There's a similar thing with "functional". In that case I at least understand the intuition why it's better, which is because if I/O behavior is constant and you don't have to think of an internal state, like in OOP. It is indeed much easier to divide and conquer when you can understand the parts of the whole individually. And as soon as you understand the parts you can piece them together.
With "declarative" I still have to find out what's the intuition WHY it's supposedly better, until then it's kind of like the 90s, where the washing machine was "better" because it had "fuzzy logic".
- ghayes 5y agoDeclarative here means you’re describing the end state and letting the system decide how to transition from the current state. For instance, you can declare that you need two X (e.g. containers, disks, …) and pass that configuration to the framework. If the framework sees you currently have 1 X in production, it allocates another. If there are three, the framework kills one. And if there are 2, it’s a no-op. The beauty is that if you express what you need declaratively, you’re shielded from deciding the state transition.
- deleted 5y ago[deleted]
- maccard 5y ago> With "declarative" I still have to find out what's the intuition WHY it's supposedly better, Declarative is better because you write what you want to _have_ not what you want to change, which means you need implicit knowledge of the state of the system, and leave the complexities of figuring out the in between to the tool you're using.
- jen20 5y agoAs someone who has spent the last 7-8 years working on declarative infrastructure tooling: this is only better if the tool can work out how to get from where things are to where you want them to be without being destructive. It’s not like these tools are composing pure functions, sadly.
- ClumsyPilot 5y ago> this is only better if the tool can work out how to get from where things are to where you want them to be That's a bit like sating car is only better than a horse if the engine works. The tool has one job, They do ofcourse fail regularly, I feel that devops tools are 10 years behind our development tooling
- jen20 5y agoPart of the reason they fail so regularly is because so many are wedded to the declarative model, in order that they don't have to understand what they are managing and how it operates.
- cle 5y agoThe problem with most black-box declarative interfaces is that you often do care about how things will happen. The real-world limitations often leak through the declarative interface, because you have to care about things like performance, or do things that don't quite fit into the opinionated declarative interface, or have other weird constraints that the authors didn't think of. And then you're in a world of pain, where you have to not only know how to do what you want, but then also how the system will map from declarative->imperative, and then how to massage your declarative input so that it does the right imperative thing. And your teammates too. And you've all got to think about it every time you change the code or upgrade. I've run into this problem in nearly every declarative system I've ever used (examples: SQL, Prometheus, infrastructure-as-code frameworks, dependency injection frameworks, ORMs, k8s, and so on). Neither approach is "better". They have tradeoffs.
- 5y ago
- lordnacho 5y agoIt's what you want vs how to do it: Imperative: open the top drawer, then take out a knife, then take out a board, then open the basket, take out a potato, slice the potato with the knife 4 times in parallel, then turn it 90 degrees and do it again. Declarative: make some diced potatoes however you like, whenever you like. Have it ready for when the frying pan is hot. Imperative lets you be very precise about what to do and when to do it, what resources you need, etc. Declarative lets the system decide things like execution plans (and thus algorithm and resources) so you can spend your time specifying the target state rather than all the steps in getting there.
- carlmr 5y agoI know the difference, why it's implicitly assumed to be better is what eludes me. In my experience, describing the end result in a way the program understands is sometimes much harder than telling the program "do this". Don't get me wrong I think the longevity of SQL shows that declarative can be the right way. However I think there's a logical leap with declarative = better.
- halpert 5y agoDeclarative is better because it’s simpler. For instance let’s say you have a system and you want to add a new resource to it. If you’re using an imperative paradigm, then you’ll write a script to transition the state from the current state to the desired state. Now let’s say you want to spin up a new cluster in a different region, you need to write another script to go from the empty state to your final state from before. With a declarative paradigm, both modifying and creating resources are the same. It’s also easier to understand the current state of the system. In an imperative style, you need to understand every operation that has been performed to know what the current state is. In a declarative system, you just need to look at the most recent declaration. In short, declarative is more scalable and understandable. Another way to look at your question is to ask what is better about the imperative style? Having used both, I can’t think of any advantages. Maybe you could say you have more control with imperative, but is that control really necessary? In my experience, it is not. The additional control just makes things more complex. And of course you can make a overly complex, hard to understand system using a declarative paradigm. But the simplest declarative system can be simpler than the simplest imperative system for achieving the same configuration.
- jhoechtl 5y ago> Why it's easy to understand because it's declarative Whoever came up with that ... XSLT or Prolog are declarative yet I challenge both of them to be hard to understand
- carlmr 5y agoVery good examples. I would put SQL in the "good" column for example. I'm not saying declarative = bad either, just that I don't see the causation.
- nightpool 5y agoBut on the flip side, Excel spreadsheets are declarative, and they're the most commonly used programming language in the world. Declarative programs can be simpler, when simplicity is the goal.
- 62951413 5y agoI'm fairly certain people like me are confused by Prolog not because it's declarative but because it's a logic programming language. Which is more exotic than a functional one with even more esoteric syntax. I have a feeling XSLT would be better known (i.e. be able to justify investment into learning) if not for json/yaml popularity. Though XML is not particularly human readable anyway. The next logical step after https://json-schema.org/ https://json-schema.org/ would be JSLT I imagine. On a related note, Maven is a great example of a declarative build system. Both Gradle and SBT were gigantic steps back.
- pmontra 5y agoThis is a tangent > [in functional programming] you don't have to think of an internal state, like in OOP. You still have to but less than with OOP languages. For example I've got an Elixir GenServer that uploads files to Google Storage and keeps retrying of something goes wrong. The internal state of the server is the list of files to upload. Files get added to the list when the server receives a message with a file and removed when the file is uploaded. Tests have to deal with the internal state, as in OOP. This kind of stateful "functions" are implemented by recursively passing the state to the same function. Tail call optimization helps not overflowing the stack. Of course we have state only where it matters so the servers are few and sparse. But sometimes we have to pass large data structures between functions. They would be the internal state of an object in OOP. Check Ecto's Multi for transactions.
- jolux 5y agoAnd Elixir/Erlang is actually more imperative and stateful than some other functional languages, because of the process model. Sending messages imposes an ordering on the receiver's state. One way you can think of a mailbox is as a continuously-updating imperative program that runs on the "CPU" of its process.
- jasode 5y ago>I feel like declarative is some kind of technical manual meme [...] With "declarative" I still have to find out what's the intuition WHY it's supposedly better, >, why it's implicitly assumed to be better is what eludes me. I think the common generalization of why declarative is almost always better than imperative is simply this: strlen(declarative_statement) < strlen(imperative_statements) Basically, a shorter declaration of a goal/objective is easier to comprehend than a longer list of step-by-step instructions. With imperative code, it's harder to see the forest because you're in the details of the trees. So a more concrete example is: strlen("SELECT * FROM customers where state='CA'") < strlen("open binary db file, seek to disk sector xyz, btree search index id, allocate memory buffer for cursor results, etc, etc") An interesting insight about the declarative -vs- imperative category is that a particular abstraction can simultaneously be declarative AND imperative because its status is relative to other abstractions above and below it. E.g. SQL is typically thought of as declarative but it can be reframed as imperative when it's used to fulfill a higher declarative objective: strlen("We want to increase sales of suntan lotion.") < strlen("SELECT \* FROM customers where state='CA' or state='FL'; select \* from products where category_tag = 'suntan_lotion'; [...more SQL instructions...]") A common definition of declarative is "the what" and imperative is "the how" -- but that's not the full story because an abstraction layer's "the what" can itself become "the how" to a higher level abstraction.
- dempedempe 5y ago> With "declarative" I still have to find out what's the intuition WHY it's supposedly better Declarative is generally better because you move complexity out of your code to someone else's code. In other words, it reduces the LOC you write and have to maintain. For example, say you are writing some code to query Postgres and aggregate a column. The imperative approach would be to query Postgres and do the aggregation yourself. The declarative approach would be to query Postgres and ask it to do the aggregation via GROUP BY. Aside from reducing complexity, it's also usually more efficient to take a declarative approach. Dozens if not hundreds of people have been working on Postgres for almost 20 years now. The chances of your own aggregation algorithm being more efficient than Postgres's is practically zero.
- krageon 5y ago> The imperative approach would be to query Postgres and do the aggregation yourself. The declarative approach would be to query Postgres and ask it to do the aggregation via GROUP BY. These solutions don't necessarily have anything to do with the concepts as you name them.
- jasode 5y ago>These solutions don't necessarily have anything to do with the concepts as you name them. Why not? A "GROUP BY" syntax is -- relatively speaking -- more declarative than handwritten imperative code looping through a cursor and dynamically adding to a keys-values data structure to accomplish the same idea.
- majewsky 5y agoThat's not "more declarative", that's just "more high-level". Using higher-order functions does not suddenly turn imperative programming into declarative programming.
- dempedempe 5y agoA higher-order function is a function that takes a function as an argument which doesn't have anything to do with the discussion at hand. But you are right that it is higher level in that it abstracts away the logic behind GROUP BY. In this sense, all declarative programming is higher level.
- fennecfoxen 5y agoImperative config means you run the code and it does what the code says. Declarative means “some system reads and parses the config, can do clever things to change what happens in different circumstances, show you a preview of what happens, track chances of what the config has been in a straightforward way, audit the config for consistency across several systems or for adherence to selected principles, and do other smart things”. These are possible because the config is a data structure now. You can do things with a data structure you can’t do with a shell script. The script is too opaque and our computers are not yet smart enough to analyze it in these ways. There are great advantages to the simplicity of imperative configuration scripts, which is why shell scripts will not soon die. There is some peril (shell scripting in particular is full of tricksy traps; alternative languages may mitigate this.) There is great power and some peril in imperative config. It’s a choice.
- deleted 5y ago[deleted]
- ClumsyPilot 5y ago> I don't know at this point how often I've read that something is better because it's modern and declarative. Why it's easy to understand because it's declarative, etc. I feel most comments here miss the point of declerative systems - resillience. You write a script to stand up an Application on a clean system, a declarative system does the same. But what if current state is not a blank slate? A declarative system is meant to be smart enough to achieve target state even if machine crahsed half way through the setup last time, or has a different config already running. Writing a shell script that addresses all edgecases is hard. Now, declarative systems do fail, but that's the promice.
- jpthurman 5y agoI agree with the ‘promise’ of the declarative. A useful analogy is human teams. Effective leaders are often good at the declarative - they provide a vision or end state and the creative problem solving team members determine how to implement the stated vision in relation to the current state. The result is determined by the problem solving ability of the element to which the end state was given.
- deleted 5y ago[deleted]
- jimbokun 5y agoIn other words, a declarative system has the capability to do a diff with the current system and apply changes to eliminate those differences.
- j3s 5y agoNo - imperative systems can do that too. Take Chef (an imperative tool) for example - it can trivially examine a tracked file and mutate the state if the state is not correct. This satisfies the "diff" criteria you mentioned above. Isn't Chef looking sort of declarative? The nuance is subtle but important. Let's say you stop tracking that file. In Chef, the file will simply remain in its last known state, because Chef forgot about it. Likewise, if you do the same process on other systems, files will be left in various states - causing configuration drift. This is what a declarative tool is meant to solve. A proper declarative tool would _delete_ the file, because it's no longer tracked, to ensure that the system is in the state the user expects.
- grogenaut 5y agoA common thread I've seen is that preference for declarative or functional often correlates with how you approach systems. Many of our traditional operators / SysDE greatly prefer reams of declarative configuration. They like to be able to look at a system configuration and understand it in totality. Even if there are abstractions. These folks tend to run other people's software, be great at reading manuals, and debugging systems they can't see code for. The reasoning for a given setup is usually in a wiki or is common knowledge (to some extent) in their heads and the organization expertise of running that software for years. Most of our engineers (SDE) hate declarative as it's not DRY, really boring, and doesn't encode the intent as you said. Code based solutions let a developer (who groks code) understand some of the rules behind WHY (to some extent), and developers tend to be lazy and want to move that knowledge out of their head and into computers so they don't have to deal with it. Both sets of people can be right.
- lukev 5y agoIt really doesn't have to be either/or. It's possible to build quite nice abstractions in a declarative style, using real code. This is actually the next generation of devops tools... CDK, Pulumi, etc.
- grogenaut 5y agoBeen using CDK for years, since pre-alpha. I love it and my company is moving very heavily towards CDK, a thing I helped drive. Some of our ops folks still prefer pure declarative. Like down to the explicit yaml and knowing exactly what AWS flags are ticked in what way. They're also much less comfortable with code. It's not an argument it's a preference, it's how their brains think and their comfort zone. They would literally rather see 1.5 MB of zipped yaml then read through CDK libraries. They literally look at the generated CFN over the cdk.
- carlmr 5y agoPulumi looks really interesting.
- carlmr 5y agoI think this is the most satisfying answer I got in this thread yet, the WHY makes sense, and I like the WHY, because it is the simplest way to understand the how. I guess I'm in camp 2.
- metanonsense 5y ago"Promise theory" by Mark Burgess tries to explain why a declarative approach may be desirable for those kinds of systems.