Yes, we can live without templates by doing more manual work (write the code that the compiler writes, or use void*
to remove type specifics).
Yes, we can live without polymorphism by doing more manual work (using switch statements, or storing your own vtable struct).
Are there instances where they're irreplaceable?
The template and polymorphism approaches give you type safety and compiler enforced behavior (e.g. pure virtual) that can't be replaced with some of the manual methods. For example, std::sort
is safer to use than qsort
which operates on void*
. These manual methods can result in lots of code that has to be bug free and maintained. So it depends on your definition of "irreplaceable". With or without these features, these languages are still Turing complete. Theoretically, you can compute anything in a Turing complete language, so we could theoretically replace all languages with BrainF*ck... We just choose not to ;)