# Extending the standard library

**URL:** <https://discourse.julialang.org/t/extending-the-standard-library/18480>\
**Category:** General Usage\
**Tags:** question\
**Created:** [December 9, 2018, 6:36am UTC](https://discourse.julialang.org/t/extending-the-standard-library/18480 "2018-12-09T06:36:08Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jtfrederico](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jtfrederico/32/6366_2.png) [@jtfrederico](https://discourse.julialang.org/u/jtfrederico)\
**Post date:** [December 9, 2018, 6:36am UTC](https://discourse.julialang.org/t/extending-the-standard-library/18480/1 "2018-12-09T06:36:08Z")

</div>

I have a question: I can extend the standard library by inserting methods into other namespaces. E.g.:

```julia
struct Fun
end

function Base.close(fun::Fun)
    print("Fun can't be closed")
end

```

Is it generally a good idea or a bad idea to extend functions this way?

I come from C++, where putting anything in the STL’s namespace is considered a Very Bad Thing. So I expect “no,” but I’m in a discussion elsewhere with somebody who thinks it’s the right thing to do. Is there a stylistic convention or technical reason to do things one way or the other?

---

<div class="post-metadata">

**Author:** ![simonbyrne](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simonbyrne/32/19_2.png) [@simonbyrne](https://discourse.julialang.org/u/simonbyrne)\
**Post date:** [December 9, 2018, 7:14am UTC](https://discourse.julialang.org/t/extending-the-standard-library/18480/2 "2018-12-09T07:14:08Z")

</div>

No, it’s not really a problem, in fact it is sometimes necessary (e.g. to change how an object prints you need to define a `Base.show` method).

The one thing you should avoid is what has become called “type piracy”, basically defining new methods for types which your package didn’t itself define. So your example is okay (since you defined `Fun`), but it would not be okay to define say `Base.close(s::String)`.

For more details, see the [Style Guide section of the manual](https://docs.julialang.org/en/v1/manual/style-guide/#Avoid-type-piracy-1).

---

<div class="post-metadata">

**Author:** ![chakravala](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chakravala/32/6832_2.png) [@chakravala](https://discourse.julialang.org/u/chakravala)\
**Post date:** [December 9, 2018, 11:35am UTC](https://discourse.julialang.org/t/extending-the-standard-library/18480/3 "2018-12-09T11:35:39Z")

</div>

When you are worried about type piracy, you can also use `ForceImport` to make it an optional extension,

> **[GitHub - chakravala/ForceImport.jl: Macro that force imports conflicting...](https://github.com/chakravala/ForceImport.jl)**
>
> Macro that force imports conflicting methods in modules - GitHub - chakravala/ForceImport.jl: Macro that force imports conflicting methods in modules

Which I previously explained on here before

> [@Operations on expressions](https://discourse.julialang.org/t/operations-on-expressions/13666/12):
>
> The principle which all @force users must keep in mind is this: the goal is to extend Base methods locally without affecting the global method table by type piracy, and to be able to import them into another package to have the same local effect. In order to avoid the type piracy, one must define a new local complementary n-ary method that will fall back on the base method with Any arguments. Then there will be a tiered alternative dispatch layer within the local package scope that redirects to …

This way you don’t have to extend the `Base` methods by default and modified methods can be located inside your custom module; while giving the option to locally `force` their import contained in a namespace with `@force using Module`, giving you the best of both worlds locally and globally.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [December 9, 2018, 12:28pm UTC](https://discourse.julialang.org/t/extending-the-standard-library/18480/4 "2018-12-09T12:28:11Z")

</div>

> [@jtfrederico](#):
>
> Is it generally a good idea or a bad idea to extend functions this way?

This is totally fine in Julia, and we do it all the time.

When defining a new method for a function, you just need to make sure that _either_:

1. At least one of the argument types is from your module

Or

1. The function itself is from your module.

Your example above satisfies option 1, so you’re good.

Type piracy happens when you don’t satisfy either condition, like if you were to define `Base.close(x::Array)`. That’s bad because it can cause other code that doesn’t use your functions or types at all to mysteriously change behavior.

---

<div class="post-metadata">

**Author:** ![jlapeyre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlapeyre/32/4514_2.png) [@jlapeyre](https://discourse.julialang.org/u/jlapeyre)\
**Post date:** [December 9, 2018, 1:08pm UTC](https://discourse.julialang.org/t/extending-the-standard-library/18480/5 "2018-12-09T13:08:29Z")

</div>

In fact, it’s an important part of the design of Julia. You are expected to add methods to a function (e.g from `Base`) for semantically similar operations. Functions are not owned by data types.

Here are the modules defining methods for `print` in Base and the stdlib, and packages that happen to be loaded. There are many more methods for `print` in other packages

```julia
julia> using StatsBase;

julia> countmap([m.module for m in methods(print).ms])
Dict{Module,Int64} with 14 entries:
  LibGit2.Consts => 17
  Base.Docs => 2
  Base => 14
  LibGit2 => 1
  Base.Grisu => 2
  Pkg.Types => 5
  Pkg.REPLMode => 3
  LibGit2.Error => 2
  REPL.TerminalMenus => 1
  DataFileHeaders => 1
  Sockets => 2
  Base.MPFR => 2
  Base.Multimedia => 1
  Distributed => 1

```

These aren’t separate object methods, but rather methods of a single function.
