# Is there a way to know in advance if a function definition will overwrite a previous one?

**URL:** <https://discourse.julialang.org/t/is-there-a-way-to-know-in-advance-if-a-function-definition-will-overwrite-a-previous-one/114670>\
**Category:** General Usage\
**Tags:** question, function\
**Created:** [May 24, 2024, 9:42am UTC](https://discourse.julialang.org/t/is-there-a-way-to-know-in-advance-if-a-function-definition-will-overwrite-a-previous-one/114670 "2024-05-24T09:42:00Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)\
**Post date:** [May 24, 2024, 9:42am UTC](https://discourse.julialang.org/t/is-there-a-way-to-know-in-advance-if-a-function-definition-will-overwrite-a-previous-one/114670/1 "2024-05-24T09:42:00Z")

</div>

I’d like to know if there is any way to know in advance if this can be done, e.g. say I have

```julia
f(x::Int) = 3

```

In pseudo-code I’m trying to do something like

```julia
m = method overwritten by f(x::Int) = 4
if m !== nothing
    Base.delete_method(m)
    f(x::Int) = 4
end

```

Is there a way to know the method `m` which will be eventually overwritten?

**edit:**

In my actual code I have access to the signature of the new definition (as a expression in a macro context), so I thought I could use `methods(f, (Int,))`, but it doesn’t work because it matches the one it will be called even if it will not be overwritten:

```julia
f(x) = 2

```

them

```julia
> methods(f, (Int,))
# 1 method for generic function "f" from Main:
 [1] f(x)
     @ REPL[3]:1

```

---

<div class="post-metadata">

**Author:** ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)\
**Post date:** [May 24, 2024, 10:04am UTC](https://discourse.julialang.org/t/is-there-a-way-to-know-in-advance-if-a-function-definition-will-overwrite-a-previous-one/114670/2 "2024-05-24T10:04:04Z")

</div>

ok maybe

```julia
julia> tuple(methods(f, (Int,))[1].sig.parameters[2:end]...)
(Any,)

```

does the trick to match the signature more strictly

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [May 24, 2024, 11:37am UTC](https://discourse.julialang.org/t/is-there-a-way-to-know-in-advance-if-a-function-definition-will-overwrite-a-previous-one/114670/3 "2024-05-24T11:37:12Z")

</div>

To answer the question from your title:  
Generally no and I think the question might be a [X-Y-Problem](https://xyproblem.info/).

To go into a bit more detail: You can of course try to detect if there is **currently** a method with a given signature but this is not good enough. The method could simply not be defined yet because it is loaded later, or generated later or… IIUC from your example, you would consider `foo(x::Int)` to not overwrite a definition of `foo(x::Any)` but this is not really what Julia’s semantics reflect in my view.

The aim of your question is likely connected to type piracy (perhaps inspired by this current thread: [How to detect/avoid type piracy?](https://discourse.julialang.org/t/how-to-detect-avoid-type-piracy/114588)). If that is the goal, then no meta programming can really help you. Even checking whether a method “exists” before you provide your own definition does not safe you from committing type piracy. Also that check should be stricter than what you showed in your post. Defining `foo(::Int)` for a `foo` you do not own that has a definition for `foo(::Any)` is definitively type piracy and can bite you.  
Perhaps one can argue that defining `foo(::String)` if you don’t own `foo(::Number)` is not quite as bad, as hopefully nobody relied on the `MethodError` being hit, but it still stays type piracy.

---

<div class="post-metadata">

**Author:** ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)\
**Post date:** [May 24, 2024, 12:46pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-know-in-advance-if-a-function-definition-will-overwrite-a-previous-one/114670/4 "2024-05-24T12:46:40Z")

</div>

thanks for the help @abraemer, to add some more context, I’d like actually to redefine a function which was previously defined in the same module (actually by my macro at a previous point inside the module), the problem with just redefining it without any further thought is that I discovered that precompilation is then not possible because it gives a warning “function overwritten at …”. To try to solve this, then I thought I could just try to remove the previous method with `Base.delete_method` but this means I need to identify if and which method was previously defined, I’m doing something along the lines of

```julia
try
    m = which($f_name, tuple($(f_signature...)))
    if tuple($(f_signature...)) == fieldtypes(m.sig)[2:end]
        Base.delete_method(m)
    end
catch
    # no method already defined
end

```

where `f_name` contains an expression of the name of the function and `f_signature` its signature always as a expression. This seems to work fine. Is there any issue with something like that?

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [May 24, 2024, 12:59pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-know-in-advance-if-a-function-definition-will-overwrite-a-previous-one/114670/5 "2024-05-24T12:59:26Z")

</div>

This still sounds a bit confused to me. Let me try to understand better:

1. You define some function in your module (via a macro)
2. Later you overwrite it
3. This gives a warning that precompilation is broken.
4. You want to retain precompilation and thus work around this redefinition.

This raises a couple of question for me:

1. Why do you need to redefine the function at all? Why not just have the latter definition?
2. When you check and see that the function is already defined, then you want to remove the old method and put your new definition into its place, right? That won’t fix precompilation in a meaningful way though. I am not sure what will happen, when you try this, but in the best case the precompilation is just wasted and in the worst case you break something badly, so I would recommend not doing this.
3. If you really need to overwrite methods constantly, then precompilation does not make sense and you should probably just turn it off (by putting ` __precompile__ (false)` at the top of the module). You can possibly put the stuff that needs to change all the time in their own module to still have precompilation for the rest of the code, but tbh my understanding is a bit hazy in that area.
4. If you define the function via a macro, then the easiest thing would be to have that macro generate a bit more code that also does some book keeping for you so you can check for the existence of definitions more easily.

---

<div class="post-metadata">

**Author:** ![Tarny\_GG\_Channie](https://avatars.discourse-cdn.com/v4/letter/t/3bc359/32.png) [@Tarny\_GG\_Channie](https://discourse.julialang.org/u/Tarny_GG_Channie)\
**Post date:** [May 24, 2024, 1:28pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-know-in-advance-if-a-function-definition-will-overwrite-a-previous-one/114670/6 "2024-05-24T13:28:01Z")

</div>

> [@abraemer](#):
>
> If you define the function via a macro, then the easiest thing would be to have that macro generate a bit more code that also does some book keeping for you so you can check for the existence of definitions more easily.

Yeah… or generate some book-keepings of which functions you need to generate and generate all the functions at the end.

---

<div class="post-metadata">

**Author:** ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)\
**Post date:** [May 24, 2024, 8:25pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-know-in-advance-if-a-function-definition-will-overwrite-a-previous-one/114670/7 "2024-05-24T20:25:00Z")

</div>

I have seen this kind of technique in a couple of repos e.g. in ProtoStructs.jl where methods are removed and new ones are added, I would be okay to waste the precompilation of that function, if that still fixes the bad precompilation warnings. At the same time, I don’t really want that something bad happens like undefined behaviours. I thought about ` __precompile__ (false)`, but I wasn’t sure how to apply it to only those function defined (maybe in another package) with my macro, I’m not sure if this is even possible.

But yes fortunately I have already the book-keeping of methods in place, what is keeping me away from just defining all the methods at the end is that I would not want to require the user to register the functions at the end with some other macro, do you know if there is a way to tell Julia to define them at the end of a module automatically @abraemer @Tarny_GG_Channie?

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [May 24, 2024, 8:34pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-know-in-advance-if-a-function-definition-will-overwrite-a-previous-one/114670/8 "2024-05-24T20:34:12Z")

</div>

One thing you could play around with is using more `module`s. I.e. you could about generating a whole module per function and importing the function from there (your macro would generate the necessary code).

Or you could make a single module (with precompilation disabled) for all the functions you need to generate and use `@eval module` to add the functions to that module.

It is kinda hard to suggest useful things without knowing more about your requirements/constraints. If you produce a MWE code for us to play around with, it would be easier to help you.

---

<div class="post-metadata">

**Author:** ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)\
**Post date:** [May 24, 2024, 8:43pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-know-in-advance-if-a-function-definition-will-overwrite-a-previous-one/114670/9 "2024-05-24T20:43:40Z")

</div>

yes, sure no problem: more specifically I’m talking about the @dispatch macro in MixedStructTypes.jl, I discovered this issue when in another package it was tried to be used and it returned the overwriting warnings ([Use dispatch instead of manual branching by Tortar · Pull Request #90 · mastrof/MicrobeAgents.jl · GitHub](https://github.com/mastrof/MicrobeAgents.jl/pull/90)), this is how it works

```julia
julia> using MixedStructTypes

julia> @sum_structs AB begin
           struct A end
           struct B end
       end

julia> @dispatch f(::A) = 1
f (generic function with 1 method)

julia> @dispatch f(::B) = 2
f (generic function with 1 method)

julia> f(A())
1

julia> f(B())
2

```

the dispatch macro actually add/substitute some branches

---

<div class="post-metadata">

**Author:** ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)\
**Post date:** [May 24, 2024, 8:48pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-know-in-advance-if-a-function-definition-will-overwrite-a-previous-one/114670/10 "2024-05-24T20:48:46Z")

</div>

Do you still think that the module tricks you suggest can be used? I’m still digesting the suggestion

---

<div class="post-metadata">

**Author:** ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)\
**Post date:** [May 24, 2024, 9:37pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-know-in-advance-if-a-function-definition-will-overwrite-a-previous-one/114670/11 "2024-05-24T21:37:59Z")

</div>

Maybe I could use something like

```julia
julia> macro m(name)
           e = quote
                    @eval module $name
                        __precompile__ (false)
                        f() = $name
                    end
                    $ __module__.f = $name.f 
               end
           return e
       end
@m (macro with 1 method)

```

which seems to work fine

```julia
julia> @m X
f (generic function with 1 method)

julia> f()
Main.X

julia> @m Y
f (generic function with 1 method)

julia> f()
Main.Y

```

I would whenever I change the function produce a new module like that

---

<div class="post-metadata">

**Author:** ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)\
**Post date:** [May 25, 2024, 1:36am UTC](https://discourse.julialang.org/t/is-there-a-way-to-know-in-advance-if-a-function-definition-will-overwrite-a-previous-one/114670/12 "2024-05-25T01:36:35Z")

</div>

mmh, I hate the solution I proposed, forbidding precompilation for the `@dispatch`-ed functions would have also side effects on other functions in the package which use them I think, something I would not want.

I would just really like to do some bookkeeping and after all macros are expanded in a module (maybe when the last one of that kind is called?) evaluate all the definitions. Do you have any idea how to accomplish this @abraemer? Thanks a lot for the help anyway, really appreciated

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [May 25, 2024, 4:54am UTC](https://discourse.julialang.org/t/is-there-a-way-to-know-in-advance-if-a-function-definition-will-overwrite-a-previous-one/114670/13 "2024-05-25T04:54:24Z")

</div>

Well the inelegant solution would be to just have 2 macros, e.g. `@dispatch_add` and `@dispatch_finish` or so. Where the first ist just used to add branches to the bookkeeping and the second actually generates the definition. You could use this split to allow @dispatch to define multiple branches ones like:

```julia
@dispatch f begin
    f(::A) = 1
    f(::B) = 2
end

```

This would transform to

```julia
@dispatch_add f(::A) = 1
@dispatch_add f(::B) = 2
@dispatch_finish f

```

I don’t think there is a solution that preserves the exact current syntax without downsides. The module solution above should work with precompilation as well (as you can simply generate a new module each time which then will be precompiled) but the huge downside is, that the function name is no longer a `const` value and so using this function for dispatch is using a global… Typing it makes it slightly better but still it will be horrible for performance.

Edit: A slight variant: instead of `@dispatch_finish f` you could have a `@dispatch_generate_all` that just generates all the definitions and then users need to put that once at the very bottom of their module when they decide to use the package. That seems quite low effort to me, so maybe it’s the closest we can get to the current state.

---

<div class="post-metadata">

**Author:** ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)\
**Post date:** [May 25, 2024, 9:56am UTC](https://discourse.julialang.org/t/is-there-a-way-to-know-in-advance-if-a-function-definition-will-overwrite-a-previous-one/114670/14 "2024-05-25T09:56:38Z")

</div>

that is what I thought as well. I’m not sure if there is some sort of trick which could keep entirely the current syntax, e.g. `call_at_the_end_of_the_module(f)`, maybe I want too much 😃

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [May 25, 2024, 10:59am UTC](https://discourse.julialang.org/t/is-there-a-way-to-know-in-advance-if-a-function-definition-will-overwrite-a-previous-one/114670/15 "2024-05-25T10:59:14Z")

</div>

Well I just found a hack 😃 Not saying you should use it though… I am unsure wether this is behavior that should be relied upon.

We can use a `@generated` function to generate the dispatch function on first call from some global variable.  
Consider this behavior:

```julia
@generated function foo(x)
    stmts = [:(if x < $i return $i end) for i in sort(BREAKPOINTS)]
    return Expr(:block, stmts...)
end
BREAKPOINTS = []
push!(BREAKPOINTS, 1)
push!(BREAKPOINTS, 3)
push!(BREAKPOINTS, 5)
push!(BREAKPOINTS, 7)
foo(6.3) # this generates the function with all BREAKPOINTS defined up to here

```

So with this in mind:

1. The first `@dispatch` should register the function name in some global datastore and generate the `@generated function` definition
2. all following `@generated` macros just put their data into the datastore  
That avoids the precompilation issues and retains the exact current semantics for packages at least.

The downsides here are:

1. Of course this function is not precompiled - which a package author could fix by just calling it once in a precompile workload
2. In interactive development adding new branches via `@dispatch` AFTER the function was run once does **NOT** lead to recompilation… This could maybe be fixed by using a second macro `@dispatch_interactive` that behaves like the current `@dispatch` and is intended specifically for interactive use and not for package code.

---

<div class="post-metadata">

**Author:** ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)\
**Post date:** [May 25, 2024, 11:09am UTC](https://discourse.julialang.org/t/is-there-a-way-to-know-in-advance-if-a-function-definition-will-overwrite-a-previous-one/114670/16 "2024-05-25T11:09:37Z")

</div>

Ingenious!! I think 2. could be solved by checking `isinteractive()` and behave differently in that case. 1. is still a bit concerning to me because this means that also any function which contain these `@dispatch` function wouldn’t be precompiled, right?

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [May 25, 2024, 11:13am UTC](https://discourse.julialang.org/t/is-there-a-way-to-know-in-advance-if-a-function-definition-will-overwrite-a-previous-one/114670/17 "2024-05-25T11:13:33Z")

</div>

No I think that’s fine. IIUC precompilation is, if you don’t do anything else manually, essentially just parsing the julia files and creating the bookkeeping stuff. Inference and actual compilation is only part of precompilation if you actually run some functions otherwise Julia doesn’t for what types it should compile methods.

---

<div class="post-metadata">

**Author:** ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)\
**Post date:** [May 25, 2024, 11:17am UTC](https://discourse.julialang.org/t/is-there-a-way-to-know-in-advance-if-a-function-definition-will-overwrite-a-previous-one/114670/18 "2024-05-25T11:17:59Z")

</div>

then, even if it is a bit hacky, I think we have a solution! But I need to test this before crying victory 😃 Thank you a lot @abraemer

---

<div class="post-metadata">

**Author:** ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)\
**Post date:** [May 25, 2024, 11:21am UTC](https://discourse.julialang.org/t/is-there-a-way-to-know-in-advance-if-a-function-definition-will-overwrite-a-previous-one/114670/19 "2024-05-25T11:21:40Z")

</div>

> I am unsure wether this is behavior that should be relied upon.

Before though I could maybe try to open a new thread for this 🙂

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [May 25, 2024, 11:26am UTC](https://discourse.julialang.org/t/is-there-a-way-to-know-in-advance-if-a-function-definition-will-overwrite-a-previous-one/114670/20 "2024-05-25T11:26:28Z")

</div>

Well actually I am sure that this hack breaks the usual contract of generated functions (see 5. in the manual [Metaprogramming · The Julia Language](https://docs.julialang.org/en/v1/manual/metaprogramming/#Generated-functions))  
The thing is that I think it will be relatively fine. Maybe some future Julia version breaks something but I wouldn’t see how really. So while it is technically undefined behavior or something like that, I think it should rather fine. But someone else might have more to say on that. The official recommendation will be to not do it though.

Edit: Thinking about it some more: We really need to try this in a module/precompilation setting… Maybe it the global variable holding the dispatch rules does not survive well into runtime and that would spell doom for this approach. In that case I would resort to the 2 macro variant.

[Next page](https://discourse.julialang.org/t/is-there-a-way-to-know-in-advance-if-a-function-definition-will-overwrite-a-previous-one/114670.md?page=2)
