Hmm, but when you add a new type of expression, you still have to write the particular implementation of the functions for that type.
There are other approaches to generic programming where when you add a new datatype, all the already defined functions work, and if you add a new function, it automatically works for all the datatypes.