|
|
Subscribe / Log in / New account

It's not a coincidence that Fuzzing is added to Go

It's not a coincidence that Fuzzing is added to Go

Posted Sep 6, 2020 0:38 UTC (Sun) by HelloWorld (guest, #56129)
In reply to: It's not a coincidence that Fuzzing is added to Go by Cyberax
Parent article: Fuzzing in Go

The idea that more indentation somehow ”obscures“ the code is complete and utter bullshit. There is _zero_ evidence to support it.


to post comments

It's not a coincidence that Fuzzing is added to Go

Posted Sep 6, 2020 0:47 UTC (Sun) by Cyberax (✭ supporter ✭, #52523) [Link] (7 responses)

There actually is: https://www.cs.umd.edu/~ben/papers/Miara1983Program.pdf - deep indentation (be it purely visual or a result of deep nesting) hampers the comprehension.

I've seen other studies, but I'm too lazy to find them again. Deep nesting is definitely bad, and "structured programming" often requires it, while break/continue allow to un-nest some of the code.

I'm personally fond of this style:
for (i : someCollection) {
  if (i.frobBarBaz == SomeConstant) {
     // The flag frobBarBaz disqualifies the object
     continue;
  }
  if (!somethingElse(i)) {
     // This is not the object you're looking for.
     continue;
  }
  ...
}
Sure, it can be rewritten as a one long condition, split into predicates for map/filter, but often at the expense of readability.

It's not a coincidence that Fuzzing is added to Go

Posted Sep 6, 2020 1:16 UTC (Sun) by HelloWorld (guest, #56129) [Link] (6 responses)

Deep nesting is definitely bad
Let's take some code that's indented twice:
while (foo)
  while (bar)
    baz();
And rewrite it with one level of indentation:
l1:
if (! foo)
  goto l4;
l2:
if (! bar)
  goto l3;
baz();
goto l2;
l3:
goto l1;
l4:
Yeah, you're right. That is so much more readable, I wonder why I never noticed…

It's not a coincidence that Fuzzing is added to Go

Posted Sep 6, 2020 1:40 UTC (Sun) by Cyberax (✭ supporter ✭, #52523) [Link] (5 responses)

OK, please now please rewrite this function without gotos or early returns: https://elixir.bootlin.com/linux/latest/source/mm/mmap.c#...

Of course if you remove ALL structure, the code becomes bad. 'for' loops are there for a reason.

However, there's an easy test to tell that early return/break/continue is well-placed. It's if it reduces (or keeps the same) the overall number of lines of code.

It's not a coincidence that Fuzzing is added to Go

Posted Sep 6, 2020 4:03 UTC (Sun) by HelloWorld (guest, #56129) [Link] (4 responses)

> OK, please now please rewrite this function without gotos or early returns

I would, but it's just too hard to read…

Anyway, I'll point out that
1. the paper you've presented is meaningless. It deals with the question how deep a single level of indentation should be (2 to 6 spaces). That says nothing about the benefits (or lack thereof) of structured programming
2. you haven't addressed my point that with structured programming it's easier to understand which conditions must apply for a certain piece of code to execute, because every condition corresponds to one level of indentation
3. you haven't addressed my point that it's easier to get resource cleanup right with structured programming (no need for any "goto fail" nonsense)
4. you keep harping on this structured vs. non-structured programming thing instead of addressing the much more important point that in order to avoid bugs we need to employ formal methods (which is another thing that Dijkstra was right about)

Frankly these discussions with you are just tiresome, because when it comes to programming, you're completely stuck in a 1980s-style imperative mindset. There's nothing interesting to learn from that.

It's not a coincidence that Fuzzing is added to Go

Posted Sep 6, 2020 4:15 UTC (Sun) by Cyberax (✭ supporter ✭, #52523) [Link] (3 responses)

The paper looked purely at graphical indentation level, and it holds true for nesting as well.

Again, you seem to not understand that the theory says that every loop can be rewritten as a loop with invariant in its condition.

In practice a lot of invariants are too unwieldy to write in one condition and benefit from being split into multiple statements (with break/continue to help). Often because you need to introduce additional variables. All "structured" alternatives result in additional levels of indentation in this case.

> 4. you keep harping on this structured vs. non-structured programming thing instead of addressing the much more important point that in order to avoid bugs we need to employ formal methods (which is another thing that Dijkstra was right about)
It doesn't matter if you use break/continue for automated formal methods, they can just reconstruct the formal invariant anyway. And manually applied formal methods basically failed for anything non-trivial.

It's not a coincidence that Fuzzing is added to Go

Posted Sep 6, 2020 19:23 UTC (Sun) by HelloWorld (guest, #56129) [Link] (2 responses)

All "structured" alternatives result in additional levels of indentation in this case.
This is purely a matter of how you choose to indent your code. It works just fine with only one level of indentation:
while foo and begin
  # several statements
  not bar
end do
  # more statements
end
But anyway, you've clearly made up your mind about this, and fortunately I don't need to convince you.

It's not a coincidence that Fuzzing is added to Go

Posted Sep 6, 2020 19:26 UTC (Sun) by Cyberax (✭ supporter ✭, #52523) [Link] (1 responses)

Gah. Your example is even WORSE than several levels of indentation, as it completely confuses condition and the body of the statement.

It's not a coincidence that Fuzzing is added to Go

Posted Sep 6, 2020 23:06 UTC (Sun) by HelloWorld (guest, #56129) [Link]

It's exactly the other way around. The statements in the "body" of the C loop up to and including "if (bar) break;" are what determines whether the loop will continue and are hence part of the condition. This is clearly reflected in the Ruby code and not in the C code, so the Ruby variant is the correct one.

This is actually kinda funny, because it shows that what Dijkstra said about BASIC also applies to C: you've been mentally mutilated by C enough to not be able to tell the condition from the body of the loop any more. I'm sorry that happened to you (-:

It's not a coincidence that Fuzzing is added to Go

Posted Sep 6, 2020 1:04 UTC (Sun) by HelloWorld (guest, #56129) [Link] (2 responses)

In fact, it's the other way around: it's the *lack* of indentation caused by early returns that obscures the code. Somebody came up with the idea that one should return early from functions when encountering errors:
do_stuff();
if (foo)
  return bar;

do_more_stuff();
But this is downright retarded. The whole idea about indenting the contents of blocks guarded by if and while is that it allows you to tell at a glance that a piece of code is not always executed but only when some condition is true. Early returns break this: you need to read the code and notice the return statement in the if (foo) block to know that do_more_stuff() will not be executed unconditionally but only when foo is false. And even worse, it's very easy to mess up resource cleanup when coding in this style. People then came up with even more retarded ideas like “goto fail” to “fix” that, and when the Go developers noticed that people were messing that up too, they added *yet more* crap to the language, i. e. the defer statement. And then they give talks about how “Less is exponentially more” 🤦

It's not a coincidence that Fuzzing is added to Go

Posted Sep 6, 2020 1:11 UTC (Sun) by mpr22 (subscriber, #60784) [Link] (1 responses)

I have never found code using the early-return pattern hard to read.

I have, however, encountered code with deeply nested ifs, and I concur with the paper Cyberax cited that reading it is a horrible experience.

(It's still more pleasant than trying to read JSP, though.)

It's not a coincidence that Fuzzing is added to Go

Posted Sep 6, 2020 4:41 UTC (Sun) by flussence (guest, #85566) [Link]

I first learned of the early-return pattern when doing maintenance work on someone else's PHP site in 2003. Namely, they had never heard of it, and every single page was wrapped in a giant "if access_check then page_contents else show_error" construct (not to mention the contents themselves would meander off to the right). It was downright painful to read until that got fixed.


Copyright © 2025, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds