Live data from Hacker News

Self-Documenting Code

lackofimagination.org

21–30 of 131 posts

Re: Self-Documenting Code

#21
post #12

I don't find this easier to read: !(await userService.getUserByEmail(user.email)) || throwError(err.userExists); I guess if I worked in a codebase that used that pattern consistently I'd get used to it pretty quickly, but if I dropped into a new codebase that I didn't work on often I'd take a little bit longer to figure out what was going on.

> I don't find this easier to read:

I agree. The previous iteration shown is simpler IMO.

I've really shifted how I code to making things just plain simple to look at and understand.

Re: Self-Documenting Code

#23
post #8

Earlier quoted context omitted.

I was thinking exactly the same. You can write if (cond) { cons } on one line and get more readable code admittedly a few chars longer.

Don't even need the curly braces. I do if (cond) doSomething(); all the time.

if (heathen) dontUseCurlies();

Re: Self-Documenting Code

#24
"Self-documenting code" is already a thing called Code-as-Docs. It's the inverse of Docs-as-Code, where you're "writing documentation like you write code". Code-as-Docs is where you write Code that is self-documenting. (And this has absolutely nothing to do with Literate Programming.)

You do not have to adhere to any specific principles or methods or anything specific in order to do Code-as-Docs. Just write your code in a way that explains what it is doing, so that you don't need comments to understand it.

This often means refactoring your code to make it clearer what it does. It may not be what your ideal engineer brain wants the code to do, but it will make much more sense to anyone maintaining it. Plus very simple things like "variables-that-actually-describe-what-they-do" (in a loop over node names, don't make a variable called x; make a variable called node_name)

edit It seems like I'm the only one who says "Code-as-docs"... by searching for "Code-as-documentation" instead of "Code-as-docs", I found this: https://martinfowler.com/bliki/CodeAsDocumentation.html

I guess "self-documenting code" more hits: https://www.google.com/search?q=self-documenting+code https://en.wikipedia.org/wiki/Self-documenting_code https://wiki.c2.com/?SelfDocumentingCode

Re: Self-Documenting Code

#25
post #12

I don't find this easier to read: !(await userService.getUserByEmail(user.email)) || throwError(err.userExists); I guess if I worked in a codebase that used that pattern consistently I'd get used to it pretty quickly, but if I dropped into a new codebase that I didn't work on often I'd take a little bit longer to figure out what was going on.

> I don't find this easier to read: I agree. The previous iteration shown is simpler IMO. I've really shifted how I code to making things just plain simple to look at and understand.

That's the way it should be, easy to understand. This set up might be short but it's complex to read.

Re: Self-Documenting Code

#26

I agree with most of the article but want to nitpick this last part: > I’m not a fan of TypeScript, but I appreciate its ability to perform static type checks. Fortunately, there’s a way to add static type checking to JavaScript using only JSDoc comments. If you're writing JSDoc comments, then you're not writing what the author considers to be "self-documenting code." I wish the author had explained why they are not…

I find myself agreeing with much of your point, but I feel the need to nitpick a bit of your comment myself :)

I don't think your code base needs to be very large, or very legacy in order for comments to be valuable or even the best way forward. If the decision exists between a somewhat large refactor or a one-off comment to account for an edge case, I'm likely to take the latter approach every time. Refactors introduce risk, add time, and can easily introduce accidental complexity (ie: an overengineered solution). Now once that edge case becomes more common, or if you find yourself adding different permutations, yeah I agree that an incremental refactor is probably warranted.

That said, perhaps that comment could — and certainly one should at least supplement it — be replaced with a unit test, but I don't think its presence harms anything.

Re: Self-Documenting Code

#27
post #12

I don't find this easier to read: !(await userService.getUserByEmail(user.email)) || throwError(err.userExists); I guess if I worked in a codebase that used that pattern consistently I'd get used to it pretty quickly, but if I dropped into a new codebase that I didn't work on often I'd take a little bit longer to figure out what was going on.

After that step, they say "The resulting code is shorter and has no nested logic." The resulting code has the same logic as before, it's just not visually represented as being nested. I've seen the same argument ("nesting is bad so indentation is a code smell") used to say that it's better to use early returns and omit the `else` block, eg:

    if (some_condition) {
      // do stuff here
      return;
    }
    // do other stuff here
is "better" than:

    if (some_condition) {
      // do stuff here
    } else {
      // do other stuff here
    }
If you have very-deeply nested code then it usually becomes easier to work with after splitting it up into smaller pieces. But IMO rewriting code like this to save a single level of indentation is bikeshedding.

Re: Self-Documenting Code

#29

Having a function throwError makes me squirm. `isValid() || throwError()` is an abuse of abstraction

A fail fast paradigm is a style of programming that can be used very effectively, as long as it's understood that's the style of code that is being written.

Much of my code, for example, is fail fast, and then I have error handling, supervisors, etc, at a level that can log and restart the work.

Re: Self-Documenting Code

#30
After 10 years as a commercial dev I've noticed I don't really care about things like this. Not sure if it ever made a difference. The "local code" - as in anything within a function or often a single class (1-2k LoC is not really a problem) - is trivial to read in most languages. The most difficult thing to understand always was the domain or the infrastructure/library quirks - stuff that's never properly documented. (Hot take: might not be worth to document anyway as it takes longer to write and update such docs than to struggle with the code for a little bit).

Naming or visual code structure was never a problem in my career so far.

Post reply on HN