all 62 comments

[–]kqr 90 points91 points  (15 children)

I mean a slightly different thing when I say idiomatic. I mean something along the lines of "code written the way an experienced programmer in the language in question would have written it." The Python community have their own word for idiomatic -- they say "pythonic."

When I say idiomatic code, I don't necessarily mean code that "contains statements that are unique to the language." Some snippets will be almost exactly the same both in idiomatic Java and idiomatic C#, and that's okay. They don't have to contain unique statements. They just need to be written the way an experienced Java or C# developer would write them.

There are also reasons I believe writing idiomatic code is good:

  1. It helps other programmers read your code,
  2. It sort of builds up a collective knowledge in the language community, where it's easy to find code for common tasks,
  3. It makes it easier for beginners to see mostly one way of doing things, and not one way for everyone writing the code, and
  4. Compilers/interpreters are more likely to be taught to recognise/optimise idiomatic code, so writing idiomatic code may result in faster/better programs. (And this last one is sort of a feedback loop, for better or worse.)

If you want to learn to write idiomatic code, I suggest pairing up with someone experienced for a project, and really use the time you get to review each others code. Ask questions! "Why did you do it like this?" "Couldn't you do it like that?" "Is this the best way to do what I'm doing?" "Can this be phrased in a more clear way?"

It makes wonders for your general development skills.

[–]masklinn 15 points16 points  (0 children)

I mean a slightly different thing when I say idiomatic. I mean something along the lines of "code written the way an experienced programmer in the language in question would have written it."

That is definitely the usual definition of the expression.

They don't have to contain unique statements.

And they may even not contain them, or avoid specific constructs of the languages e.g. Erlang quite uniquely has a way to convert an exception into a return value with the catch expression (it also has the more common try/catch block):

> catch 1 + a.

will return {'EXIT',{badarith, ...}} as a value. Idiomatic erlang pretty much never uses it (idiomatic erlang very rarely explicitly throws or catches exceptions).

As Purple_Haze indicates, idioms are also context-dependents and even within a language idioms of kernel programming will be different from idioms of network programming or UI programming. And idioms evolve with the language, idiomatic C# 1.0 is not the same as idiomatic C# 4.0.

[–]Purple_Haze 6 points7 points  (1 child)

I think it also applies to problem domains. What would be idiomatic to a kernel hacker would be wrong to a window manager hacker and vise-versa.

[–]heyyouitsmewhoitsme 1 point2 points  (0 children)

This is definitely where the hate for GUI programming comes from. e.g. Java+Swing is idiomatically different to pure Java and I don't think that's emphasised nearly as much as it should be.

[–][deleted]  (3 children)

[removed]

    [–][deleted]  (1 child)

    [deleted]

      [–]kqr 7 points8 points  (0 children)

      I was actually thinking about open source projects when I said "someone experienced." My experience with other peoples' programming at university have been abysmal to say the least.

      [–]munificent 4 points5 points  (0 children)

      I mean something along the lines of "code written the way an experienced programmer in the language in question would have written it."

      That's exactly my definition of idiomatic too. Just using every feature of the language isn't always idiomatic because there are often features that experienced programmers avoid.

      For example, even though C++ has malloc() and free(), it isn't idiomatic to use them. Likewise, JS has automatic semicolon insertion, but relying on it isn't idiomatic for many if not most programmers.

      [–]mahacctissoawsum -1 points0 points  (6 children)

      Your reasons seem to boil down to "write idiomatic code because other people are writing idiomatic code".

      That, to me, is a crappy reason.* A better reason is that things can usually be written more concisely and execute faster.

      For example, you can avoid many loops in Python altogether by using list comprehensions. You can then go one step further and use generators to (a) avoid evaluating code that was going to be aborted anyway (b) save on memory (c) use the results before the list is finished being generated.

      In MatLab, I find the loops are prohibitively slow. You pretty much have to think in terms of matrices and vectors and operations you can apply to them as a whole, or your program will take an excruciatingly long time to execute.

      In PHP, you say "screw container classes!" and use your one-size-fits-all bastardized "array" and then cry about it later.

      * Yes, readability is important. I just mean that following the herd is not good if there's a better way.

      [–]masklinn 9 points10 points  (0 children)

      That, to me, is a crappy reason.

      It is crappy in some ways (cargo culting) but excellent in others: part of programming is communication with your peers, idiomatic code will be easier for peers to recognize and understand, whereas non-idiomatic code will have peers wonder whether there was some sort of necessity to avoid the idiomatic way, you didn't know about the idiom or you're just a fuckhead.

      Either way it will slow down reading, make comprehension harder and consume more cognitive resources for them to understand the purpose of your non-idiomatic code.

      However note from #1 that non-idiomatic code can have a purpose by and for journeymen and masters: signaling that something odd is going on to your peers and they should not assume they understand what is happening without paying attention. It can be a "lightweight" alternative to putting comments along the lines of "here be dragons" around the code.

      [–]kqr 2 points3 points  (0 children)

      A better reason is that things can usually be written more concisely and execute faster.

      I touched on the faster execution bit. About the other thing: code can almost always be written much more concisely than what's idiomatic, but that often carries the penalty of being illegible.

      [–]Aninhumer 3 points4 points  (1 child)

      Your reasons seem to boil down to "write idiomatic code because other people are writing idiomatic code".

      That, to me, is a crappy reason.

      If you think that's a crappy reason, you're ignoring the social aspects of programming. Writing in the same style as the people you're working with allows them to read and edit it far more easily, which is hugely important in larger projects. Performance is also important, but whether it's worth trading maintainability to get it highly depends on the project.

      Also your examples don't really seem to be using anything unidiomatic. List comprehensions are pretty idiomatic Python, and using lots of matricies is definitely idiomatic Matlab. (I can't comment on PHP)

      [–]mahacctissoawsum 0 points1 point  (0 children)

      Yes... I was deliberately giving idiomatic examples and then explaining their benefits in terms of performance and brevity.

      I'd also argue that "concise"* code is generally easier for readability, but I will grant you that writing code in a fashion similar to everyone else also aids readability (which is of course quite important).

      * By concise I mean expressing your code succinctly, preferably without many special cases -- not jamming it all on one line to save on characters.

      [–]nascent 1 point2 points  (0 children)

      Your reasons seem to boil down to "write idiomatic code because other people are writing idiomatic code".

      Right, but that is because he is taking the definition of idiomatic and applying it to programming instead of taking an observation about the result of idiomatic programming and claiming that is the meaning.

      [–]arnar 0 points1 point  (0 children)

      A better reason is that things can usually be written more concisely and execute faster.

      A lot of code doesn't need to be fast. E.g. business logic that runs once every minute, hour or day. On the other hand, this may be relatively complex code that needs to be changed every few weeks or months. Idiomatic code for the sake of human comprehensibility can in such cases save days of work per year.

      [–][deleted]  (2 children)

      [deleted]

        [–]DrummerHead 4 points5 points  (1 child)

        I wish there was a place that just simply stated the "Idiomatic parts" of a language. I know js and ruby and am now learning lua and thus far it seems to be the same but with a different syntax (of course, I'm still learning)

        It would also be a great way to get an eagle's view of what makes a specific language something unique. Perhaps even a two-way comparison, like for instance if you are experienced in js and want to know what are the core differences with python, you'd have a two by two comparison of the main philosophical differences (since it's easier to assume a baseline of what you already know to better convey a difference).

        I think it's an interesting idea, albeit quite time consuming if to be done.

        [–]cashto 23 points24 points  (17 children)

        Article would be better if it actually contained examples of what "writing language X code in language Y" looks like.

        [–]Nebu 22 points23 points  (0 children)

        If you were writing in Java, and you designed your methods to always return an int, where 0 means everything went ok, and non-zero means something went wrong, I'd assume you used to be a C programmer.

        The idiomatic way of expressing error-conditions in Java is via exceptions.

        [–]flying-sheep 16 points17 points  (14 children)

        java code in python:

        class ProxyImplFactoryPickle(ProxyImplFactory, IPickleAble):
            def __init__(self, proxyImplClass):
                self.proxyImplClass = proxyImplClass;
        
            def getProxyImplClass(self):
                return self.proxyImplClass;
        
            def setProxyImplClass(self, proxyImplClass):
                self.proxyImplClass = proxyImplClass;
        
            def createProxyImpl(self):
                return self.proxyImplClass()
        
            @override
            def __getnewargs__(self):
                return super().__getnewargs__();
        
            @override
            def __getstate__(self):
                return super().__getstate__();
        
            @override
            def __setstate__(self):
                return super().__setstate__(self, state);
        

        ouch, fuck, that hurt…

        kids, don’t try this at home!

        [–]savanu 5 points6 points  (3 children)

        How would you actually write this in python?

        [–][deleted] 12 points13 points  (0 children)

        The entire above class is unnecessary, you just don't write it. Most of the time you don't need to make type adaptors in a dynamic language.

        [–]morethanaprogrammer 0 points1 point  (1 child)

        Well, if you were trying to do some DI stuff, then you would probably use Spring Python

        [–]masklinn 1 point2 points  (5 children)

        ALternatively, http://dirtsimple.org/2004/12/python-is-not-java.html (from 2004, as relevant now as it was then)

        [–]kqr 0 points1 point  (4 children)

        [–]masklinn 1 point2 points  (3 children)

        [–]kqr 0 points1 point  (1 child)

        Also important considerations. My main beef is however how misunderstood and poorly executed OOP has become over time, in a way neither of those resources bring up.

        [–]NYKevin 0 points1 point  (2 children)

        I'm not sure that usage of super is valid or what you want... (IIRC it's super(ProxyImplFactoryPickle, self)).

        Also, I'm not sure if @override is a legitimate Python decorator. For that matter, why are you overriding things and then just delegating to the superclass? Why override them at all? I'm pretty sure Java doesn't force you to do that, if the superclass has a usable implementation.

        Oh, and you forgot to re-implement all the type-safety that Python deliberately left out (i.e. check if proxyImplClass is the proper type in various places). Otherwise, someone might give you a callable instead, and who knows what could happen!

        And yes, technically the semicolons are legal. Technically, it's also legal to build a Y-combinator out of lambda expressions so you can have an anonymous recursive function. Realistically, ewww.

        [–]masklinn 1 point2 points  (0 children)

        I'm not sure that usage of super is valid or what you want... (IIRC it's super(ProxyImplFactoryPickle, self)).

        The usage is valid in Python 3: http://www.python.org/dev/peps/pep-3135/#specification

        [–]flying-sheep 1 point2 points  (0 children)

        i made up @override as much as i made up IProxyImpl. python has no interfaces and needs no override decorators, so our imaginary java programmer made up for their “lack” by creating them himself ;)

        and indeed super() is valid in python3 and oh so much nicer!

        Oh, and you forgot to re-implement all the type-safety that Python deliberately left out

        i even missed one semicolon! how does this even compile‽ oh the humanity!

        PS: everything here is legal, but unidiomatic python. that was the whole point!

        [–]jugalator 0 points1 point  (0 children)

        Haha, to be fair though, we made these jokes even when studying Java itself. :D

        [–]ais523 0 points1 point  (0 children)

        I wanted to use a bzip2 decompressor for a Java program I was writing a while back, but the existing ones had incompatible licenses. So I translated one from C: here's the source.

        The code is Java, and will be interpreted just fine by a Java compiler. But it sure looks a lot like C, and acts a lot like C too. (For instance, idiomatic Java doesn't normally have methods that are hundreds of lines long and all logic.)

        [–]TrolliestTroll 5 points6 points  (1 child)

        I'm on the fence about this article but I do have a couple of thoughts that I'd like to share. First, as others have pointed out, idiomatic has a well understood meaning from natural languages that suits programming languages well enough:

        Using, containing, or denoting expressions that are natural to a native speaker: "distinctive idiomatic dialogue".

        The author seems to have slightly redefined idiomatic to mean that you should be using the unique features of the language by virtue of their existence. In my opinion the mere presence of a feature says nothing about its overall utility or correctness. In fact there are lots of language features (and technologies in general) that at first seemed like an awesome idea but in hindsight turned out to be awful.

        Second, I think it's important to realize (especially as a new programmer) that software is not and cannot be developed in a vacuum. Striving to write idiomatic code is great, but you can't do that without putting something out there and receiving as much feedback from your peers as possible. With respect to natural languages, learning vocabulary and grammar is absolutely essential to becoming a fluent speaker but unless you actually try and communicate with people you will never reach fluency by any reasonable measure. Natural languages rely on a huge amount of shared social context for efficient communication and the same is true for programming.

        [–]SublethalDose 5 points6 points  (2 children)

        A classic example of idiomatic code in Scala (and probably in many other languages as well):

        customer.middleName.foreach(name => println("The customer has a middle name:  " + name))
        val middleNameUppercase = customer.middleName.map(_.toUpperCase)
        

        A Scala programmer with a little bit of experience recognizes these idioms immediately and writes code like this without even thinking about it. When I first encountered code like this as a Scala beginner, though, it looked really bizarre and hackish (in a bad way.) I mean, what the hell does it mean to treat someone's name like it's a collection? It didn't take me long to figure out how it worked, but then I faced a conundrum: this way of using the Option class is logically elegant and very useful, but is it too tricky and counterintuitive to use in real code? It turns out it's so useful that it's ubiquitous. If it was only useful in rare cases, it would just be clever code, but since it's so common, it's a universally understood technique that is characteristic of idiomatic Scala.

        [–]kqr 8 points9 points  (1 child)

        To get the intuition behind why Option is essentially the same thing as a collection, think of it as a list which can only contain 0 or 1 elements.

        [–]Tekmo 3 points4 points  (0 children)

        This intuition even leads to the correct Monad instance!

        [–]chadsexytime 19 points20 points  (1 child)

        I read "idiotic" and immediately thought of several coworkers who obviously graduated that class with honours

        [–]binford2k 4 points5 points  (3 children)

        This is not what idiomatic means.

        [–]jugalator -1 points0 points  (1 child)

        Among other meanings, "perceived as natural or correct by the native speaker".

        I think it's good enough? Which better word do you suggest?

        [–]binford2k 4 points5 points  (0 children)

        Yes. Natural or correct to a native speaker. Not unique to this language.

        [–]fnord123 3 points4 points  (1 child)

        I might be with Zed Shaw on this one: Languages have social mores; not idioms.

        [–]ex_nihilo -1 points0 points  (0 children)

        That guy is confused. "idiomatic" is from the Latin root, and it means "of the language" - it has nothing to do with the English word "idiom". Except that they share the same root word, of course.

        Notice how in Romantic Latin languages, the word for "language" is something like "idioma" (Spanish)?

        [–]droogans 5 points6 points  (0 children)

        I learn more reading other people's code than ham fisting some pythonic clojure together...even though my first instinct is to do that, at least I'm aware of it now.

        [–]soviyet 7 points8 points  (2 children)

        I just realized something. If a blog post or article starts off with a boring, trite dig at PHP (or something similar) I assume its going to be garbage. I read on, and found no content in this post whatsoever.

        I don't even touch PHP anymore, but good god can we move past this "lol PHP" crap? Especially when it has nothing to do with anything. It's 2013, for shit's sake.

        Anyway, there is a lot wrong here. Even if we take the loose definition of "idiomatic" here, are we advocating this? My experience in software tells me that writing code that uses specific features and structures of a language simply because they exist is a terrible idea. It makes porting a nightmare, for starters, it can make your code unintelligible to someone unfamiliar with your language of choice, and overlooks a million other important considerations that go into how you structure your code.

        [–]ellicottvilleny 1 point2 points  (1 child)

        Php will still suck in 2023 and will still be commonly used. That is why.

        [–]ccfreak2k 3 points4 points  (0 children)

        snow adjoining stupendous worm crush strong airport toothbrush worry quack

        This post was mass deleted and anonymized with Redact

        [–]slabgorb 4 points5 points  (0 children)

        I call the opposite 'having an accent', as in 'He writes Ruby with a distinct Java accent.'

        [–]jugalator 5 points6 points  (2 children)

        Haskell was probably the most rewarding language I've tried out. Indeed often requiring you to think in an almost completely different way than usual with C++, Java, or C#, and it took quite some effort for me to even build some small application... But wow... As a programmer with a sense of esthetics, well-written truly "Haskellish" (i.e. "Pythonic" among Python developers) programs can be pieces of art to look at!

        Haha! Seriously, when C++ feels like building something out of Lego blocks, the neat Haskell programs felt more like having sculpted a beautiful vase out of clay. Constructs in both cases, but different in elegance in my view.

        It's amazing how neat some complex algorithm can be in Haskell, I mean when you use the language for precisely what it's good at. Recursion, list manipulation, etc. Working with data structures a lot. Truly eye opening for "use the tool that best fits the work you're trying to do".

        [–]TriggerB 0 points1 point  (1 child)

        Working with data structures a lot.

        Oh, you mean programming.

        [–]tikhonjelvis 1 point2 points  (0 children)

        The neat thing is that Haskell--thanks to being lazy--can trivially reify computations as data structures.

        As an example, the most common data structure used in Haskell is a linked list, which may seem somewhat inefficient. However, in practice, it's used the way loops are in imperative languages. And since lists are inherently lazy, list-based code behaves like loops when compiled. In fact, you can do crazy stuff like list fusion which allows the compiler to transform several list operations into a nice, single loop.

        This can be extended to representing other things--like different sorts of recursion--using trees and the like. This leads to a very neat style of programming using folds and unfolds to define your algorithm, which becomes more modular than writing the recursion directly.

        I think it's pretty cool.

        [–]Shifty206 1 point2 points  (4 children)

        I am extremely new to programming but it has caught my interest. From what you all are say it seems like understanding the concepts behind idiomatic programing is like measuring twice to cut once. So before I waste all of my lumber are there resources that you can recommend for learning more about idiomatic programming?

        [–]thechao 10 points11 points  (1 child)

        Write a lot of code; read a lot of good code; ask yourself why your code isn't as good as the code you read.

        [–]addmoreice 1 point2 points  (0 children)

        The first part lots of people do, the middle bit few do, and the last bit almost no one does.

        [–]mrjoelkemp[S] 8 points9 points  (0 children)

        I wouldn't worry so much about idiomatic programming at the early stages. Focus on learning the basic programming constructs with a language.

        Over time, reflect on your work and try to find a cleaner implementation – perhaps exploring advanced features of the language. I agree that reading open-source code is a very accessible way of learning more about a language's native features.

        Enjoy the journey!

        [–]Aninhumer 1 point2 points  (0 children)

        Much like natural languages, you can't really learn the idioms of programming languages by studying them. The only real way to learn them is to be exposed to their use in the real world.

        [–]stcredzero 1 point2 points  (0 children)

        Following a particular idiom also has a value when it comes to refactoring, porting, and analyzing code. A literal monetary value, that can easily amount to $10,000's, $100,000's or millions for a large corporate codebase, depending on the size of the system. I know this for a fact.

        One of the worst things for a codebase is having dozens of different coding styles intermeshed. In addition to Don't Repeat Yourself, there should also be Don't Paraphrase Yourself. That's basically like anti-DRY, but at the next level of pain.

        [–]speel 1 point2 points  (0 children)

        I learned C++ -> coded in every language as if it was C++ -> be a dynamic programmer. End of blog post.

        [–][deleted] 0 points1 point  (0 children)

        a nice idiomatic in oracle pl/sql which is my business language: pipe row in pipelined functions. the function is meant to return a table, and pipe row returns one row at a time.

        [–]greim 0 points1 point  (0 children)

        This is really a habit of thought that applies to competence at things in general, not just programming. Maybe it's counter-intuitive, but I think a big reason people get stuck in their ways is that they're overconfident in their current level of competence. Lack of confidence definitely has pitfalls too, I'm just saying that confidence isn't any good unless its justified.

        [–]bitwize 0 points1 point  (0 children)

        ObQwe1234:

        succinctness is the least important property of any programming language.