Thank you, Steven. Your explanations are clear and helpful.
But then I don't know how to obtain the behavior I want.
A) I don't want to completely replace Base's signif because I still want
access to Julia's methods. For instance, my method only works in base 10,
so I don't want to lose Julia's ability to calculate signif() in other
bases. When I "personally" call signif (e.g. at the REPL), I want my new
method to be dispatched for specific-enough input types. If I do
signif(1.2,2) I want to get 1.2. If signif(1.2,2,2), I want 1.0 (base 2).
Even if at some point I want to invoke Julia's method on base 10, I still
want to be able to do signif(1.2,2,10) and get 1.2000000000000002 instead
of my method's 1.2.
That is easy to achieve, because Julia's methods are:
signif(x, digits::Integer)
signif(x, digits::Integer, base::Integer)
which do not specify the type of x, so after "import Base.signif", as soon
as I add a method like
function signif(x::Float64, digits::Integer)
if x is a Float64 my method will be chosen, because it is more
type-specific.
B) But neither do I want to affect all modules calling signif, because then
any package that calls signif would alter its behavior. This means that my
method should be invisible to packages. [If I understand you well, both
defining "function Base.signif", or alternatively doing "import
Base.signif" before defining "function signif", both will affect all
modules calling signif, no?]
Summarising: my REPL (or my Main module or whatever module I want) should
see Julia's methods plus my own; but installed packages should only see
Julia's methods.
P.S.1 Choosing a different function name, like function felipesignif(),
would work, because no package will call felipesignif(), but it is not
something I like too much, because my function does essentially the same
thing as Julia's, only with more care about roundoff errors (at the cost of
some speed, which is not needed for my intended purposes). The natural
thing is to use the same function name, possibly with an optional third
input argument "options" to control its behavior regarding dealing with
roundoff errors.
P.S.2 Of course my question was a somewhat general one regarding best
practices, rather than this specific signif() issue. Julia's design
encourages adding new methods to existing functions. Is nobody else worried
that installed packages can be affected by new methods?
On Tuesday, January 13, 2015 at 8:30:21 PM UTC+1, Steven G. Johnson wrote:
>
> In any module, if you define "function signif", it will completely replace
> Base's signif (for *all* argument types), but only within that module;
> other modules will not be affected. Defining things in the REPL is
> equivalent to defining them within the module Main.
>
> If, instead, you want to add a new method signature to the Base.signif
> function, you should define "function Base.signif", or alternatively
> "import Base.signif" before defining "function signif". This will affect
> all modules calling signif.
>