One example of how rules can produce unwanted results is the rule a*0=0. This would always seem to be true. However, when a is a vector, like a:={b,c,d} , then a*0 should actually return {0,0,0} , that is, a null vector. The rule a*0 -> 0 actually changes the type of the expression from a vector to a integer! This can have severe consequences when other functions using this expressions as an argument expect a vector, or even worse, have a definition of how to work on vectors, and a different one for working on numbers.
When writing rules for an operator, it is assumed that the operator working on arguments, like Sin or *, will always have the same properties regardless of the arguments. The Taylor series expansion of Sin(a) will be the same regardless of whether a is a real number, complex number or even a matrix. The same trigonometric identities should hold for Sin, regardless of the type of a, too.
If a function is defined which does not adhere to these rules when applied to another type, a different function should be defined.
By default, if a variable has not been bound yet, it is assumed to be a number. If it is in fact a more complex object, like a vector, then you can declare a to be an 'incomplete type' vector, using Object("IsVector",a). This subexpression will evaluate to a if and only if a is a vector at that moment of evaluation. Otherwise it returns unevaluated, and thus stays an incomplete type.
So this means the type of a variable is numeric unless otherwise stated by the user, using the "Object" command. No rules should ever work on incomplete types. It is just meant for delayed simplification.
The topic of implicit type of an object is important, since many rules often implicitly need to be able to assume something is a number.
The problem mentioned above with a rule for vectors and scalars could be solved by making two rules:
a*b (b a vector) -> return vector of each component multiplied by a.
a*0 -> 0
So vector multiplication would be tried first.
The ordering of the precedence of the rules in the standard math scripts is currently: