While reviewing the first draft I realized that these two tidyings could use an example or two. Send ‘em, please! To review for the many of you who weren’t here when the chapters were published: Reading Order says that you take an element with randomly sorted sub-elements (e.g. a file with functions or a class with methods) & place the sub-elements in the order you wish they had been when you read the code.
To make things more complicated, I know from experience that some developers (typically those trained in math) tend to to structure things like a proof, with "atoms" first, building up to larger entities.
At least I have seen many .Net projects where developers with near OCD have taken great care to define collapsible regions for constructors, properties, public methods and private methods. While it looks nice and tidy, I see it as a big anti-pattern to arrange methods by protection. In terms of readability it can almost be worse than random order, because you are guaranteed that the sub elements are placed very far from the invocation, and the ideal reading order
Does this depend on language? I ask because I’m JS, for example, “consumed” methods precede “consumer” methods (because IIRC methods are evaluated top-down when the file is loaded) as opposed to Ruby, for example, that will typically have the inverse.
In some rare case the first one might be useful if the use1 is really slow and we have command line tool which takes hours to execute. Sometimes, it is sad to look into the results in an hour and realize there was a mistake in a command line argument.
Are you looking for real-world example with some domain information?
The ideal example is 1) real open source code and 2) requires domain knowledge all readers share. 2) is impossible but worth optimizing for. Bonus points for an actual diff.
I can think of two similar examples that come immediately to mind. For classes, generically, it's a good idea to keep the public methods at the top of the file, as they'll be the "entrypoints" into that logic. Same with react components, it's usually a good idea to put the "main" component at the top of the file, front and center. It's definitely a choice of style, and doesn't have any behavioral impact (most of the time?) but can help the next person to read that module. Is that in the spirit of this advice?
Exposing the public API is a valid reason to do that, but depending on programming language, I would rather use an interface for this purpose. It also makes your code easier to test.
To make things more complicated, I know from experience that some developers (typically those trained in math) tend to to structure things like a proof, with "atoms" first, building up to larger entities.
While reading this, I realized I unknowingly followed a mixed pattern, where I would use cohesion and sorting both.
Like, first group the variables by related meaning, then sort these groups alphabetically.
Much like
```
filters,
setFilters,
result,
setResult,
title,
setTitle,
```
At least I have seen many .Net projects where developers with near OCD have taken great care to define collapsible regions for constructors, properties, public methods and private methods. While it looks nice and tidy, I see it as a big anti-pattern to arrange methods by protection. In terms of readability it can almost be worse than random order, because you are guaranteed that the sub elements are placed very far from the invocation, and the ideal reading order
I'd love to have one of those re-ordered as an example.
Does this depend on language? I ask because I’m JS, for example, “consumed” methods precede “consumer” methods (because IIRC methods are evaluated top-down when the file is loaded) as opposed to Ruby, for example, that will typically have the inverse.
This is true for lisps, but in JavaScript it is just convention (with exception if you declare functions as let/const bindings).
One of good examples IMO is hls.js library - https://github.com/video-dev/hls.js/blob/master/src/hls.ts
Notice how they grouped together methods of Hls class by their logical context:
on()
once()
removeAllListeners()
off()
attachMedia()
detachMedia()
startLoad()
stopLoad()
Class itself is pretty big (>800LOC) and it can be hard to find what you need without that cohesive grouping.
I like (within the file) "calls should always go down" and "...should be as close as reasonable."
So the "main" or "entry point" function is always at the top and widely reused functions are near the bottom end.
One of example last I know is
validate1()
validate2()
use1()
use2()
Was transformed into
validate1()
use1()
validate2()
use()
In some rare case the first one might be useful if the use1 is really slow and we have command line tool which takes hours to execute. Sometimes, it is sad to look into the results in an hour and realize there was a mistake in a command line argument.
Are you looking for real-world example with some domain information?
The ideal example is 1) real open source code and 2) requires domain knowledge all readers share. 2) is impossible but worth optimizing for. Bonus points for an actual diff.
I can think of two similar examples that come immediately to mind. For classes, generically, it's a good idea to keep the public methods at the top of the file, as they'll be the "entrypoints" into that logic. Same with react components, it's usually a good idea to put the "main" component at the top of the file, front and center. It's definitely a choice of style, and doesn't have any behavioral impact (most of the time?) but can help the next person to read that module. Is that in the spirit of this advice?
Yes. You're reading some code. You get towards the end of the file. Aha! You think, "Well why didn't they say that up front?"
The tidying is to reorder the elements in the order you wish you could have read them. That's what I'd like examples of.
Exposing the public API is a valid reason to do that, but depending on programming language, I would rather use an interface for this purpose. It also makes your code easier to test.