Programmers tend to write software in the opposite direction of their language’s history. That is, people using bottom-up languages tend to write their software top-down. And people using top-down languages tend to write their software bottom-up.
This is a very interesting observation, and I tend to agree.
I think that this pattern exists because, as programmers, we tend to be anti-procrastinators when it comes to technical difficulty. Sure, we’ll procrastinate the political nonsense (meetings, requirements whatevering, etc.) but we actually like to do the most challenging technical things (the parts that might fail, requiring us to change course, but also from which we learn the most) first.
If you’re using a low-level language (or Java, which isn’t really low-level insofar as it’s unsuitable for truly low-level work, but takes low-level inspiration) then the technical challenge is getting big things done. It takes a lot of work just to get macroscopically-interesting projects built in those languages. On the other hand, if you’re using a high-level language, the hard part is getting the pieces to fit together precisely and reliably, so programmers tend to focus on correctness, which requires starting small and building up.
I tend to think that, in general, the bottom-up approach is better for both low-level and high-level programming, because I put a high value on correctness and think that quickness of coding (barring egregious slippage) is massively overrated. I tend to think that it’s better to take a week and do something correctly than to take 4 hours to hammer out “Agile” code that occasionally wipes a hard drive or produces bad trades.
surprised this is getting so little attention on here; it’s a really interesting point.
i think the difference lies in the grain of the language - most bottom-up languages encourage a compositional style where the unit of abstraction is the low-level building block (types and functions) and at each level the way to build up the next level is to combine them in various ways to form larger blocks.
top-down languages tend to encourage a more decompositional style, where the basic unit of abstraction is a bunch of sequenced statements wrapped in a function call, and sharing code between those functions happens more often as a refactoring step than as an up-front design.
This is a very interesting observation, and I tend to agree.
I think that this pattern exists because, as programmers, we tend to be anti-procrastinators when it comes to technical difficulty. Sure, we’ll procrastinate the political nonsense (meetings, requirements whatevering, etc.) but we actually like to do the most challenging technical things (the parts that might fail, requiring us to change course, but also from which we learn the most) first.
If you’re using a low-level language (or Java, which isn’t really low-level insofar as it’s unsuitable for truly low-level work, but takes low-level inspiration) then the technical challenge is getting big things done. It takes a lot of work just to get macroscopically-interesting projects built in those languages. On the other hand, if you’re using a high-level language, the hard part is getting the pieces to fit together precisely and reliably, so programmers tend to focus on correctness, which requires starting small and building up.
I tend to think that, in general, the bottom-up approach is better for both low-level and high-level programming, because I put a high value on correctness and think that quickness of coding (barring egregious slippage) is massively overrated. I tend to think that it’s better to take a week and do something correctly than to take 4 hours to hammer out “Agile” code that occasionally wipes a hard drive or produces bad trades.
surprised this is getting so little attention on here; it’s a really interesting point.
i think the difference lies in the grain of the language - most bottom-up languages encourage a compositional style where the unit of abstraction is the low-level building block (types and functions) and at each level the way to build up the next level is to combine them in various ways to form larger blocks.
top-down languages tend to encourage a more decompositional style, where the basic unit of abstraction is a bunch of sequenced statements wrapped in a function call, and sharing code between those functions happens more often as a refactoring step than as an up-front design.