5 ms·
Hmm, perhaps I am misreading this? Your understanding of ML languages is correct. I have always found “Uncle Bob” condescending and obnoxious so I can’t speak t
by nicklecompte 5y ago
Hmm, perhaps I am misreading this? Your understanding of ML languages is correct. I have always found “Uncle Bob” condescending and obnoxious so I can’t speak to the actual source material.
I am putting more emphasis on the “reading top-to-bottom” aspect and less on the level of abstraction itself (might be why I’m misreading it). My understanding was that Bob sez a function shouldn’t call any “helper” functions until the helpers have been defined - if it did, you wouldn’t be able to “read” it. But with your comment, maybe he meant that you should define your lower-level functions as prototypes, implement the higher-level functions completely, then fill in the details for the lower functions at the bottom. Which is situationally useful but yeah, overkill as a hard rule.
In ML and F# you can certainly call interfaces before providing an implementation, as long as you define the interface first. Whereas in C# you can define the interface last and call it all you want beforehand. This is what I find confusing, to the point of being bad practice in most cases.
So even if I misread specifically what (the post said) Bob was saying, I think the overall idea is what Bob had in mind.
- Izkata 5y ago> I am putting more emphasis on the “reading top-to-bottom” aspect and less on the level of abstraction itself (might be why I’m misreading it). My understanding was that Bob sez a function shouldn’t call any “helper” functions until the helpers have been defined - if it did, you wouldn’t be able to “read” it. But with your comment, maybe he meant that you should define your lower-level functions as prototypes, implement the higher-level functions completely, then fill in the details for the lower functions at the bottom. Neither really, he's saying the higher-level abstractions go at the top of the file, meaning the helpers go at the bottom and get used before they're defined. No mention of prototypes that I remember. Personally, I've never liked that advice either - I always put the helpers at the top to build up the grammar, then the work is actually done at the bottom.
- tsimionescu 5y agoIt seems your idea is precisely the opposite of Robert Martin's. What he is advocating for is starting out the file with the high-level abstractions first, without any of the messy details. So, at the top level you'd have a function that says `DoTheThing() { doFirstPart(); doSecondPart();}`,then reading along you'd find out what doFirstPart() and doSecondPart() mean (note that I've used imperative style names, but that was a random choice on my part). Personally I prefer this style, even though I dislike many other ideas in Clean Code. The requirement to define some function name before you can call it is specific to a few languages, typically older ones. I don't think it's very relevant in this context, and there are usually ways around it (such as putting all declarations in header files in C and C++, so that the actual source file technically begins with the declarations from the compiler's perspective, but doesn't actually from a programmer perspective (it just begins with #include "header").