Live data from Hacker News

Self-Documenting Code

lackofimagination.org

111–120 of 131 posts

Re: Self-Documenting Code

#111
post #92

Earlier quoted context omitted.

It definitely depends, but personally I find early returns to be a bit of an antipattern IF they're based on business logic. If a function has lots of ifs, you can glance at the nesting to see which ones affect the line you want to edit, and ignore the others. But if the function has lots of returns, you have to check every one before a given line in order to know what constraints are true at that point. OTOH early r…

> you can glance at the nesting to see which ones affect the line you want to edit, and ignore the others. Only if all the cases return! Only then is it obvious that you have independent cases. E.g. suppose we have three Boolean inputs x, y, z and want to do something for each binary combination: if (x) { if (y) { if (z) { return 7; } else { return 6; } } else { // x && !y if (z) { return 5; } else { return 4; } } }…

> Only if all the cases return!

My comment was about using if blocks as opposed to early returns. I.e. where the nested ifs run exhaustively and return afterwards.

Also, obviously deep nested ifs aren't good, so I wasn't advocating them - I just think it's better to fix them by splitting functions or simplifying control flow, than by adding early returns.

Re: Self-Documenting Code

#112
post #92

Earlier quoted context omitted.

It definitely depends, but personally I find early returns to be a bit of an antipattern IF they're based on business logic. If a function has lots of ifs, you can glance at the nesting to see which ones affect the line you want to edit, and ignore the others. But if the function has lots of returns, you have to check every one before a given line in order to know what constraints are true at that point. OTOH early r…

Calling it an anti pattern (as opposed to a subjective preference) is in my opinion super dangerous and reeks of cargo-culting as it implies an active avoidance of it which can result in deep nesting or contorted and hard to read logic. There is no hard rule about early returns being always good or always bad, it depends on the particular situation.

[deleted]

Re: Self-Documenting Code

#114
post #81
post #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…

> Naming or visual code structure was never a problem in my career so far. Either you're the high verbal skill person on the project and you haven't noticed yet that everyone keeps coming to you to name things, you're in a pocket of devs with high verbal skills so you don't see problems, or you're in an echo chamber where everyone is equally bad and you don't know what 'good' looks like. There's literally a programme…

> everyone keeps coming to you to name things

Nah, not really. Years ago when we worked in office and I was still a junior we did discuss naming things here and there but I didn't like those conversations. It's all just opinions and habits.

> you're in a pocket of devs with high verbal skills

I mean, we don't hire juniors so it's possible but doubt it.

> you're in an echo chamber where everyone is equally bad

Most probably but if no one is having problems with reading code then I'm not sure what bad even means. If it's in English and it describes what it does and does not use any tricks - it absolutely doesn't matter how exactly is it worded and structured. The examples from the article are especially bad. I've seen some code I'd consider bad in general but it was all about those library hacks (usually ORMs) I mentioned previously or about trying to fit a lot in a single LINQ statement (i'm a c# dev). The only time when I'd consider naming to be bad was were all variable and function names were in German.

> There's literally a programmer joke about how hard naming things is.

It's a joke because it's not that serious. It might be hard sometimes to come up with any name for a thing (especially for non-english speakers like me) and you plop down a "var x" or something even less mature and run which is funny. So it is hard but it's not a "real" problem.

Re: Self-Documenting Code

#115
post #95
post #76

Earlier quoted context omitted.

The business rules for passwords and usernames are separate. It's okay for them to be separate methods. You also know that the 'valid password' function is going to list the rules for a valid password. If you get a task to change the password creation rules, do you honestly expect people other than you to remember that code is in the createUser function and not the valid password function?? I don't think you're being…

> If you get a task to change the password creation rules, do you honestly expect people other than you to remember that code is in the createUser function and not the valid password function?? I don't expect anyone to remember where the code is, regardless of which function it's in. I don't even expect them have been aware of every function to begin with. How do you expect people will find the `isPasswordValid` func…

how do you unit test this function that’s handling many responsibilities?

Re: Self-Documenting Code

#116
post #81
post #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…

> Naming or visual code structure was never a problem in my career so far. Either you're the high verbal skill person on the project and you haven't noticed yet that everyone keeps coming to you to name things, you're in a pocket of devs with high verbal skills so you don't see problems, or you're in an echo chamber where everyone is equally bad and you don't know what 'good' looks like. There's literally a programme…

> There's literally a programmer joke about how hard naming things is. If you don't understand a programmer joke you should probably pull on that thread real hard to figure out why.

Those are for people who are new to programming.

Re: Self-Documenting Code

#118
I don't like this article, author just added some abstraction and moved the stuff that matters out of the perspective and we just have to imagine that whatever is outside the perspective is perfect.

Re: Self-Documenting Code

#119

If I were reviewing the original code, the first thing I’d question is the line user.password = await hashPassword(user.password); 1. As a rule, mutations are harder to understand than giving new names to newly defined values. 2. The mutation here apparently modifies an object passed into the function, which is a side effect that callers might not expect after the function returns. 3. The mutation here apparently cha…

> At least three of those problems could trivially be avoided by naming the result hashedPassword and, ideally, using TypeScript to ensure that mixing up plain text and hashed passwords generates a type error at build time.

Going that path further ends up what a few code bases I've worked with do: Pull the two domains apart into a "UserBeingCreated" and an existing "User".

This felt a bit weird at first, but the more I think about it, the more sense it makes. One point leaning towards this: You are dealing with different trust levels. One is a registered and hopefully somewhat validated user, which can be trusted a bit. The other thing could just be a drive by registration attempt.

And you're dealing with different properties. Sure, there is some overlap - username, mail, firstname, lastname. But only a UserBeingCreated needs validation errors or a clear text password. Other things - like groups, roles and other domain properties only make sense after the user is properly registered.

Re: Self-Documenting Code

#120
post #95

Earlier quoted context omitted.

> If you get a task to change the password creation rules, do you honestly expect people other than you to remember that code is in the createUser function and not the valid password function?? I don't expect anyone to remember where the code is, regardless of which function it's in. I don't even expect them have been aware of every function to begin with. How do you expect people will find the `isPasswordValid` func…

how do you unit test this function that’s handling many responsibilities?

Look at it. It's under 20 lines long and handles one thing, which is creating a user. You unit test it by passing a user with an invalid password. You might possibly decide to put the validation of user input into one function and avoid mocking userService, but I don't see a good justification for splitting password and other user fields into separate functions.

I accept that if there was more logic then you might want to split it out, but seriously, it's tiny. The single responsibility principle doesn't justify making your production code much more difficult to read just so the unit tests around it are marginally easier to write.

Post reply on HN