Settings

Theme

Ask HN: How to Write Readable Code

10 points by marijnz0r 4 years ago · 12 comments · 1 min read


Hi HN, I write code and unit tests for other departments in my company. For me, writing code in a programming language feels natural, so I like to use the notation of the language itself. A colleague likes to write code more like prose so someone from another (non-IT) department should be able to read it. How do you deal with this in your company? I think I read an article about this a few days ago, but I can't seem to find it anymore. Does someone still remember this?

me_me_mu_mu 4 years ago

I’ve worked with “code like prose” people and found them pretty difficult to work with. I’ve also found most of them to be not that great technically or they have exclusively Ruby on Rails backgrounds and can’t seem to function on any other technology or approach.

I don’t think the sales guy needs to be able to read channel handling logic or care about how the react code is organized.

Engineers should write good code that can be easily understood and modified by other engineers. Are engineers going to cold call people or run the financials? No their job is to build systems and keep them running.

notadev 4 years ago

I’ve always tried to use naming of variables and methods to make it obvious what the code is doing. Something like:

``` if service_is_disabled: start_service() else: send_notification(“Service is running”) ```

eslav 4 years ago

What does “code like prose” look like? I had a group project in college with a guy who used MS Word to write code in paragraphs..formatted like an English paper (I’m not kidding); is this what you mean?

(Looking back I often wonder how long this guy wrote code like this before someone said “knock it off”..)

  • marijnz0rOP 4 years ago

    Regarding a unit test it looks something like this in pseudocode:

      function test_addition() {
          given_two_integers(2,3);
      
          when_summed_up();
      
          then_the_result_should_be(5);
      }
    
    Whereas I would prefer something like

      function test_addition() {
          int a = 2;
          int b = 3;
      
          int result = new Addition(a, b);
      
          Assert.AreEqual(result.Sum(), 5);
      }
    
    For a non-coder it might seem more intuitive to read the first example, because it only contains natural language. For a coder it seems more intuitive to read the second example, because it prevents "method hopping" (I have to go into the methods from example one to see what's actually happening inside them).
    • Jtsummers 4 years ago

      It sounds more like the colleague wants a DSL. DSLs can be useful but should also be used with care since they are "mini languages" that stand apart from the host language. A perhaps better (though not necessarily stellar) alternative to the first would be to have a series of calls like:

        function test_addition() {
          given(2,3)
            .when(add) // assume `add` is a function here
            .result_is(5);
        }
      
      `when` could take a lambda as well so that you can pass in anything:

        given(2,3)
          .when(a,b => new Addition(a,b)) // to stick with your second example where the constructor returns a result
          .result_is(5)
      
      This is how many testing DSLs I've seen look, and it's not awful if this style of programming is already present in the language.

      But I agree, if that first example is representative of what the colleague wants to do it introduces a lot of "magic". Where are the integers stored? Where is when_summed_up defined and how does it know which function/method to use? Is the entire test in its own class/module so that this can work? Or is this test class/module now polluted with, potentially, dozens of class/module scope variables to store all these hidden variables and many utility functions that disguise what is actually being tested?

      Regarding "how to deal with this", bring it up in code reviews, offer alternatives like the above (or some palatable-to-you version of it) for some situations. If their style is so far from yours it may be easier to meet in the middle than to totally break them of it. Emphasize the complexity that their solution is bringing to the table (again, assuming that your example is actually representative, it does make it more complex).

      A testing DSL like what I described can be written once, kept in its own modules, extended across the board (not on a per-test basis), and provides a uniform approach to a testing DSL. An ad hoc DSL per test (case or set) is a lot of extra work all around. It is fragile, potentially introduces race conditions which breaks the ability to run tests concurrently, and non-uniform. This last one is really important when working in teams and when working with outsiders to the team. With teams, it makes it harder for someone to jump into a test and understand it. The above DSL is more readily comprehended (even if requiring a bit more upfront study, that upfront study happens once). When working with outsiders from the team, they can look at a variety of tests and understand it well enough, if not perfectly, because it is consistent.

    • fatnoah 4 years ago

      I was having trouble visualizing what OP meant, and this is a great explanation!

mvaliente2001 4 years ago

I think it's important to keep a consistent style in a repository. Ideally, the style should be kept _among_ repositories too, but given that different people like different thing, allowing them to explore the pros and cons might be a better strategy to achieve it.

100011_100001 4 years ago

You might want to look at BDD. It's a way to be able to discuss what has to happen and use code to make it happen.

  • marijnz0rOP 4 years ago

    Thanks for the recommendation. I've read the book by Eric Evans and I like the first chapters about creating an ubiquitous language. I'm trying to figure out how to create a balance between the spoken language in code and the actual implementation of the code.

gushogg-blake 4 years ago

Literate programming maybe?

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection