I'm Beginning To Think That Much Of Programming Is Wildly Subjective
From what I've seen and heard, a large portion of the programming community - myself often included - feels that much of what goes into programming is objectively good or bad. We all seem to have hills that we're willing to die on because we believe that said hills are objectively the right choice. Vim vs an IDE; tabs vs spaces; functional vs object oriented; relational databases vs document stores; single-file components vs separation of concerns; single-letter variables vs intuitive variables; ORM vs SQL; Go vs ColdFusion; Angular vs React; single-quotes vs double-quotes; idiomatic vs pragmatic; monoliths vs microservices; REST vs GraphQL; the list goes on and on ad infinitum.
When I was younger, and unjustifiably cockier, I used to think that the choices I made were right because, why else would I make them? But, as I get older, I'm more keen to think that it's all subjective. Your choices are right for you; and, my choices are right for me; and, we don't have to sell each other on why we made those decisions. Programming is just wildly subjective!
The irony of it all is that in much of our lives, we're totally happy to exist in the subjective. I think "Death Metal" is probably the worst thing ever; and, death metal enthusiasts probably can't understand why Ani DiFranco is one of my favorite artists; and everyone is OK with that because musical taste is like 100% subjective.
My wife loves Brussels sprouts. It's like literally her favorite thing in the world to eat. And for me, just a faint whiff of Brussels spouts and I literally get nauseous. For me, the idea of eating something that smells like rancid dog farts is just mind-boggling. But, she's thrilled to gobble them down. And that's OK, because food taste is like 100% subjective.
In fact, not only is so much of life deeply subjective, it's also driven by our personal DNA profiles. I'm a morning person - I can barely keep my eyes open after 9pm. That's my circadian rhythm. That's my biology. Being a morning person is objectively correct given my personal situation.
I'm also an introvert. I'm always the first one to leave the party - always! I have about a 2-hour window where I can enjoy being social; and then, after than, I literally get uncomfortable - my body will actually start to ache. I don't enjoy that. I wish people energized me. I wish I could be the life of the party. But, it's just not how I'm wired. And, my family gets that and we're all cool with me being the "anti-social one" because we all understand that we all have our own Truths.
So, we have all this highly subjective stuff in our lives, generally; and it's totally fine; and then, we get into programming and we convince ourselves that there is something so objectively correct about so much of it! We convince ourselves that what feels right for us must feel right for everyone else. And, if someone has the gall to say that they don't enjoy it, we start preaching to them about the power of uniformity (see any argument for linting or gofmt
); and, how they should just suck it up and get on board because, somehow, looking at code that doesn't look like your code is somehow a "Good Thing".
For years, I've had an inkling - that it's all subjective. But, I chalked those feelings up to a feeble mind and a lack of diversity of experience.
And then something magical happened. I started writing Adobe ColdFusion in my personal life and Lucee CFML in my professional life. And, while the two platforms have a tremendous amount of overlap, they also have some big differences.
In particular, Lucee CFML offers a feature called Tag Islands. This feature allows you to use CFML tags, like CFQuery
, in a CFScript
context. What this means, in a Lucee application, is that I can write all my components in script while still being able to leverage the readability, simplicity, and elegance of the CFQuery
and CFQueryParam
tags.
So, in Lucee - in my professional life - my data-access objects look like this:
component {
public query function getThingsByFilter(
numeric id,
numeric otherID
) {
```
<cfquery name="local.results" result="local.metaResults">
SELECT
t.id,
t.name
FROM
thing t
WHERE
TRUE
<cfif arguments.keyExists( "id" )>
AND
t.id = <cfqueryparam value="#id#" sqltype="bigint" />
</cfif>
<cfif arguments.keyExists( "otherID" )>
AND
t.otherID = <cfqueryparam value="#otherID#" sqltype="bigint" />
</cfif>
</cfquery>
```
return( results );
}
}
And, in Adobe ColdFusion - in my personal life - my data-access objects look like this:
component {
public query function getThingsByFilter(
numeric id,
numeric otherID
) {
var results = queryExecute(
"
SELECT
t.id,
t.name
FROM
thing t
WHERE
TRUE
AND
(
:id <=> NULL
OR
t.id = :id
)
AND
(
:otherID <=> NULL
OR
t.otherID = :otherID
)
",
{
id: {
value: id,
cfsqltype: "cf_sql_bigint",
null: ! arguments.keyExists( "id" )
},
otherID: {
value: otherID,
cfsqltype: "cf_sql_bigint",
null: ! arguments.keyExists( "otherID" )
}
},
{
result: "local.metaResults"
}
);
return( results );
}
}
Now, I've been coding in these two competing styles for just short of 3-years. Newness is not an issue for me. Familiarity is not at an issue for me. Comfort is not an issue for me. And yet, after 3-years, using tag islands to execute queries in Lucee CFML feels so natural and so easy; and using queryExecute()
to do the same in Adobe ColdFusion feels like some shit I have to do in order to get things done.
Since I'm currently using both of these techniques - and have been using both of these techniques for years - having such a strong feeling about one of them made me believe that one way was objectively better than the other way.
In fact, when I learned about Tag Islands in ColdFusion, it was one of those Eureka moments! And when I blogged about it, I was 100% confident that I would start a revolution; and, that everyone else would be rejoicing in tag islands, finally able to write SQL queries in Script with ease and with good affordance.
And sure, some people were excited. But, many weren't. In fact, some people - like Scott Stroz - found tag islands to be downright offensive.
At first, I thought maybe these people were trolling me, just being facetious in their disdain. But, eventually, I realized that they weren't joking - that they truly believed that the queryExecute()
function was better - even more readable - than the CFQuery
tag.
But how is that possible? I ran a 3-year natural experiment on myself, using the two techniques side-by-side, and found conclusively that one approach is hands-down better than the other! How could anyone possibly disagree with me?
Oh Shit! Turns out that it's totally subjective! Turns out that what makes complete and undeniable sense in my brain doesn't make complete and undeniable sense in other people's brains. That what is true for me in programming is not true for them.
Now, you might be thinking that I'm over-reaching here - that I'm taking this one tiny thing and trying to extrapolate too much from it. But, as I alluded to earlier, I've had feelings about this for a long, long time! Just look at a quote from an article that I wrote about Linting 5-years ago:
My approach to code formatting is the best. If it weren't, I wouldn't use it.
Formatting is part of my being - an extension of my genetic makeup. And, when I write code, my formatting is the fingerprint that I leave behind. When I'm asked to change my style, I am - quite literally - asked to deny a fundamental Truth of my being.
Or, this post on var
variable declarations in JavaScript that I wrote 7-years ago:
Now, with ES6, there are a lot of really smart people talking about how many of our variable declarations should be using
const
andlet
. But, I just don't connect with the concept. While the explanations that I read are logical, they don't strike a chord in me - they don't seem to be solving a problem that I have.
I have lots of strong feelings about lots of areas of programming. And lots of people have strong feelings that diverge greatly from mine. And part of me used to think that one of us was either crazy, or naive, or simply rejecting anything that didn't seem familiar. But, I'm now much more inclined to believe that we are all correct in our own context. Those strong feelings that we have about some aspect of programming - they are correct. For us. And maybe not for anyone else.
The thing that sent me down this mental rabbit hole was a conversation that I had the other week with Jonathon Wilson - another Principal Engineer at InVision. I was expressing my fear that when I move from using ColdFusion on the legacy platform over to using Go/Golang on the modern platform, I wasn't going to enjoy it; that it wasn't going to spark joy; that I would be unhappy.
In an attempt to alleviate my anxiety, he something to the effect of:
Don't worry about it - ColdFusion and Go aren't that different - it's just syntax.
It was that phrase, "it's just syntax", that haunted me after our conversation. As if the syntactic choices of Golang were something I could just get used to or look past. And, I'm sure I can do that. And if my job requires it, I will do that - I am a team player (or at least I like to think I am).
But, at least for me, "syntax" isn't just part of a language - it is the language. To me, a language is the collection of syntactic choices. For the most part, that's what makes one language different from another. That's why I have zero desire to write Assembly language, and I dream about CFML in my sleep.
ASIDE: I understand that there are "generations" of languages; and that Assembly and CFML are not in the same generation. I use that comparison because the differences are stark and illustrate the power of syntax.
Now, here's the kicker - that's probably subjective. Meaning, there are very likely people for whom syntax isn't a big deal - that they can seamlessly float from one language to another language and not give it a second thought because that's how their brains work. But for me, that is not "The Truth". Syntax appears to be a huge part of why my brain finds some things natural and some things opaque.
It's all subjective. And, there's nothing you can do about that other than try to keep it mind before you foist your perspective on someone else. Just keep in mind that what is true for you may not be true for them, no matter how deeply you feel it in your bone marrow. I say this as much to myself as I do to anyone else. I need to remember that the things I love are just that — the things I love. And, have no bearing on what you might love.
Not Everything in Programming is Subjective
While a lot of stuff is almost certainly subjective, I do still believe there are many truths. I still believe that low-coupling is better than high-coupling. I still believe that favoring composition over inheritance is wise. I still believe that writing a SQL query that uses an index is better than one that performs a full-table scan.
There are a lot of things that I think are "True" in programming. But, these days, I believe that said category of things is a lot smaller than I used to believe it was.
But, That's Not How You Run a Team!
You might think I'm arguing here that everyone on your team should be able to do whatever they want. But, this isn't a blog post about how to run a team. You run your team the way you think you need to. This is simply a blog post attempting to illustrate that the "Truths" you have in your head about programming are, very possibly, only true for you.
To quote the Handmaid's Tale:
Better never means better for everyone. It always means worse, for some.
Want to use code from this post? Check out the license.
Reader Comments
I was trying to come up with a good analogy for the "it's just syntax" sentiment, and I think Food is a good one. Or, at least, recipes for a particular dish.
One person could take a set of ingredients and make a world class, MICHELIN Star version of a dish. Then I - someones who doesn't know anything about cooking - could take those same ingredients and try to put them together and end up creating a terrible, off-putting version of that dish.
In my mind, the difference in taking the "same ingredients" and making two very different experiences - that's the syntactic choices of a language. A dish isn't just the ingredients in it - it's everything about how those ingredients are combined together and cooked / baked. The two concepts are forever coupled to each other.
You can't eat food and just look past the way it was prepared.
Completely echo your thoughts... it is "art" - so by definition is it going to be subjective. Oh and don't forget MVC vs no-MVC!
Like in Math and Science, the experimental outcomes or calculations must be repeatable and consistent. Likewise the code has to perform consistently and should be repeatable - the rest is all subjective.
Along the same lines, I have often wondered about the "learning and maintaining" someone else's code, VS just rewriting it. I know that may not be always practical, but, shouldn't there be a desire the calculate the difference in overheads between the two.
@Sanjay,
Totally agree on the art vs. science. The two concepts must weave together to create a solution. It's like the Matrix when Morpheus talks about how some rules are meant to be bent, other broken. The trick if figuring which are which based on experience.
I couldn't agree more! The "right way" now is very rarely going to be the "right way" in 5 or 10 years. I have never believed in the idea that there is only "one best way" to do things. (This mindset is a big reason why I have always resisted implementing community frameworks). I believe you need to approach each application with an open mind and consider what is best for that application. It may help that I deal with a lot of different applications written by different people at different times. I do however, try to always make sure that whatever syntax choices I make within a particular application is consistent with the rest of the code in that application.
Excellent overall sentiment, Ben. I feel "seen" in the tag islands section. I will not comment further on that (despite feeling like it).
One danger with "it's subjective" is ppl too often use it as a reason to stay on that hill they want to die on, rather than it being a solution to it. No matter what advice they hear, they trot out "it's subjective!" to validate their position, as if that's all the research / investigation / consideration they need to do on the matter. It's basically a version of "lalalalalalaIcantHearYouIcantHearYouLalalalalala"
[now that I think about this, my comment is going to continue in a direction I had not initially planned...]
TBH I feel like you are actually doing this a bit with your mention of Go & "it's only syntax". Jonathon's comment was clearly trying to allay your change-aversion fears, but you're off making a false equivalence to assembly language (granted you catch yerself doing it). It's a bit defensive and ill-informed though.
You are correct that language syntax pros/cons are subjective. However to one still needs to be in a position of being able to compare in an informed way before making any sensible evaluation about the why it's subjective.
You're not doing that, you seem to be falling back on "it's subjective" to justify why you think CFML is "better".
I think you should probably work with Go for a year or so, and then come back to what the (subjective, but now informed) pros & cons are cf CFML. And you should also... JFDI... there's no future for you and CFML @ Invision, whereas there is a future for you with Go. So take Jonathon's assurances as they were meant, and crack on with your future. It'll be a great future mate. Trust me (and everyone else who has said the same).
@Scott,
If I'm working in someone else' code, I do try to keep it consistent with theirs (no matter how much it might hurt my sensibilities). But, if I am being honest, I haven't worked on an application that anyone else is actively maintaining in quite some time (years). Even so, when I have to update one of our Node.js services, when it needs a security patch or something, I'll try to strip out the luxurious white-space and brackets that I would normally use, opting for the given service's desire for terseness 😨
@Adam,
I don't think you're being entirely fair with your evaluation of my reasoning. Part of why I spend so much time talking about "Tag Islands" in this post is because it provides a context with which I have very deep familiarity. You and I clearly have a different personal preferences when it comes to writing SQL, which is fine (to the point of the post); but, what I was attempting to demonstrate was that the two different syntax have a real and non-trivial impact on my enjoyment of writing the code in the various contexts. And, it's not something that I could just get used to over time - 3-years, in fact, has not been enough to remove the relative differences of enjoyment.
Now, to your point, I will have to write Go at some point. That's just the reality of the situation. And, I will do my best to learn Go and write the best Go that I can. But, I don't want to pretend that I believe that it will simply be as enjoyable as CFML.
And, I'm not saying that CFML is "better" than Go; I'm only saying that the CFML syntax seems to be much more enjoyable for Me.
And, I don't want this to be Go-specific post - it was just part of how I get down this mental journey. But, I have trouble imagining that I will ever enjoy the fact that in Go I have to deal with pointers (referencing and dereferencing). I am sure that every single time I have to use a pointer explicitly, it's going to make me sad. And I will think to other languages, like JavaScript, like CFML, where I don't have to think about such things. And, I don't imagine that friction will just go away over time.
Now, before you point out that I haven't really worked with Go, I will say that I had the same issue with Linting. I worked on a team that had Linting for 3-months. Granted, not the longest time; but, it was a struggle to enjoy it every day. It was a constant fight between my muscle memory and the desires of the linter. Now, would a year of working with a linter make that pain go away? I'm not sure.
Anyway, not sure how to wrap up my thoughts here 😆 I'm sure I'll have more to say when I actually start writing Go.
@All,
One thing that I don't think we've touched-on here is the fact that for some (?many?) people, it might not be subjective at all. Meaning, there might be many people who couldn't care less which language they are using or what database they have or what formatting they use.
I mean, the number of people that talk about how they don't think about formatting while they are writing code - it honestly blows my mind. But, clearly, to these people, formatting of the code is just "not a big thing". It's a mindset that I cannot relate to at all.
So, not only are things subjective, the very idea that they are subject is perhaps also subjective 😂
@Ben,
Objectively speaking, my subjective opinion is that the objective fact that some people don't care at all simply furthers the argument that formatting and syntax preferences are indeed subjective. 🤓
@Ben,
I think you misunderstood anything I was trying to say about CFML / tag islands etc. That was pretty much covered by the first four words of my comment: "Excellent overall sentiment, Ben."
Like... I disagree with you on tag islands, but that falls under the remit of "subjectivity". I was not contesting that ;-)
@Scott, 😳 🤪
@Adam,
I don't mean that you were contesting the tag islands stuff; I thought what you were saying is that my lack of experience with Go inherently negates the idea that one can have a subjective experience of a language. I only referred back to the ACF vs. Lucee context because it is a subjective experience with much history behind it.
Anyway, when I have Go experience, I am sure I will talk about it 😛
Nope, I did not mean that at all, bad wording on my part if that's how you read it, soz. EG: you can legit form some sort subjective opinion re cfquery vs queryExecute. Sure.
However I don't think one can make any sort of informed comparison between two languages - or even elements of them - without having a reasonable amount of experience in both so that one has a broadly equivalent feel for the nuances of each.
@Adam,
I'll agree with that. I do review PRs for people on the other teams, so I do have some experience with at least reading Go code. But, I have next-to-no experience with actually writing Go code.
I was recently listening to an old episode of Full Stack Radio, and Adam Wathan was interviewing DHH. In the episode, DHH talked about how the miracle of server-side programming allows us to choose technologies that we happen to love. It really spoke to me. Adam said I could repost a portion of it on the blog:
www.bennadel.com/blog/4455-dhh-on-the-freedom-of-server-side-programming.htm
It dove-tails very nicely with this post.
Post A Comment — ❤️ I'd Love To Hear From You! ❤️
Post a Comment →