
The Shapes of Code - jandeboevrie
https://www.fluentcpp.com/2020/01/14/the-shapes-of-code/
======
classified
> ... not so good code: if it was, we wouldn’t need a comment...

How much longer will this rumor persist that "good code" doesn't need
commenting? Good comments explain things that aren't immediately obvious from
the code.

~~~
clarry
Most code should be boring and immediately obvious. I don't run into lots of
real world code that needs much explaining. Sometimes you do something weird
or not-obvious for good reason, but I see plenty of comments explaining things
that only need to be explained due to poor design. Also poor comments that
don't really explain anything that isn't obvious by looking.

~~~
nerdponx

        def clean_start_year(x):
            # Account for the 7 year offset in the database
            return x + 7
    
        def process_record(record):
            record['start year'] = clean_start_year(record['record'])
    

It's perfectly obvious what this code does, but without the comment it's
totally unclear _why_ it does what it does.

~~~
taneq
Ah, the inline equivalent of Doxygen-for-the-sake-of-Doxygen documentation.

    
    
        int frob(const int x, void *context)
        Performs a frob on x in the given context.
        Parameters:
          x - int param
          context - a pointer to context
        Returns an id of the frob performed.

~~~
clarry
I see a lot of this at work, sigh.

The better a variable / function is named (and the better its scope or purpose
is limited to one thing), the less it needs comments. So there are a lot of
self explanatory variables or functions with doxygen comments that state
exactly the same thing the name already does, without adding anything besides
noise. And then there are some poorly named things where the exact same thing
happens: comment re-states what the bad identifier states. Sigh. Genuinely
useful comments are rather rare.

------
luckycharms810
While the patterns themselves are interesting, the idea that all code must be
rearranged in to smaller functions to be “refactored” seems a little juvenile.

~~~
hinkley
There’s an exercise for creative writing that my lit major friend told me
about. You take everything you’ve written and cut it up into sentences. You
just push the sentences around until something clicks and you figure out how
to write your way out of the “stuckness”.

Refactoring has rediscovered this trick, among others.

~~~
0x445442
Another similarity to creative writing is this; you're not done when there's
nothing left to add, you're done when there's nothing left to remove.

------
saltyfamiliar
I'm glad I'm not the only one who pays attention to this. This is completely
unsubstantiated and coming from a relatively inexperienced programmer, but
it's been my experience that better code tends to produce nicer shapes. An
obvious example not mentioned in the article arises when code is nested too
deeply and too thinly, creating jarring and disproportionate peaks.

~~~
Thorrez
Microsoft's docs have an interesting idea of what good nesting looks like:

[https://docs.microsoft.com/en-us/previous-
versions/windows/d...](https://docs.microsoft.com/en-us/previous-
versions/windows/desktop/legacy/bb776913\(v=vs.85\)?redirectedfrom=MSDN#basic-
usage)

Apparently 13 different indentation levels is good.

~~~
jpz
I actually find that surprisingly readable, probably because of the indent
size which clearly allows the eye to see the blocks - and the size of my very
large monitor - but this code seems to indicate a religious dogma about
avoiding early returns, which would otherwise straighten it up.

~~~
a_t48
Refactoring it effectively needs some sort of scope guard, too, to run
`pfd->Release();` and the like. It's just as much dogma to write C++ like C,
avoiding RAII.

------
hinkley
I used to push hard for my favorite indentation style, and at one point I
figured out that a big reason I could find bugs so fast was that, given
reasonable formatting, I could _see_ code smells just from the shape.

If the bug wasn’t in the ugliest part of the code, then that code likely had
two bugs in it.

------
mariojv
I hadn’t thought about the shape of code much as a refactoring heuristic, but
it’s neat to see a post about the concept of code shape.

I found examining code shape to be an effective method for assisting in
algorithm recall in some college courses. Now working with larger codebases in
industry, I find it really useful for navigating around large files or
remembering where to go for particular snippets of code.

I wonder if this phenomenon has anything to do with different spatial tricks
people use for memorization and recall (the “memory palace” technique). I’ve
never thought of myself as having good spatial reasoning at all, but this kind
of thing makes me question the boundary between “spatial” and symbolic /
verbal thinking.

------
zdragnar
My favorite name for a shape of code I've heard is the "pyramid of doom"
caused by excessive nesting- think lots of ifs or callback hell in something
like node.js

It's easy to recognize, and the importance of recognizing it is right in the
name.

~~~
quickthrower2
Luckily we have async await to save us!

------
foxes
For me I would think of the "shape of code" as an abstract measure of
complexity [0]. More text might correlate with more complex logic. This is a
measure in a language which manipulates state / control flow.

I'm not sure what happens in a functional language. Maybe you could just think
about numbers of functions. In Haskell sometimes it helps to write things in a
pointfree way and you can spot some more general function to replace some
noise.

[0]
[https://en.wikipedia.org/wiki/Cyclomatic_complexity](https://en.wikipedia.org/wiki/Cyclomatic_complexity)

------
Huggernaut
Sandi Metz talked about a thing she does in her 2014 All the Little Things
talk that she calls the "Squint Test". The idea being that you can tell a lot
about the code from only its shape and colours by squinting at it.

Someone made an Atom plugin: [https://atom.io/packages/squint-
test](https://atom.io/packages/squint-test)

~~~
hackinthebochs
This is exactly why I hate the trend in reducing structural characters in new
languages, or having it be almost all words (e.g. python). There is much to
understand about code by its shape, but blocks of words tend to have much less
obvious at-a-glance shape than similar code with structural characters thrown
in.

------
lincpa
The data flow programming of pure pipeline structure, It systematically
simulates integrated circuit systems and large industrial production lines.

In the computer field, for the first time, it was realized that the
unification of hardware engineering and software engineering on the logical
model.

It has been extended from Lisp language-level code and data unification to
system engineering-level software and hardware unification.

and it brings large industrial production theory and methods to software
engineering. It incorporates IT industry into modern large industrial
production systems, This is an epoch-making innovative theory and method.

This is the [Pure Function Pipeline Data Flow v3.0 with Warehouse/Workshop
Model]([https://github.com/linpengcheng/PurefunctionPipelineDataflow](https://github.com/linpengcheng/PurefunctionPipelineDataflow)).

------
RickJWagner
I'm a software maintenance engineer. I make my living reading other people's
code and trying to internalize it so I can make repairs where they are needed.

This is an interesting article, and I intend to go listen to the podcast, too.

In the past I've made efforts to try to speed up the process of learning a
codebase. I'd do things like copy the code into a text processor, then shrink
the font so I could see which files (classes) were biggest, and look for
repeating shapes like the author mentions. I'd also use code cleaners to point
out troublesome classes and UML full-trip tools to try to get a good sequence
diagram out of a piece of code.

It was all cumbersome, unfortunately. Most days I just use 'grep' to help me
figure things out. I'm still looking for helpers, though. I'm hoping the
podcast helps.

------
DarkCrusader2
This post very nicely summarizes what I now realize I have been doing
subconsciously all the time. Writing in paragraphs with headings, turning
short else branches in guards, refactoring "sharp saw teeth" etc. Good to know
that others also use these heuristics.

------
0x445442
> ...understand legacy code, refactor long functions...

Wouldn't this invite consternation during code reviews because it doesn't have
anything to do with the current feature? Or are you one of the lucky few who
gets to exercise professional judgment when working?

------
l0b0
Handy patterns, which could probably fairly easily be implemented as a high-
level linter.

------
crimsonalucard
This is the surface shape of code.

There is an intrinsic and deeper geometry that textual programming hides.

------
gitgud
High indentation has always been a good heuristic for high complexity.

More indentation equals more mental context required.

But although these shorter, less-indented functions are inherently easier to
understand, they're not necessarily freer of bugs...

------
crimsonalucard
Functional code tends to extend horizontally a lot.

------
sinuhe69
Functional code would be totally different, I guess.

~~~
pmontra
Probably. This is my experience with the case of the unbalanced if.

When it happens to me in Python or Ruby, I return immediately from the smaller
branch and move the other branch out of the if, to the main level.

When it happens in Elixir... It doesn't happen because I don't use ifs there.
I write two versions of the same function. One matches the condition for the
then branch, the other the condition for the else one.

