One of the defining moments in my career as a software developer came before I was getting paid to cut code. One of my uni courses required the development of a program to do read a bunch of numbers from a file then add them and display the result. I decided to do this using 80x86 assembler, which we were learning in this unit. I thus spent a weekend writing an assembler program than used DOS interrupts to do this. It had to do things like manage it's own buffer, moving partial data to the start of the buffer then reading more data into the empty portion as necessary. This took some time to implement and validate.
When it came time to demonstrate it, I ran it for the lecturer, who glanced at it, verified that the output looked correct, gave me a 9 (out of 10) then moved on. It was at this point I became enlightened. Everyone else in the class had used C. Doing this in C was about 10 lines of code (I'm not sure exactly, because I didn't use C), and it handled a lot of the low level stuff. Of course, being C it was still fairly low level, but it was orders of magnitude simpler, and it gave the same result. The important lesson here is that high level languages are (provided they're suitable expressive and performant) more effective development tools.
It is therefore somewhat of a surprise to me that I've been writing assembler today. I've been writing some IL for the .NET runtime. This code takes a MethodInfo instance and returns a delegate that can be used to invoke that method on any instance of the method's type. This is done by dynamically generating code to invoke the method. Generating IL seems to be the most effective way to build this, as I can't rely on the presence of a C# compiler and reflection performance would suck too much for this application.
This is possibly a scenario where a dynamic language would be preferable. I may try an equivalent in Python (once I learn sufficient Python) to see the difference.