There is a subtle difference between this and @rdeits’s example. In both cases the conversion of s into a string (by the function string, via interpolation, etc.) is the same, but look at the line where s is created: overloading Base.show does not only tell how a string created out of a Expression_Symbol will look, but also what string will be used when the object itself is presented.
The recommendation of overloading print when you mean to have a particular string method for your type can be found in the documentation of string itself:
string should usually not be defined directly. Instead, define a method print(io::IO, x::MyType) .
(Likewise, Base.show is the function that should be overloaded if what you want is to change the behavior of repr.)
The string function is called in both cases, but with one argument in the first case and two in the second. Since you have only overloaded the one-argument method of the string function, your method never gets called in the second case. As others have pointed out, one generally does not want to overload string at all, but rather show.