Hacker News new | ask | show | jobs
by engmgrmgr 1618 days ago
Effort to refactor is something to consider, and verbosity makes this harder as you get lower level.

Another thing to consider is the very verbose names can be something that people actively avoid for clean code, and you could end up with spaghetti code to make it both readable and verbose (imagine someone doing this for years and then handing the code off to someone when they leave because they were so pigeonholed in that system that no one else could easily collaborate).

Downstream, you can end up with tech debt instead of optimally refactored code as people struggle to do something of a smaller scope. And if every tiny thing is unit tested, it gets even harder to change without expanding the scope of work.

Math code is an extreme example of where verbosity can quickly become detrimental.

1 comments

Definitely have to disagree.

"Clean" code is often an excuse for lazy, short names which need a comment to explain them. Consider this completely fabricated example:

// calculates the area of a rectangle with sides a and b, u being true for metric, false for imperial

int rarea(int a, int b, bool u);

versus

int rectangle_area(int side_a, int side_b, bool metric);

which more or less doesnt even need a comment anymore.

"Clean code" people want short names, massive comments that can be collapsed, so that from really far away, it looks neat. Its a terrible beginner mistake I see time and time again, and it shouldnt be defended.

If you write a math formula, how is writing "side_a" or "phi" worse than "a" and "p"?

Why would it be worse? Why would you write p instead of phi?

I would, however, point out that to call this function, you need to separately compute lengths of sides. Where do those come from? How are coordinates stored? How are you wiring all this up? What happens when you change the data to support more dimensions, or to use memory pools, or to add new shapes?

To be clear, a lot of math needs a ton of complex code, and you also often have algorithms optimized for performance, approximation, numerical stability, etc. You can encode your understanding of what’s going on in the naming and break it into chunks so it’s readable, but that’s not necessarily a good thing.

Write some code to compute the intersecting earth-surface geometry of the projected frustum far planes from two satellites’ cameras at some point in time. Who’s using this code, is it a library? How do you abstract it? Who are the consumers of the code, will they ever change it or only use a part of it and want to refactor? Is it going to be a lot of work to refactor and are they just going to inject what they need into an evolving system of glue code? If I have to call it n times, how can I pass in and reuse memory to avoid memory penalties? What happens to names when we have to reuse symbols?

Edit: probably not obvious, but you can probably elegantly describe what you’d do with ideal inputs, but getting those inputs is the particularly hard part.

For an even more contrived example, see my other comment [1]

[1] https://news.ycombinator.com/item?id=29872191

“If you write a math formula, how is writing "side_a" or "phi" worse than "a" and "p"?”

When you pick up your pencil to do some manipulations on that formula, you’ll wish you’d chosen the one-letter variables. Also, single character variables, perhaps with different fonts, subscripts, or other decorations, make it easier to see the structure of the equations. That’s why we use them in math.

For those of us who use a pencil to manipulate our code, to see how it might be transformed, the value of short variable names is the same—we’re often going back and forth between code and math. That’s why languages like Julia that let you use Unicode identifiers are so cool.

`bool metric` does not ring any bells (I never lived in US, so I had to refer to the comment to understand it), and units of `a` and `b` and result are missing.
`bool metric` implies that `metric` can be YES or NO, that's clearer than what was there before.

Its a made-up example, this discussion is about style, not about semantics. To please those who would like to see a semantically improved version: (C++)

    enum class Unit {
        Meter,
        Inch,
        Foot,
        // ...
    };

    template<Unit U>
    struct UnitValue {
        double value;
    };

    template<Unit U>
    UnitValue<U> rectangle_area(UnitValue<U> side_a, UnitValue<U> side_b);


    // invocation example
    constexpr Unit unit = Unit::Meter;
    UnitValue<unit> result = rectangle_area<unit>({5.3}, {1.5});

    std::cout << result.value << std::endl;
There is still room for improvement, maybe some concepts to further generify it, some more comments, maybe a PDF with full documentation, ...
I'd imagine in an ideal world they'd've gone with `enum(Metric, Imperial) units` but as a direct rewrite of the original function signature it was probably the least worst available option.