Hacker News new | past | comments | ask | show | jobs | submit login
Programming is boring art (ahsmart.com)
120 points by tomkwong on May 30, 2020 | hide | past | favorite | 98 comments



Comments are harsh on what I took merely as a pedagogical example, but maybe it's because y'all have been burned so many times. I agree with you who advise to resist speculative programming. Don't write it till you need it, since all code incurs a burden of maintenance.

But I would like to address a tangent: extracting configuration from code. Let's take the article's example and change it a little. I'll decompose it, since it already has become a function, but often the first step is just a series of statements. (I will also port it to javascriptish pseudocode, since I don't know Julia.) So this might be your first draft:

  response = HTTP.get('https://www.example.com/');

  if (response.status !== 200) {
     email('someone@example.com', 'something is wrong');
  }
Instead of abstracting this into more general functions, I might simply move the literals to the top of the file:

  url = 'https://www.example.com/';
  ok  =  200;
  to  = 'someone@example.com';
  msg = 'something is wrong';


  response = HTTP.get(url);

  if (response.status !== ok) {
      email(to, msg);
  }
The only reason I know to do this is to maybe make changes easier. Even if you never need to generalize your code to other uses, you may need to update it for reasons outside your control. For example, someone leaves the company, and now you need to email someone-else@example.com. Or marketing changes the URL.

Is there a name for this kind of refactoring?


I don't know if there's any name about this specific refactoring change :-)

In general, it is best to create small functions that takes few dependent variables for the intended flexibility. The first judgment here is to decide whether a value should be a constant or variable. Constants would then be declared at the top, and variables come in as function arguments.

You reminded me that another pattern to handle this is to put some of these values as configuration parameters. For example, the email alert may need to be sent to different people for different environments - DEV, QA, and PROD.


In the grand-parent comment's example, you just want it to be more readable, because it is a once off block of code, so that whoever maintains it next can easily figure out what it is doing. Moving it into a function doesn't stop it from being a once off block of code, and we need to be careful not to increase complexity for the sake of it. By your last paragraph you had already introduced a configuration store and the concept of environments!


In all fairness, I led him that way. I called it "extracting configuration from code", which is reminiscent of #3 of the 12-Factor App (https://12factor.net/config).

You can extract config to various degrees. My example is perhaps the mildest: just group it together, near the beginning. You don't need complex frameworks. In fact this technique first caught my attention when I was reading other people's shell scripts.

The next step would be to move the config to its own file. This is very common in Linux. You have some tight binary, that is compiled and hard to change. But then you have config files, often with dozens of options. It's a nice way to do things.

The next step would be to move the config to a different level, no longer in a simple file. This is often either a relational database or environmental variables. Linux commands use environmental variables along with their config files.

For very large systems, this technique is the same in kind, just different in degree. You get fancy specialized systems, like Hashicorp Vault, to store your configuration, at least your secret ones, like passwords and stuff.


It's "extracting constants".


>Is there a name for this kind of refactoring?

I'd call it introducing a few variables.


> There is nothing wrong with this function. Really. It does exactly what it should do with the least amount of code. In fact, this is probably what I want to deploy in production as well. But, it is inflexible.

It does one well-defined thing, and does it well! That's the good kind of 'inflexible'.

> A skillful programmer looks at the problem and says, hey, why don't we build an abstraction layer to make it more flexible?

In this example, the additional complexity just doesn't seem justified. You ain't gonna need it. [0] Unnecessary abstractions cause bugs, bloat, and baggage. The article then goes on to acknowledge this, but I really question the chosen example.

> Just having these few abstractions opens up a lot of possibilities. Why? Let’s suppose that you have 3 different kinds of fetchers and 3 kinds of notifiers. Now, you can easily compose 3 x 3 = 9 different kinds of health checks.

You've just introduced an exponential explosion into your testing burden. The pay-off: additional functionality that might be useful later.

edit On reflection I suppose it's not a 'exponential explosion', it's merely a 'multiplicative explosion'.

> Enjoy your programming life. It's a fun art!

The article doesn't go into detail on what it means here, but the more serious the software work, the less the artistic mindset applies. [1]

I think the most sensible approach to software engineering is to draw satisfaction from solving a challenging problem well. Things like 'programmer freedom' strike me as false idols.

That said, I'm a sucker for elegance (a famously subjective commodity), so maybe I'm a hypocrite.

[0] https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it

[1] https://www.fastcompany.com/28121/they-write-right-stuff


Ding ding ding. I agree one hundred percent. This isn't elegant, this is needlessly over engineered and now much more likely to slow development. The biggest cost isn't lines of code, it's understanding abstractions.

What happens when an "abstractnotifier" blows up? Where does the error happen? what are the possible side effects? What systems might be impacted?

What happens when 'alert's start failing? Is it queued/buffered? Do I need to worry about OOM errors on systems? Will it retry?

I lead a team of developers - This kind of abstraction tends to slow everything down. The only place it fits is during a refactor of software delivering real business value already. Basically - You can do this if you know exactly what your requirements are, and this nicely solves them.

If you do this before you understand EXACTLY what you need, you're going to be wrong. You will abstract the wrong pieces, with the wrong assumptions. I promise you. Then later you have to rip it all apart anyways, except now instead of 4 simple lines with clear consequences, you have a bloated monster of bad assumptions.


>If you do this before you understand EXACTLY what you need, you're going to be wrong.

The main problem with this is culture imo. I agree 100%, but it is so hard to fight against the idea that "real engineering" or being a "good developer" means tiers of abstraction.

To me, being a good developer actually means understanding what your operating parameters are, and then writing the smallest amount of code that satisfies the business requirement. Sometimes (a lot of times!) this DOES mean you have to go back and refactor or completely throw away code. By _design_ you chose to only solve the immediate problem. However, culturally, this is seen as a failure rather than a success.


>You've just introduced an exponential explosion into your testing burden. The pay-off: additional functionality that might be useful later. > edit On reflection I suppose it's not a 'exponential explosion', it's merely a 'multiplicative explosion'.

This statement seems rather inaccurate and misleading. What you thought about 'multiplicative explosion' is the number of integration tests required. Generally, software testing focus more on unit tests, and so in this case, the number of tests is still linear.

> The article doesn't go into detail on what it means here, but the more serious the software work, the less the artistic mindset applies. [1]

This claim seems to be too opinionated. I doubt seriousness makes a difference. I have seen artistic/creative design in some very serious projects before.


> What you thought about 'multiplicative explosion' is the number of integration tests required. Generally, software testing focus more on unit tests, and so in this case, the number of tests is still linear.

I don't follow. The new function has 9 different modes of operation to be tested. I don't see the relevance of the distinction between unit tests and integration tests.

The alternative is to decline to test them all, of course, risking a trade-off between bugs and baggage.

Even in this trivial example, there's a bug resulting from inadequate testing. [0] Perhaps in this example we might be confident enough in the independence of the two parameters that we wouldn't bother testing all 9 combinations, but my general point stands.

> I have seen artistic/creative design in some very serious projects before.

What kinds of projects? Avionics? Formally verified systems?

Formal development solutions like SPARK, and informal frameworks like MISRA C and other restrictive coding standards like [1], greatly restrict the programmer's freedom.

[0] https://news.ycombinator.com/item?id=23365655

[1] https://news.ycombinator.com/item?id=22192656


> I don't follow. The new function has 9 different modes of operation to be tested. I don't see the relevance of the distinction between unit tests and integration tests.

The alternative is to decline to test them all, of course, risking a trade-off between bugs and baggage.

Even in this trivial example, there's a bug resulting from inadequate testing. [0] Perhaps in this example we might be confident enough in the independence of the two parameters that we wouldn't bother testing all 9 combinations, but my general point stands.

I think what he means is that, in unit testing, you only test code units in isolation to each other, with the tests assuming the other parts that your unit-under-test interacts with behave exactly as the unit-under-test expect: If you had n producers that could plug into one of m consumers, you'd test each producer in isolation against a mocked consumer and each consumer in isolation against a mocked producer. That will give you n + m unit tests, which is indeed linear.

Of course this hides the fact that in practice, you'll have n * m different modes of operation, so you'd need n * m different integration tests if you actually wanted to test each possible interaction.

You can get away with only testing units in isolation if the interface/API/protocol between producers and consumers (in this example) is well-defined and rigid enough that implementation details in one part really have no effects on the other part. I think there is lively debate how well this is possible in practice - in effect, this is the whole point of standardized interfaces. However, even attempting this is often a lot harder than it appears and therefore shouldn't be done if not necessary.

That being said, I think it's important to keep in mind that you can almost never write tests for all possible configurations that a program could run in, if your program is non-trivial. You get combinatorial explosion pretty fast, even if you don't use any abstraction at all. And after all, the whole point of a program is that you can feed it with novel inputs without knowing what the exact output will be - becasue finding out that output is what you wrote the program for. So you'll always have to think about classes of inputs and restrict your tests to (hopefully representative) examples of each class.


OP here. The code presented in the blog post was just an example although your points above are well taken. Practically, the decision to do abstraction or not depends on the use case and requirements.


These articles reliably confuse art with craft and technique.

Art is about giving other people rich, engaging experiences that distill and/or highlight some element of relatable human emotional, psychological, and/or sensual experience.

The more unusual, original, and insightful the experience, the more interesting the art.

Doing something difficult with elegance is not art. Solving problems is not art. Complex but comprehensible systems that have "beauty" are not art.

If there's no emotional or sensual content, there's no art - just technique.

There's nothing wrong with technique, and art isn't better or worse than technique on its own terms. But they're different languages with different goals.

Calling software abstraction "art" is like watching someone who has discovered a for loop trying to persuade you they're an expert developer.


> Art is about giving other people rich, engaging experiences that distill and/or highlight some element of relatable human emotional, psychological, and/or sensual experience. The more unusual, original, and insightful the experience, the more interesting the art.

This is a great definition (and this is coming from someone who has studied it for decades).

I wonder, though, if you're being too hard on the writer. Art originally meant the same as skill or craft (https://www.etymonline.com/word/art#etymonline_v_17037). You can see it also in the word artisan, which would likely be applied to a cobbler or carpenter. I believe you are defining the fine arts, which more specifically refer to art purely for the sake of emotional expression, as opposed to the more practical arts, like cabinetry.

Nowadays the sense of the word art has narrowed more to what you're saying, to what our forebears meant by fine arts. But it is not always used that way. Many times I have heard people refer to common, practical activities as requiring some "art". Or they might say that someone who does it with exquisite taste has elevated the activity to art (like, cooking). This is even though it wasn't about, as you say, distilling experience into some other medium.

People loosely use the word art any time that an activity presents some options, any time there is a choice to be made, and a much better result happens when you choose well. By this definition, almost anything could be called an art, or at least could involve art. The only exceptions would be things that are 100% formulaic, like maybe working an assembly line (even then, I wonder if assembly-line workers distinguish some room for art in their duties).

The two meanings continue to intermingle, because all of the arts take craft, and all of the crafts take art. If you want to be a composer, painter, or writer, there are skills to master (the musical scales, paintbrushes, sentence structure). If you want to be a carpenter, chef, or architect, there are always choices to be made, every project is unique in its own little ways.

My point is, your definition is very useful to anyone attempting fine art. But I wouldn't attack people who use the word more broadly (and this is coming from someone who likes writing and who often is irritated by imprecise diction).


Boring means that it's predictable, something you'd expect or have seen before.

In design you work towards a desired outcome, usually something that adresses a group of people, and therefore a set of characteristics. The outcome can be repeated, or changed in a predictable manner. That what lies between the outcome and your intent is what design is obsessed with, process, templating, decoupling from environmental factors, including your own personal characteristics. Sounds like functional and good OO programming right?

Art is the opposite, it's obsessed about capturing unique outcomes, originality. This means that what lies between the outcome and your intent is also about the opposite, coupling unique personal and evironmental inputs.

Performing arts, or arts and crafts are more like design, outcome driven, it's only that they can't remove human inputs because those are also expected to be there.


> Art is about giving other people rich, engaging experiences that distill and/or highlight some element of relatable human emotional, psychological, and/or sensual experience.

Some of the loveliest art wasn't created with any care or interest in anyone else ever seeing it-- but just because its creator loved it for what it was and felt it needed to exist.

If you're a programmer and have never seen true art in a program or its underlying algorithm-- some ingenious machine which moved you with its elegance or serendipity-- then I feel a little sad for your sake. It's not necessarily common, but its out there if you open yourself up to it.


I think you got it on the nose. I think folks who engage in more “traditional” arts (painting, music making, ...) really develop a distinction between these often interacting concepts. When playing an instrument, you distinguish between creative interpretation (art), musicality & sonic control (aural craft, imho), and manual or corporeal dexterity (technique). Of course, one’s ability to communicate a musical interpretation is propped up by the

(In very rare circumstances I might consider a program to be art, like the original metacircular Lisp evaluator, even if the author’s express intent wasn’t to appeal to somebody’s emotions.)


If it's possible to have "bad art", then it doesn't really follow that only beautiful or conceptually interesting programs qualify as art. Either it's all art - the beautiful and the interesting with the boring and ugly - or none of it is. Maybe you'd agree 'artfully constructed' covers what you mean?

I think art is contextual. Some art comes with that context built into the mind of the observer, like paintings or music, or something that tells a story - and there are many, many ways to tell a story.

Other art has its context declared for the observer, like Duchamp's 'ready-made' sculptures.


I think you are technically correct that we often use the wrong word, art instead of technique. However it is common use of "art" to mean "high level of technique" for example in martial arts.

Likewise many people currently use "Corona" instead of "CoViD-19". We still communicate just fine. Still, precise use of words is necessary in technical documentation and a blog post might be considered as such. Maybe not though.


In The Oxford Dictionary and Thesaurus, American Edition (1996),

    art /aart/ n. 1 a human creative skill or its application. b work exhibiting this.
Of course, those are the first of many definitions.


That was helpful and clear, thanks!


I don't consider programming an art in the term of humanities (eg painting/drawing/music etc) but more a craft (eg cabinet making, stonemasonery).

There are assemblers, people that can follow a set of IKEA instructions and end up with a reasonably stable bookshelf. The average starting developer out of college is at this level.

There are journeymen programmers, they have a few years experience, understand some of the nuances, know a bit about what doesn't work, can use the word "strategy" both correctly and ironically.

Then there are master craftsmen, they understand the material they are working with. Know when to use an IKEA wooden dowel and when a custom joint is required. They build cabinetry that can be on display for its own inherent structure and leverage the natural capabilities of the material.

The same applies to programming, both in the small and in the large.


Programming can be everything.

I agree that most programming is craftsmanship.

Code like the Obfuscated C Contest is art.

The code that orchestrates your cloud servers is more like engineering.

Prototypes in language research is science.


One of the most beautiful pieces of code I've ever read is this:

https://github.com/solvespace/solvespace/blob/master/src/srf...

If you have a basic understanding of spline and NURBS surfaces but never knew how you might actually implement that, well there it is. Incredibly readable IMHO.


If you want to write truly beautiful geometric code, watch this:

https://www.youtube.com/watch?v=tX4H_ctggYo

Discussed here:

https://news.ycombinator.com/item?id=22282452


I kid you not, I just watched that 2 days ago at the suggestion of a friend. It will take more viewings and study to digest. Really amzing!


Hm.. my concept of beauty greatly differs from yours. This code looks completely mechanical to me, the opposite of "beautiful" (but it's great code nonetheless).

Beautiful code to me involves the creative composition of parts to form a whole in a way that seems obvious only in hindsight, but takes a form of "genius" to come up with.

I've written a few compilers and seen how the way you model the problem radically changes how easy/hard the implementation of "features" (as opposed to said "model") becomes. That, to me, is programming beauty, therefore, art. Code that model the problem so well that it brings up clear as water problems you hadn't event thought existed. Code that makes apparently difficult transformations trivial. I wish I could give you some examples, but I can't think of any right now. If you know of some, I'd love to look at it.


I can appreciate that distinction. The code I linked is mostly clean and readable, but it also does things IMHO very simply - that's not to say it does simple thing though some of them are. I was taken aback the first time I read the last function.

I agree that choosing the right definitions and structures can make more problems solvable. That's a major driver of data structure choices - the things we build need to support the things we want to do, and getting that right is also part of the art.


I see a lot of beauty in this.


sorry, but I see no beauty in this.


You have to read it to see the straight forward simplicity in it. Like I said, it also helps to have a high level understanding of the subject matter. The culmination at the end - finding the intersection point of 3 parametric surfaces - is artful IMHO.


I'm right there with you.


> A skillful programmer looks at the problem and says, hey, why don't we build an abstraction layer to make it more flexible?

No he doesn't


On the other hand looking into my internal glas orb and expecting the next possible or useful use-case amd making my code flexible / abstract, while keeping it readable, enough to also represent that use-case has saved me hours time and time again.

I think there is something to say for not overdoing it, but for not mindlessly implementing only the thing either. Thinking about what is the next abstraction that includes the functionality your want to implement and also is useful to implement anyway, because you already expect the need for flexibility in a certain direction.

It depends probably on what type of software you write. Just a few procedures in a legacy code or a little command line tool, standing on its own for example.

Certainly implementing only "the thing" gets the job done though. Perhaps doing more is doing more than what one is paid for.


I write code that lasts decades and I can promise you a glass orb is unnecessary.


100% agreed. Code should only be as flexible as necessary to solve the intended problem along with a very cautious estimation of how that problem will evolve in the future.

Small critique: s/he


Was on mobile, punctuation is a PITA but normally I use s/he


I don't disagree with your title. I pretty strongly disagree with your content.

You started with a simple solution that nicely handles the current needs.

You then over-engineered a solution so badly that you haven't even noticed the 'url' param isn't used in the last method you've shown.

You went from simple enough a junior dev can make meaningful changes, to bloated enough the original author is fucking it up.

Don't do this. Wait until you actually have a REAL use case for adding complexity.


Yup, I also strongly disagree with the OP article. The most frustrating codebases I've dealt with are those with layers and layers of overly clever abstractions, and over-engineered generalizations which will never be used before the code is refactored and rewritten. They are hard to understand, not well documented, difficult to test, and frustrating to debug. They often have tons of buggy edge-cases due to the combinatorial explosion of inputs, assumptions, and code paths. The older I get, the stronger I believe that simple is beautiful, and definitely not boring. Simple is often harder than complex.


OP here. Thanks for the note.

The intention to illustrate the power of abstraction. Based upon yours and other people's comments below, perhaps it wasn't the best example.

I did correct the typo about 'url'. Best regards.


A good rule of thumb is to abstract inherent complexity and not incidental complexity.

Loggers are examples of incidental complexity. There is nothing fundamental about sending the warning by email vs slack vs irc. The way to deal with this is not to keep adding more and more options, because you end up with combinatorial growth in the number of interactions, it's to make it company policy that you only use email and discipline anyone who doesn't.


> There is nothing fundamental about sending the warning by email vs slack vs irc.

I agree with this but I would put it somewhat differently. To me, notifications are a separate service, and whatever options there are for notification should be orthogonal to whatever is doing the notifying. If company A's policy is that notifications only go by email, nothing else, while company B has email, slack, and irc, that's for their respective notification services to worry about, not for each individual application that is using the notification service. To the application, it should be send_notification(content, recipient) and that's it.


Have you considered the power in having little abstraction? There's a whole school of thought (the APL/J/k community) that thinks these kinds of abstractions are not just unnecessary, but actually harmful. After trying my hand at "abstractionless" programming in kdb+/q, I tend to agree. When your entire program is only a couple lines of code, you don't need to code for tomorrow. You don't need to think about the future. The code is so short you can just throw it away and start over.

And in fact, this is what Arthur Whitney (creator of kdb+/q and Shakti) does. Every new version of k is started entirely from scratch. No code reuse, no libraries, no sharing.


I'm delighted to learn about this perspective. Appreciate the note.

I believe in reusability with software engineering. The reason why legos is so much fun is because you can compose and build things out of simple shapes.

I also agree with you and others in terms of simplicity. I guess what I failed to communicate in the original post was about the judgment that is required to make the right decision, and that caused quite a bit of opposing arguments.

I believe that the right level of abstraction is required for any non-trivial system. Life is full of balancing act - like yin and yang. Too little abstraction is also costly and leads to code bloating and maintenance nightmare.


I understand it was a typo, and I generally think you did an ok job pointing out that over-abstraction has it's costs.

My real problem is that abstractions are Expensive with a capital E. That typo happened because you had to think harder, about more lines of code, for a longer time. You're spread thinner, and the amount of time you spend actually reading each bit goes down. It's easier for errors to slip in. It takes more time to reason about. And worst of all, most people are genuinely bad at coming up with good abstractions - It turns out it's really hard too.

Now - Once a problem has reached sufficient complexity - you need them. But they really should be avoided until you're AT that point.

Using an abstraction too early is overfitting to your current problem space.

To make a more genuine criticism than just pointing out the typo - What happens if it turns out that your next health check 'fetcher' needs to emit events, or requires a callback, or doesn't use a url but a redis connection string?

You haven't avoided the need to change "check()" in any of those cases.

The abstraction just leaked, and now you have to understand every last bit of all that code again. Which is another chance for small errors to slip in, which they will do, because programmers are human and we fuck up ALL the time.

From my experience, the best way to avoid fucking up is to just not do anything you don't absolutely have to. Avoid adding lines, avoiding adding more things to understand, avoid adding complexity, avoid adding abstraction.

Do the job you need to do, and JUST that job. But hey, it turns out that's Boring!


> You then over-engineered a solution so badly that you haven't even noticed the 'url' param isn't used in the last method you've shown.

I think he wrote 'site' instead of 'url', so I'd call it a typo, but... I agree with what you wrote. For me, the article transports a wrong message. It's a thin line between YAGNI, KISS and OMGINTWNT[0]

[0]:"OMG, I NEVER THOUGHT WE'D NEED THAT!" - made this one up, sorry.




Another way to express semantics is the use of Unicode in source code. For example, I have this Julia package that performs Box-Cox transformation, and I was able to use bold face for vector data and greek letters for the parameters as found in research paper and literatures.

https://github.com/tk3369/BoxCoxTrans.jl/blob/master/src/Box...


I’ve been conflicted about using verbose names or symbols for mathematical expressions in code, and I don’t think there’s an easy answer for when to use them. For simple arithmetic expressions, it seems like verbose names are superior because it’s easier to derive their meaning and we already understand the operators at play. When translating complex expressions, however, we usually a priori understand the meaning of the expression with our algebraic mental model and it makes sense to use that nomenclature. At the same time though, someone who is unfamiliar with the particular source of the algebra used would find such code quite opaque. For something like the Box-Cox transform I think it makes sense to use the symbols widely employed by the mathematical nomenclature.

This certainly also depends on the language you are using and the ability to define arbitrary in/postfix operations.

It’s also rather annoying to type them, but that’s also probably because I just haven’t developed a workflow for it.


>It’s also rather annoying to type them

I wonder how mathematicians do this, I suppose they use latex notation most of the time, inputting ASCII which is formatted as the symbol instead of looking up tables


> It’s also rather annoying to type them, but that’s also probably because I just haven’t developed a workflow for it.

That's true. I remember hitting C-c and C-v a lot... XD


Interesting. Thanks for the share.

I wonder if programming fonts could achieve that - like the original author could specify a font for a portion of the code eg. a “destroy_context” or “drop_connection” function could have a scary look.


Yeah! Or syntax highlighting that confers some emotional valence to runtime behavior (allocating resources - say, calling a constructor for instantiating objects - having a different color)


This brought me back to the time my SO tried to explain an 84 year old lady she was assisting what is it that I do for a living.

The consensus was that I'm a writer.

Also there's one thing I ask everyone seeking to get into programming: "are you resistant to boredom?"

This appears to be a good predictor of future success.


I find football/baseball games to be incredibly boring. I posit that successful ball players must be highly resistant to boredom.


Yes I bore easily. Which is why I love programming. It's like having the largest set of legos possible. Infinite possibilities. Making games, graphics, diagrams, music, art, photos.

Glad that I bore easily and programming is not boring.


I consider myself very easily bored, and that's why I ended up programming, because every bit of coding is about eliminating repetition.


> This brought me back to the time my SO tried to explain an 84 year old lady she was assisting what is it that I do for a living. The consensus was that I'm a writer.

Maybe relevant talk from DHH coming to the same conclusion: https://youtu.be/9LfmrkyP81M


Hmm, interesting. I can’t tell, though, if that question means, “do you not bore easily?” or “do you avoid boredom at all costs?”


Something must have been lost in translation then. Pardon, I half of my vocabulary was shaped by RPGs.

I was thinking of the former.


> A skillful programmer looks at the problem and says, hey, why don't we build an abstraction layer to make it more flexible?

A skillful programmer doesn't add layers of abstraction unless there's a good reason or need to.


The article was presuming a need? Otherwise there's nothing to discuss.

Yes, pedantically this approach is only used in certain circumstances. Then, a skillful programmer has a ready set of skills. And so on.


Upvoting this just for the title ... and was disappointed by the article. Rats.


So the clickbait worked.Congrats OP!


Appreciate the upvote anyways LOL


You're welcome. It's an attention economy these days


> How boring is it to produce something of the same shape over and over again.

Same applies to any text written. Yet, few people would argue there aren’t any artists among novelists, screenwriters, and poets.


It's as boring as one's ability to be mindful, non-judgmental/accepting of the moment, and ability to be grateful for whatever's happening right now.

These are all skills I'm pretty sure not mentioned in most programming books/blogs, much less schools.

Boredom comes from within. Pointing at a thing and saying "that's boring" is a conflation of what's really going on: "I haven't learned to enjoy myself in this context yet and am blaming the context for it."


OP here. What you said is very true. Visual impression isn't the only dimension. Nowadays, it seems that most people (especially the younger generation) just want to watch a video than reading a book. There is bounded to be something missing with a different medium.


Does copywriting count as art? Or is it merely the equivalent of CRUD-style boilerplate?


Depends on your definition of art. Good copywriting must be a very skilful trade. Not sure about the whole "must serve no purpose other than itself" aspect.


Any skillful programmer will tell you this is horrible. The 3 rules of thumb of programming are:

1. Paradigm purity is worthless 2. You ain't gonna need it. 3. Less complexity is better.

You just broke all of them.


Git is art. All programming is a solution to a problem. Some of the problems are very pedestrian and the solution is very boring. There have been many version control systems before Git. I remember using SCCS, RCS, CVS, ClearCase and finally Git came along, and just redefined the whole concept. Sure, the CLI may be clunky at times, but the fundamental problem of version control is solved. I suspect, that historically, Git may be considered as a bigger accomplishment for Linus Torvalds than Linux. After all, Linux is a clean room implementation of Unix, whereas Git is completely original.


I thought the origin story of Git was that Linus wanted to recreate the workflow he had with BitKeeper after the Linux project lost access to it. I've never touched BitKeeper so have no idea how similar they actually are.


I find these kinds of near-journal-article-for-self fairly useless. If you think our stuff is boring where'd you leave intel/amd etc doing statistical process control in the domain of mother nature that's got the standard model in her favor? More boring? Less? Or dumb question?

Abstraction is a sort of entropy / Shannon / Kormogorov issue. So let's discuss it there not semi-liberal-arts school fogginess.

Folks let's please keep science in science. One day if QC gets commercial all these flowery articles will disappear. QC is math based. We'll need to deal or get left behind, and by then all this handwaving won't matter in the least.

Now, the other bad of software dev is that today's work is generously semi-formal at best in commercial settings. Not because CS is art, but because requirements gathering, human factors, corporate culture are strongly reactive in the software realm, where mother nature is directly absent.

Here we could help each other to understand management and management us to move this whole ediface along. And here less technical articles ala HBR work well.


IMHO, alert() should be called at a higher level by something that calls check().


A bit tangential, but since OP mentioned abstraction, I'd like to add this: One of the marks of a readable piece of code is that it does not mix different levels of abstractions.

Here's a contrived example:

  if (a < b && c == d)
    createUserProfile();
Instead, do this:

  if (userIsAuthenticated())
    createUserProfile();


When the developer is inexperient, programming is similar to art. You see hacky stuff and sometimes "innovation" that a senior engineer would just call dirty code. Senior engineers however don't do art unless they are explicitly doing it like with computer graphics or other kinds or computer-based art generation, or through movements like hacktivism that are certainly quite poetic. Otherwise it's so far away from art, regular APIs aren't art, databases aren't art, operating systems aren't art. Many engineers have the need to call themselves artists, you should have taken drawing lessons if you wanted to be artists because regular engineering for business is maintainable just if it's as standard as possible and let me tell you that is the opposite of art.


I was a commercial artist for 10 years. The same is true of art. In the visual art world everything boils down to contrast. It may be colour, composition, sequences of shots, silhouettes, animation, or otherwise - but at the end of the day everything boils down to contrast. There is nothing mystical or romantic about art. At the end of the day, it is just a set of rules of manipulation/communication. I would say the same about programming. I find programming more interesting and engaging, but that's just me.


Hey! I’m a person who’s really serious about transitioning from programming to art. Can I pick your brain?


In college a teacher asked us if programming was an art. There is the element of creation, copying and some may say beauty. The artist or programmer in this case use their knowledge, creativity and experience to create something new intangible and subjective appreciation but results can be life changing or solve a really complex problem. In terms of boredom this is subjective sometimes I find it really fun try to solve a problem or fix a bug


I think that when you look at things at a microscopic-level, everything looks boring and unoriginal. For example, every phenomenon on Earth (and beyond) is just an interaction between atoms. Looks pretty boring.

As the OP mentioned, beauty is created by abstraction; an ability to look at the bigger picture and make sense of it. So I agree that abstraction is the most interesting thing in writing software.


Life itself is boring art. Everything else is just an extension of that.


Depends on your Serotonin level


Does it? The only people I know who don't lead a boring life if you look at what they do minute by minute, day by day, are fictional characters in books, movies, etc.

That's why we like entertainment - because it cuts out the boring bits :)

The art part is more interesting. Is there art to someone's life? I'd say yes, but that's because I'm artistic.

If you ask most people, they'll probably be confused by the question. Is your life 'boring art'? 'Huh' is the answer I most expect :)


I'll quote someone

>I can sympathize with a lot of nihilist outlooks on existence, but just because a lot of these might be true, they're not the only ways you can view your flesh or your place in these patterns, as an animal or as a cog in a machine. There are other elements to existence, like imagination, that is a good example. Emotions are a great vehicle for building your own universe and reality, where your function as an animal or cog in a machine doesn't force you into some rote role that drags you into this stripped down reality of raison d'être being purely utilitarian and unchangeable. You mentioned imagination, but emotions make things real. Does it really matter if your imagined reality isn't concrete or factual? What matters is your happiness, right?


That's like someone who eats a lot of junk food complaining that other food is tasteless. Then people who give it up are surprised to see carrots and milk taste sweet now.

That adrenaline action movie junkies think moment by moment life is boring, doesn't mean it is.


Have an upvote fellow depressed


Good Clojure and Ruby code, in that order, is the closest to art. Structure and Interpretation of Computer Programs (SICP) also deals with abstraction so elegantly you could consider it art.


programming isn't art. it's "life imitating art imitating life"


When I hear people talking about programming as an art, I usually assume that the decisions they make about their code tend to be about how elegant and beautiful it is, not efficient and valuable. It's fun and satisfying to write elegant code, but your company hired you to produce value, not art.


Elegant and beautiful things are often also efficient and valuable.



> what does Hardy mean when he says there is no permanent place for ugly mathematics? He means the same thing Kelly Johnson did: if something is ugly, it can't be the best solution. There must be a better one, and eventually someone will discover it.

I don't think Hardy's take really stands up today. There is at least one mathematical fact which has been proven through exhaustive computerised tests, and which no-one has (yet) been able to prove without using computers.

Ugly? I suppose so. Is there a 'place for it'? I don't see why not.

https://en.wikipedia.org/wiki/Four_color_theorem#Proof_by_co...


Right, there is also difference between short-term value and long-term value.


> how elegant and beautiful it is, not efficient and valuable

Perhaps a nitpick, but 'correct' deserves a mention somewhere.

As others have said, elegance in code should generally align with efficiency and correctness.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: