When I taught programming using Arduino there was a bit of trial and error to see what worked best for students. Going into my first trimester, I thought that the first few weeks would be teaching the basics of coding followed by the second half of the trimester would be students creating their own inventions and building them. That turned out to be way too ambitious and students needed much more time learning how to wire their circuits and write code. My approach towards teaching coding changed from trimester to trimester.
The first trimester, I taught with sample code and expanding that code to solve other problems. This taught students to problem solve and find creative solutions. They had great success finding different parts of the code and changing out numbers. But this was not always the most efficient method to solve the problems at hand. Rather than learning what different sections of the code did, and modifying them accordingly, it was mostly trial and error at random. While this type of perseverance in problem solving is admirable, I believed that students were not learning all they could be. Specifically, they were not fully understanding the programs that they were writing and as the programs became more and more complex, they became increasingly difficult to modify using the students preferred trial and error strategy.
The next trimester I had students follow tutorials to write their own code from scratch. While the tutorials literally told students how to write the sample code from the first trimester, line by line, students learned the basics of coding. This taught programming structure, syntax, and coding. When I combined this with their own expansion of the code to solve different problems students learned the most.
Overall, this progression through the different formats of the Arduino class taught me the importance of foundational skills. When those skills are "skipped" or quickly gone over, students will still learn but they may not fully grasp the importance of those skills. Once they see that there is a shortcut, it can be hard to go back and teach those foundations. On the other hand, if you slow down and explicitly teach those foundations they will lay the groundwork for future deep understanding, but the learning takes place much more slowly. In the end, the choice of which instructional strategy to use should be made based on the learning goals. In the case of my class, learning to code was just as important as the problem solving skills to modify the program so I chose to slow down and have students write all the code by hand to learn the foundations. They were then allowed to use any code that they themselves had written so that they knew what every part of their program did. This ended up being the best balance for our learning goals.