New method for 'Base.sum'

function Base.sum(f, v::MyType)
    return sum(f, values(v))
end

In the Github package I am reading, the author introduced a lot of new methods for julia builtin functions.

Is this a common practice in programming, especially in a big project? As far as I can understand, the new method has to be introduced because the original sum function has no method matching the user-defined Type.

Yes this is very common if one wants to extend a function to work with one’s own type. This avoids shadowing the function, we just had this discussion yesterday:

1 Like

My rules of thumb for adding methods to existing functions are

  • only add a method signature that contains a type that you created (no “type piracy”), and
  • don’t add a new arity (number of arguments) to an existing function, and
  • be consistent with the interface of any existing arity.

For example

function Base.sum(f, v::MyType)

had better sum over the values of f evaluated on each element of the collection v.

I think this is a good conservative policy.

4 Likes

You are seeing a taste of how Julia’s multiple dispatch plays into package composability. Package composability is when packages interact to provide mixed features, here you heave a Base function extended to a package’s MyType. Like jar1 says, there are good practices to prevent chaos. Avoiding “type piracy” is another way of saying that added functionality should belong in the package where they should be developed and tested; for example, if you made a Base method on Base types, then it should be developed within base Julia, not your own package.

Composability also occurs in other languages without multiple dispatch. In OO languages, you can make a subclass with a few overridden basic methods that are dispatched at runtime in the suite of larger methods in an imported parent class. Julia calls the collection of basic methods an interface, and it works much the same way when the interface only varies the type over one argument. However, by encapsulating methods in a multimethod instead of dividing them among classes, Julia allows you to extend functions in a distant location over multiple arguments without requiring any of them be subtypes (assuming a function with only 1 method foo(::Int), you can extend it to foo(::MyNumber) when Int has no relation with MyNumber except <:Any), and if you do adhere to an interface’s types, it can vary over multiple arguments, lessening the need to stuff data in 1 composite type to dispatch on. Composability has gotten to the point that v1.9 introduced package extensions for the purpose of precompiling code when a set of packages are installed in the same environment and automatically loading the code when the packages are imported in the same session.

2 Likes

Just an FYI @jiang_ming_zhang, the julia documentation has a lot of great information on questions like this question, and also nearly all of your previous recent questions Julia Documentation · The Julia Language

You’re of course welcome to ask questions here all you like, but I’d still recommend reading the documentation as it can be a lot more systematic.

5 Likes

And if reading the manual is not your preferred way of getting acquainted with a language, there are many other resources: tutorials, videos, online courses, books etc - many of them free. Find some here:

1 Like