I agree with the thrust of the article but my conclusion is slightly different.
In my experience the issue is sometimes that Step 1 doesn't even take place in a clear cut way. A lot of what I see is:
1. Design algorithms and data structures
2. Implement and test them
Or even:
1. Program algorithms and data structures
2. Implement and test them
Or even:
1. Implement
2. Test
Or even:
1. Test
2. Implement
:-(
IMO, this last popular approach gets things completely backwards. It assumes there is no need to think about the problem before hand, to identify it, to spend any amount of time thinking about what needs to happen on a computer for that problem to be solved... you just write down some observable behaviors and begin reactively trying to implement them. Huge waste of time.
The point also about "C-style languages being more appealing" is well taken. It's not so much about the language in particular. If you are able to sit down and clearly articulate what you're trying to do, understand the design tradeoffs, which algorithms and data structures are available, which need to be invented... you could do it in assembly if it was necessary, it's just a matter of how much time and energy you're willing to spend. The goal becomes clear and you just go there.
I have an extensive mathematical background and find this training invaluable. On the other hand, I rarely need to go so far as carefully putting down theorems and definitions to understand what I'm doing. Most of this happens subliminally somewhere in my mind during the design phase. But there's no doubt that without this training I'd be much worse at my job.
Or even: 1. Test 2. Implement
IMO, this last popular approach gets things completely backwards. It assumes there is no need to think about the problem before hand
I think you misunderstand this approach.
The point of writing the tests is to think about the desired behaviour of the system/module you are implementing, before your mind gets lost in all the complexities which necessarily happens during the implementation.
When you write code, and hit a wall, it’s super easy to get hyper-focused on solving that one problem, and while doing so: lose the big picture.
Writing tests first can be a way to avoid this, by thinking of the tests as a specification you think you should adhere to later, without having to worry about how you get there.
For some problems, this works really well. For others, it might not. Just don’t dismiss the idea completely :)
I'm being a little rhetorically over the top. Of course, sometimes it's what you have to do.
In fact, right now I'm doing exactly Test/Implement because I don't know how else to solve the problem. But this is a last resort. Only because the first few attempts failed and I must solve this problem have I resorted to grinding out individual cases. The issue is that I have my back against the wall and have to solve a problem I don't understand. But as I progress, eventually I will understand the problem, and then my many cases are going to get dramatically simplified or even rewritten.
But all the tests I've created along the way will stay...
Reminds me of the attempt to TDD a way to a sudoku solver. Agreed that it is a bit of a crazy path.
Not that Implement/Test can't work. As frustrating as it is, "just do something" works far better than many alternatives. In particular, with enough places doing it, somebody may succeed.
Comments
I agree with the thrust of the article but my conclusion is slightly different.
In my experience the issue is sometimes that Step 1 doesn't even take place in a clear cut way. A lot of what I see is:
Or even: Or even: Or even: :-(IMO, this last popular approach gets things completely backwards. It assumes there is no need to think about the problem before hand, to identify it, to spend any amount of time thinking about what needs to happen on a computer for that problem to be solved... you just write down some observable behaviors and begin reactively trying to implement them. Huge waste of time.
The point also about "C-style languages being more appealing" is well taken. It's not so much about the language in particular. If you are able to sit down and clearly articulate what you're trying to do, understand the design tradeoffs, which algorithms and data structures are available, which need to be invented... you could do it in assembly if it was necessary, it's just a matter of how much time and energy you're willing to spend. The goal becomes clear and you just go there.
I have an extensive mathematical background and find this training invaluable. On the other hand, I rarely need to go so far as carefully putting down theorems and definitions to understand what I'm doing. Most of this happens subliminally somewhere in my mind during the design phase. But there's no doubt that without this training I'd be much worse at my job.
I think you misunderstand this approach.
The point of writing the tests is to think about the desired behaviour of the system/module you are implementing, before your mind gets lost in all the complexities which necessarily happens during the implementation.
When you write code, and hit a wall, it’s super easy to get hyper-focused on solving that one problem, and while doing so: lose the big picture.
Writing tests first can be a way to avoid this, by thinking of the tests as a specification you think you should adhere to later, without having to worry about how you get there.
For some problems, this works really well. For others, it might not. Just don’t dismiss the idea completely :)
I'm being a little rhetorically over the top. Of course, sometimes it's what you have to do.
In fact, right now I'm doing exactly Test/Implement because I don't know how else to solve the problem. But this is a last resort. Only because the first few attempts failed and I must solve this problem have I resorted to grinding out individual cases. The issue is that I have my back against the wall and have to solve a problem I don't understand. But as I progress, eventually I will understand the problem, and then my many cases are going to get dramatically simplified or even rewritten.
But all the tests I've created along the way will stay...
Reminds me of the attempt to TDD a way to a sudoku solver. Agreed that it is a bit of a crazy path.
Not that Implement/Test can't work. As frustrating as it is, "just do something" works far better than many alternatives. In particular, with enough places doing it, somebody may succeed.