- Using local variables instead of global variables
- Using formal loop constructs like "for", "while", and "do", instead of "GOTO"
- Using iterators instead of looping with "for", "while", and "do"
- Program to interfaces instead of implementations
Sometimes Java and Ruby fanboys who do not understand what const-correctness is will assert that one can get the effect of the const keyword with "final" in Java or "freeze" in Ruby. That is utter nonsense.
On the other hand, it is possible to get some of the const effect in Java by creating separate "ConstInterfaces" for each class. Unfortunately, such interfaces do not already exist for the standard library, and I believe that it is not possible to retroactively declare existing classes to conform to a particular Interface, even if they (syntactically) already do conform. The only alternative is to create derived wrapper classes for each standard class, explicitly declaring ConstInterfaces. Even this Herculean approach will fail with the many "final" classes in the standard library. In keeping with the general ultra-wordiness of Java, the reams of additional source files and lines of code required to emulate const-correctness in Java make this approach essentially extinct in the wild.
Ruby fanboys make a big deal about "duck typing", which is a fancy way of describing a lack of static typing. Static typing means that something about the type of each variable can be determined in the local source code context. "Duck typing" is more flexible than static typing in the same way that GOTO statements are more flexible than formal loops. The one big advantage of lack-of-static-typing is that it permits languages like PERL and Ruby to have essentially zero compile time. I love the possibilities that zero-compile-time languages create. But please do not overextend this tradeoff and pretend that "we meant to do that" and that "duck typing" is somehow a desirable language feature. Put the kool aid down.