#75: Declarative, imperative, CSV, JSON, and YAML. Do any of these items represent code? We attempt to answer that question in today’s episode.
If you like our podcast, please consider rating and reviewing our show! Click here, scroll to the bottom, tap to rate with five stars, and select “Write a Review.” Then be sure to let us know what you liked most about the episode!
Also, if you haven’t done so already, subscribe to the podcast. We're adding a bunch of bonus episodes to the feed and, if you’re not subscribed, there’s a good chance you’ll miss out. Subscribe now!
Viktor Farcic is a Principal DevOps Architect at Codefresh, a member of the Google Developer Experts and Docker Captains groups, and published author.
His big passions are DevOps, Containers, Kubernetes, Microservices, Continuous Integration, Delivery and Deployment (CI/CD) and Test-Driven Development (TDD).
He often speaks at community gatherings and conferences (latest can be found here).
His random thoughts and tutorials can be found in his blog TechnologyConversations.com.
It's not that I'm never diving into the imperative way of declaring things or expressing things with Terraform. I do. It's just that that's not a common thing. That's more exception than the rule.
This is DevOps Paradox episode number 75. What is Code?
Welcome to DevOps Paradox. This is a podcast about random stuff in which we, Darin and Viktor, pretend we know what we're talking about. Most of the time, we mask our ignorance by putting the word DevOps everywhere we can, and mix it with random buzzwords like Kubernetes, serverless, CI/CD, team productivity, islands of happiness, and other fancy expressions that make it sound like we know what we're doing. Occasionally, we invite guests who do know something, but we do not do that often, since they might make us look incompetent. The truth is out there, and there is no way we are going to find it. PS: it's Darin reading this text and feeling embarrassed that Viktor made me do it. Here are your hosts, Darin Pope and Viktor Farcic.
As we were wrapping up the last episode, you said something to the effect of if you are in the software industry and you're not writing code, you need to go become a lawyer
or a clerk or bartender. Something
yeah. You also said a nurse and then you backpedaled off that one, which I believe is correct. Because I don't know if you're somebody in the software industry and you're not writing code, I'm not sure that I want you to become a nurse. I don't know that once you treating me. But we decided to take this episode a little bit deeper and we've talked around this on the live streams and probably in other episodes. What is code?
Code is something that can be interpreted by machines. That's probably the simplest definition anybody will ever give about code. I like simplicity. Simplicity is good. Right? So if it can be interpreted by machines, it's code. Does that make sense?
Well, just because it can be interpreted by a machine, does that really make it code?
Usually simple things are good things. Uh, things that are easy to follow, easy to understand and what so not, right? Now, if you start saying that, yeah, uh, it's a, if it's compiled to something, then really we can discard Python, right, and it's definitely code. We can probably go into a definition that has a thousand exceptions and then what so not, but yeah, it can be interpreted by machines. It's very easy to to use as a definition. Ultimately that's really what we're trying to do with code. When we write code, we are trying to instruct machines to do something, right? That's the goal.
Yes. But using your definition, a CSV file would be code.
Ah, yes. Why not? Why not?
Ok. Support your argument.
Actually CSV, I'm not sure whether it would be considered code because I'm gonna going to bring probably the first exception, but it's really data. It's in the same level as a, it's not really instructing machines to interpret anything. It is feeding data into machines, right? When you provided CSV file or any other type of data input, you're just feeding it data. You're not deciding what the machine should do. Now, machines after loading CSV file might do something. But what that something is, is not instruction that CSV file. It's instruction in somewhere else, right, that says, oh, when you load this CSV file, if the value is greater than 10, then do this. That is not instruction in that CSV file. It's data, right? You're not instructing machine to do anything. So it's not code.
Okay. So a CSV file as we think of it today in normal places, that's data, not code.
but I could write an interpreter to take in a CSV file as code.
exactly. And that interpreter is code, not the CSV file. CSV file is just data.
Interpreter is code
Yeah, the same argument could be said for YAML and for JSON and other things that are also data representative.
Not really, because let's say if you take HCL from Terraform, for example, which is equivalent to YAML, you're really instructing a machine to do something. You're saying, okay, look, if this VM exists, do nothing and if it doesn't, create it, and if it does, but it's in a different state, then converge the actual into desired state, whatever that machine should be. You are giving instructions. You're not feeding data. You're giving very clear instructions actually.
See, that's where I disagree with you. Based on your earlier definition, to me, a TF file is data.
In a way, maybe. Okay. Let me give you more complicated example. A YAML pipeline. It is really saying execute this step, then execute that step, then go this then do those two in parallel, then converge those two into yet another step and if the exit code of any of those, something else, blah, blah, blah, blah, blah, blah, blah, blah. You are really creating a set of instructions. YAML pipeline for CI/CD pipeline. I don't see it being any different really than what it does than the code.
Right. So this is where the difference moves from data to definition.
Definition is an abstract of data and I'm not a college professor never assumed to be one. So I'm going to screw up the terms, but data is data. 1,John,Doe. That's a row representing a person. Right? ID, first name, last name. But in your YAML pipeline definition, you're defining what the flow is going to be. Dang. That sounds like data again, doesn't it? It's complicated.
That's why I think we're gonna get back to the initial definition of interpreted by machines. We will eventually jump into XML and XSD and then start discussing whether that's this or that. But ultimately we use it to instruct machines to do something right. That's the intention really. I agree that yes, like YAML very often is really data. Let me rephrase. Could it be that it's something that can be interpreted by a machine and it contains our intentions to do something.
Right, because it's that one and two that makes it code.
Yeah. So CSV, yes, nobody really. I mean, somebody may be, but in general, people are not trying to tell machines what to do with CSV. They're just trying to feed some maybe phone numbers into some database. That's what they're really trying to do. But if you go into YAML, really most of the time we are trying to tell machines to do something right. To execute this pipeline, to create this virtual machine to, I don't know, create those resources in, in Kubernetes. We are instructing machine to do something, directly or indirectly.
So it's gone beyond just something that can be interpreted by a machine to interpreted by a machine and it's, what was your phrase that you use there? It was a D word.
It defines our intention to instruct machines to do something one way or another.
Ok, that makes sense. Now, could you have something that takes care of that second part and ignore the first part interpreted by machines? I don't think so.
No, no. If communication is unsuccessful it doesn't matter whether we are talking about now writing code or communication between two people, if it's unsuccessful, then whichever result is supposed to come out to the communication is not going to be pretty.
The construct that you just used there is the key. It takes us back, takes me back 40 years. You said if blah, blah, blah, then blah, blah, blah.That basic construct that conditional get you in. That should be one of your first green flags that, Hmm. This might be code.
it doesn't mean that it's going to be, but you're heading in that direction potentially.
yes. Yes. If there are some conditionals and a yes, because, but. It's actually hard to say that because it really, it really depends on how much we are making those decisions and how much we are letting machines make those decisions. If I go back to one of the previous examples of Terraform. There's a lot of if/else and loops in making my infrastructure. A huge amount, like unbelievably big. But I will hardly ever, write if statement in my Terraform definitions. I'm not really using imperative approach to explaining the machine what to do when using Terraform. Whenever I write Go code or Java code or what so not, then that's that contains much more if/elses because I'm trying to control the flow of something. It really depends on who is the controller of the flow? Whether that's a person writing code or that's a machine.
We've talked around this in a number of places is the actual state versus desired state. Using Terraform that's one of the examples. Ansible, same type example. I define what I want. I hand it off to the interpreter and the interpreter makes it so.
Exactly and when you're defining the desired state, you will hardly ever have conditionals and constructs like that. You're hardly ever going to have complicated, let's say programming constructs simply because you're not making those decisions. You're describing something while traditional programming is more about making those decisions ourselves, or at least, creating frameworks for making those decisions.
So what happens when you do it the wrong way and wrong is going to be subjective. But for something that could be done declaratively and you decide that, well, I don't know how to do that. I don't like to do that. It's easier for me to go write real code. I don't like Terraform so I'm going to go write my own Terraform using Python or whatever language you choose.
So let's start by maybe defining right that there is imperative and declarative way to declare things or intentions or flow or what so not. And that declarative is well suited for defining state of something while imperative is good when we want to control the flow of information, of data, what so not, ourselves. So example of imperative would be basically traditional, I mean, programming languages like Java, Python, what so not, and declarative would be YAML. The problem is when those things get mixed. There is always some gray area, right? Like I said, maybe 10 minutes ago that I would hardly ever write if statements in Terraform form, but believe me, I did. And they're there. So it's not that I'm never diving into the imperative way of declaring things or expressing things with Terraform. I do. It's just that that's not a common thing. That's more exception than the rule. The same thing in a program in let's say Java, right? Uh, it's not that I will never be declarative, but most of the time I'm simply, I'm not. I'm imperative. So there are always some gray areas. Then there are some cases where my whole speech that I just gave you falls apart, like a CI/CD pipelines, right? That's actually as imperative as it can get. Execute this, then execute that. Then, then fork into those three executions. Then go back to the one execution. If this happens, then do this. If that happens, then do that. It's kind of, it's, it's a workflow of kind, right? It's very, very imperative. Yet, almost everybody switched to some form of declarative format for describing pipelines. Almost everybody did this, so it's not me trashing anybody. And it's definitely something that people consider very useful. But it is not really, it destroys my logic completely. It's not really describing state of something. It is really a programming steps and the connection between steps.
So, ignoring the CI/CD pipeline example, which seems to be a really strange mashup of the two; declarative and imperative.If you're a programmer, boy, that's too broad. If you're an application developer, the first thing you're going to think is I need to write code when in reality that may not be truth. And by saying, I need to write code, I'm saying I need to go write a Go application. I need to go write a Spring Boot application. That that might be your first inclination. But then that also tells me that you haven't done your homework to determine if there's already a solution out there for your use case.
Yeah. And where we might or might not agree is that, you know, those other use cases, I would call them code. If you write YAML instead of Go, we are still writing code. People choose their favorite programming language and try to do everything and that tends to be wrong because you're trusting wrong language to express things you know. It's like, I dunno, we speak German when we are mad and then if we would be all tri-lingual and then when we want to make up, then we would switch to French, right, because some languages are better at expressing some things than others. YAML is exceptional at expressing the state of something, just as JSON is, or XML even for that case and writing Java is good for, you know, creating flow of events or requests and what so not. Then we have those very strange mixes where we try to define infrastructure in a programming language, like Java or Go or what so not. Then we have other extreme when trying to write the whole application using XML and XSD. If one is wrong, I would argue that the other one is wrong as well. Right. If writing your web application in XML, which might sound strange to many, but trust me, I did it, half of the world did that. It was a common thing and it was wrong. And I would argue that using let's say Go or Java to define Kubernetes resources or to define infrastructure is just as equally wrong, except that XML went out of fashion relatively fast, and we all have a huge distaste for it today, while programming languages are something that will, some of them are going to stay forever and ever.
And it's sort of funny that we have that dislike for XML because we were being handed a tool, that although it could do the job, it's the example of sure, I can drive a nail with the head of a screwdriver, but I'd rather use a hammer. Just because I can use it doesn't mean necessarily that I should.
Exactly. I mean, if you forget everything, all the practical experience you have with let's say XML. It's not really that different from JSON. If you dislike XML, you're supposed to dislike JSON. And if you dislike JSON you should dislike YAML. They're all the same things. The difference is with whether they have semicolons or colons and whether they have a square brackets or not. Those are such minor differences that all three are actually the same. I think that we switched from one to another more because it was yet another case of something being abused and then because of that disliked, and then we make slight changes, trivial or cosmetic, to get the new format so that all that distaste goes away.
and why do we get those options? Because people got fed up with fixed length formats.
Because you ran into problems, especially with representations of numeric IDs. Okay, fixed length. We have a five field because we'll never need more than five and then all of a sudden that six digits showed up and then everything had to be rewritten. Not only the data format, but the interpreters as well. That's why the XMLs and the JSONs and the YAMLs all showed up. It all goes back to the data interchange or data exchange, if you will. But then people it's like, Oh, well, we could do, since we're able to do this with this, then we can just releverage it for this. And that's where things started to go off the rails, like the XML usage to do web programming. XML is data. If you keep it as pure data easy. Right. That's totally fine. There's great XML parsers in every freaking language that you need to use. I did say freaking right? Yeah, I did.
Yes, you did. That's not a swear word.
no, it's not, but it's morning. And if the other word came out of my mouth. It'd be like, okay, what happened? Let's sort of figure this out here. Using data formats is one thing, because that can be interpreted by a machine. The question is, are you moving that file that you have written from being just interpreted by a machine to also having the requirement that it is defining the state of something else?
Yeah, it is instructing machines to do something. Realistically, when you define Terraform, you're really defining the state of something and that, I mean, you know state in a database is a state of something, but this is a state of something with a clear intention to perform certain actions. You don't know what those actions are, just to clarify. You don't know whether it's going to create something, update something or delete something, but you're definitely hoping to get some, get some.
There is going to be a reaction that occurs due to the action of running your Terraform file through Terraform.
Yes. So I think the summary of all that is that, hey, if you're writing YAML code, you're a programmer. Now, you're writing code. Now we can discuss whether, you know, some people would say, this is, this is low level of writing code. This is high level of writing code. This is easy. This is hard, but you are a programmer. I mean, you're a software engineer if you write YAML. You are not a software engineer if you write a Word documents with daily reports.
But what if you used Microsoft Word to write a CSV? Nevermind.
That should disappear for many different reasons, unrelated with this discussion, I guess.
Yes. If you're using Word to write your data files, you are not a programmer or a coder. Did we answer the question?
What was the question? We had a question?
What is code?
Something that can be interpreted by machines and represents our intention to do something. I added the second latter part only to exclude CSVs from the story.
Is there anything else that we need to define or confuse people more on with this? I mean, seems pretty straightforward.
Yeah. Your machine interpretable, something that define some intention and then we can further divide it into being declarative and imperative. Probably there are other ways to do it. I mean, then there is a gray area, like huge gray area between the two, but in, in broad strokes, that's about it.
and we hit one of the gray areas. Can you name off one of the other gray areas?
One of the other,
Yeah, the first one we did was, um, where I've forgotten and that was only 20 minutes ago.
I mean, I mentioned that, I mean, I am going to use conditional statements in Terraform, but that's really the exception. That's something that we're trying to avoid. It's just that it's impossible to be hundred percent purist about anything. Even when I don't literally write if. First of all, you cannot write if. You can write if it's very, very weird in Terraform. When you write something like depends on, that's almost you tricking the system. That's really if. That's a conditional. It just masked into depends on statement. That's really the exception I think. That's that gray area.
Yeah, because a depends on in Terraform is pure conditional. It's checking, hey, is it, has this other thing, is it in its correct state? There, I said it. If is whatever. Okay. So that's our definition of code. What do you think? Are we wrong? Am I wrong? Is Viktor wrong? Or are we both wrong?
I'm never wrong. I will never admit it ever.
I didn't say you have to admit it.
If somebody finds out that I'm wrong, I will bend my interpretation of that something until I'm right again.
But you won't break it. Actually, you might break it because, no, I won't go there today. Okay. What is code? Let us know what you think.
We hope this episode was helpful to you. If you want to discuss it or ask a question, please reach out to us. Our contact information and the link to the Slack workspace are at https://www.devopsparadox.com/ contact. If you subscribe through Apple Podcasts, be sure to leave us a review there. That helps other people discover this podcast. Go sign up right now at https://www.devopsparadox.com/ to receive an email whenever we drop the latest episode. Thank you for listening to DevOps Paradox.