Hacker News new | past | comments | ask | show | jobs | submit login
ALL code is ugly (gist.github.com)
43 points by old_sound on May 13, 2010 | hide | past | favorite | 59 comments



  And, regarding "ugly"... ALL code is ugly. Yours, mine, everyone's. Code Is Ugly.
  Just face it. When someone says "beautiful code", hear "beautiful rotten entrails".
  The only beautiful code, the most clean code, is no code at all. If it's there, it's
  ugly. The unfortunate fact of software development is that, in order to create 
  beautiful software, we must use ugly code.
The premise that 'all code is ugly' is never really substantiated.

I believe code that accurately and clearly portrays the algorithm is beautiful code. For example, quicksort in Scala is concise, and reads like the mathematical description of the algorthm:

  def sort(xs: Array[Int]): Array[Int] = {
    if (xs.length <= 1) xs
    else {
      val pivot = xs(xs.length / 2)
      Array.concat(
        sort(xs filter (pivot >)),
             xs filter (pivot ==),
        sort(xs filter (pivot <)))
    }
  }


... which is butt-ugly compared to QuickSort in Haskell:

  qsort [] = []
  qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++ qsort (filter (>= x) xs)


Yes, and now try this:

    import Debug.Trace

    qsort [] = []
    qsort (x:xs) = trace "(Called)" qsort (filter (< x) xs) ++ [x] ++ qsort (filter (>= x) xs)

    Prelude> qsort $! [1..100]
Problem is, both of these "cute implementations" would be unusable in practice. It's hard to find beautiful code in 'real world' problems.


While I see the problem with this implementation of QuickSort, I don't agree that "it's hard to find beautiful code in 'real world' problems." I think most programmers have opportunities to write elegant code every day.


Interestingly, this very passage of code is subjected to a withering critique in Alexandrescu's recent article on iteration:

http://www.informit.com/articles/printerfriendly.aspx?p=1407...

(Not that recent, I guess. Nov 2009.)


Nice article, thanks!


I still like the pattern matching version, better. It's more concise, and I can actually follow it easier. (but my brain is weird):

  def qsort[T <% Ordered[T]](list:List[T]):List[T] = {
    list match {
      case Nil => Nil     
      case x::xs =>        
        val (before,after) = xs partition (_ < x)
        qsort(before) ++ (x :: qsort(after))
    }
  }


I agree with this definition of beautiful. The title sounds like yet another opportunity for everyone to display how humble they are. If I heard someone say that at work, it would make me wonder if they're too lazy to try harder.

On the other hand, "make sure that there's as little code as absolutely necessary" is absolutely my prime directive as a programmer.


Agreed, it never ceases to amaze me how some developers seem to love writing so much pointless boilerplate code.


Just like the oft-quoted two-line Haskell definition is not really quicksort, this isn't either. It has to be in-place to avoid worst-case O(n^2) space.


Touché.


I've noticed people often get bogged down on the issue of "beautiful" code in focusing on the syntax of the language. But that's only a tiny fraction of what makes code beautiful. The true beauty is in the underlying algorithm or idea that the code is implementing. Much like calculus problems aren't what I would call beautiful, but the underlying mathematical principles are.


Code is ugly or beautiful based on what you're used to seeing. This is the reason for the endless style debates: the way you're used to working just looks better to you.

Whenever I find a new way of working which has actual benefits, I just use it until it looks better to me.

In this case, it looks like there are real benefits to the comma-first method, so I plan on getting used to it.

P.S. By the way, the things you're talking about (clear, accurate algorithms) are not the things the author is talking about. He's talking about style, you're talking about substance. In your example, changing the style to C++ style brackets instead of K&R wouldn't make your point any less valid.


I always thought that code is like babies' diapers.

I'll change my own. I'm so used to the smell, it don't even notice it anymore.

You change your own. It smells so bad my eyes are watering.


And young people who have not had kids yet think that every diaper they come across needs changing.

Good analogy.


As contrived as those examples are, Python does have one feature that I currently miss, which is that trailing commas are ignored.

  mylist = [
    "ape",
    "bat",
    "cat",
           ]


If you'd like trailing commas in your JavaScript, one of the tiny things that CoffeeScript does is allow trailing commas, or for commas to be omitted altogether on multi-line array and object literals.

    list: [
      "ape",
      "bat",
    ]

    list: [
      "ape"
      "bat"
    ]
.. are the same.


And in Clojure, all commas everywhere are whitespace. You can use them, or not use them, even on single line expressions.

(list a b c) == (list a, b, c) == (list a b, c)


This feature is also in C and in Go language. It makes especially easy to write code generators, because you don't have to deal with first/last special cases.


I love this feature, but it bites me in the ass every time I work in a language that doesn't support this - like javascript and SQL.


"If you disagree, then apparently, "clean" just means "looks like what I saw yesterday and the day before"."

  Well
  , sometimes the way it was done yesterday simply _is_ the right way to do it
  . Of course
  , one can occasionally try to challenge fundamental grammatical conventions like putting punctuation on the end of a sentence instead of the front of a line
  . To me
  , "clean" or "beautiful" code is both easy to read and understand and follows the conventions and best practices that have proven themselves over and over
  .


Comma-first is beautiful! Comma-first is functional.

When we make lists, do we put the * at the end, or up front? Comma-first serves the same purpose. It delimits a new entry. "here is a new entry! here is another!"

Comma-first is column aligned with the least about of white space. It visually identifies the list as such, set apart from other code. Easy to parse, easy to skim, easy to elide, depending on your need.


If separators are meant to be put before each item, as in comma-first style, they shouldn't have been commas in the first place. Commas should be used just like they're used in natural written language. If I were to design a language that uses comma-first style, I'd replace commas with bullets:

    var a = "ape"
      • b = "bat"
      • c = "cat"
      • d = "dog"


"Note how the errors pop out in the comma-first style."

So what? Any decent IDE will highlight this error for you anyway.


Not the ones I use.

But actually, there are other benefits: easier to add new lines to the list (just duplicate the previous one and change the value; no need to remember to add a comma at the end of the last item).

Also, someone mentioned another (small) benefit in the comments: when diff'ing files, using comma-first will only cause one line of difference, instead of two.

These are all small benefits, but since I can't think of any disadvantages to the comma-first style, I think I'm a new "convert".


For anyone interested, the JS Tools bundle for TextMate alerts you of errors in your JS every time you save.

http://github.com/johnmuhl/javascript-tools-tmbundle


I don't use JS, but in PHP you can add a comma after the last item, which I usually do, and therefore I don't have the problems that you encountered. Of course, I believe that people should do what works best for them, and if you find comma first easier to work with, then great!

Edit: And in response to your first comment about your IDE not supporting this: Is it not trivial to identify a syntax error in JS when you attempt to run it? Surely the intepreter (browser?) will notify you of the line that the syntax error occured on?


Yeah, I'm also used to adding a comma after the last item (in C, C++, Python).

One of the problems is that this is an error in Javascript, but only in IE. Which means code will work fine while you develop, but when it comes time to test, it will suddenly stop working.

The good thing about this way is that it's also very easy for humans to spot the error. Bottom line, catching the error while you code is always better than catching it after you compile. Also, this method has the advantage of working in all the languages I work in.


What a misleading title. This is about putting commas in array initializations before the next line or after the last line and argues that ALL code is ugly, so it does not matter if it looks akward.


I think this is just an example. If the author really tried to demonstrate that all code is ugly... Well, it would be a very long gist, don't you think?


In determining the best coding style, ease of spotting errors is one thing to consider. Another is ease of interpreting correct behavior. At a glance, comma-first is harder, but that may just be because I'm used to comma-last.


Sure code is ugly. So is paint when it's sitting in it's container. But when used by someone with skill, great works of art are created. Same goes for code. Out of context it's ugly, but what it creates is beautiful.


These examples are ridiculous.


Exactly, seeding a long array has never been pretty. Some languages allow you to get rid of the comma but that's about all. Get over it.


I disagree with the title statement, as there is little in life more subjectively judged than beauty, but the post itself is very well written.


I've sometimes had my moments where I thought "no code could ever look good". If you read enough DailyWTF-like resources you'll gain a sense of pessimism about code.

My humble attempt to find some code that's pleasant to look at: http://lovelyco.de.


All code is ugly, but some code is uglier than other code.


Not mine.


jslint solves all of these problems.


ALL code is ugly. Yours, mine, everyone's. Code Is Ugly.

I couldn't agree more. It's 2010 and we're using text files to describe rules. We're using text files to describe data.

My God. Everyone just stop what we're doing and look at your code. Look at it! It's worse than ugly; it's monstrously stupid. It's idiotic to a degree that beggars the mind. And here we are, in 2010, ignoring the elephant in the room: that code, the way we do it, is petulantly retarded.


Your comment is long on hyperbole, short on reasoning. What, specifically, is wrong with a textual representation? What alternatives do you suggest?

People have tried more sophisticated representations than text before. In my experience, they offer little benefit, while throwing away a rich ecosystem of tools that work with text. It seems to me the most promising advancements have been in tools that work intelligently on top of simple text files, rather than trying to replace them.


Yeah, it was a bit troll-y, I know. But sometimes the Diogenes in me comes out and really, we all need to be slapped in the face and asked, "This? Is it? This is what we've done?" Hardware doubles every eighteen months. If it was a stock it would blow the markets away. Software is a T-Bill. It barely covers inflation. Shame on us for "having tried more sophisticated representations than text before" and then giving up when it didn't immediately pan out.

We can do better.


Humans have been writing language as text for thousands of years. You're going to have a hard time changing it.

What would be worse is something like mathematical or musical notation, with non-trivial layout rules and endless ambiguities. Or a complex binary format that only a computer can decode. Text files are actually pretty damn perfect as a simple mapping from computer (raw data) to human (language).


Why in the world would we want to make raw data to language?

You use a spreadsheet for your budget. You use an accounting system at work. Yet you use a text file to describe the mission critical rules your business runs on.

This is the misconception we've run into: that we think we need to move programming languages to human languages, when human languages are bereft of concision and determinant qualities. We need to move in the opposite direction.


So let's assume we manage to tackle all the problems associated with non-textual formats (merging, compatibility, opacity, etc). What does this new way of programming do better?


I would say it the other way. When we can really free ourselves from text, we'll have made the main core changes that have been needed to make programming better.


Given that human ability to think with abstractions is likely connected to our ability to use language, I don't see why textual representation would be the fundamental problem in programming.

There are subproblems (e.g. state machines) in our craft that benefit enormously from different kind of (visual) representations, but in my opinion textual representations is the best basis for programming.

On the otherhand, you might just hate text files as a way to organize code and would instead use a more elaborate format. Maybe there is better ways, but I think simpler formats fare better when you need to communicate with other people and over organizational boundaries.


Let's see. Text files are easy to diff and merge, to query using regexs, to generate from programs and to parse for input.

I'm struggling to see what is stupid about it.


Regex? Really? Because that's exactly what I'm talking about. Regex is a quite simply the nadir of querying languages and challenges that we ever evolved up from monkeys.


I'd be very happy if you could come up with something better.


SNOBOL did a pretty good job. (I learned it through Icon myself.)


Isn't snobol the ultimate text file processing language?


Any suggestions on how to do it better?


Presumably "graphical" programming tools like labview and gedae. But I'm not a fan of them as they are very mouse-dominated which doesn't do my RSI any good.


No, no, no. Graphical tools suck.

I'm specifically not naming what I'm talking about because I didn't have it in 1996, when I started; I just had the anger and frustration. That's where you start.

You can't get a solution before you realize there's a problem.


OK, for sake of argument let us assume that we realize that there is a problem.

What is this solution then? (It better not involve XML or Excel spreadsheets).


XML and spreadsheets would be lame. And they would both be better than a text file.


So what are you proposing then??


Rei demonstrationem mirabilem sane detexi. Hanc marginis exiguitas non caperet.




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

Search: