Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Function redefinition problem #119

Closed
antoine-levitt opened this issue Dec 16, 2016 · 6 comments
Closed

Function redefinition problem #119

antoine-levitt opened this issue Dec 16, 2016 · 6 comments

Comments

@antoine-levitt
Copy link

antoine-levitt commented Dec 16, 2016

Hi,

using DifferentialEquations

function f(t,u)
    print(u)
    u
end

u0 = 1.0
prob = ODEProblem(f,u0,(0.0,1.0))
solve(prob)

include() this file once, redefine f by commenting out the print(), include it again, the print() still gets called. What's going on here?

julia> versioninfo()
Julia Version 0.5.0
Commit 3c9d753 (2016-09-19 18:14 UTC)

DifferentialEquations.jl commit 0e86aab

@ChrisRackauckas
Copy link
Member

Hey,
This is just a standard way that Julia work. Functions are considered by default constants and so it's usually not a good idea to keep re-defining them. This is so that way they can inline and improve performance. However, you can read up on some user issues with it here

JuliaLang/julia#18725

(the Julia core devs are working on making this nicer, but the infamous issue JuliaLang/julia#265 is getting in the way right now, but should be fixed on v0.6)

However, there is an easy fix. Instead of using a function, you can use an anonymous function. These have no issues with function re-definitions. There is a short form:

f = (t,u) -> (print(u); u)

which is for writing one-line anonymous functions, and a long form:

f = function (t,u)
   print(u)
   u
end

for writing multi-line anonymous functions. Since v0.5, anonymous functions compile and therefore they have no performance disadvantage. Additionally, if you need to write extra dispatches on an anonymous function, you can via call overloading:

function (T::typeof(f))(t,u,du)
  println(u)
  println(du)
  u,du
end

so there's really no disadvantage to using an anonymous function in this case.

Let me know if this helps. I'll keep this open for awhile if you have any more questions, though this is more of an issue with Julia itself.

@antoine-levitt
Copy link
Author

Thanks for the explanations! I thought that function redefinition in Julia worked as I expect them to, and it just prints warnings. I convinced myself that it was not a Julia issue because of the following:

function f()
    2
end
@show f()
function f()
    3
end
@show f()

The output is

f() = 2
WARNING: Method definition f() in module Main at /home/antoine/test_functions.jl:2 overwritten at /home/antoine/test_functions.jl:8.
f() = 3

as expected. So what's different between that and the ODE snippet I pasted?

@ChrisRackauckas
Copy link
Member

See my response here: https://www.reddit.com/r/Julia/comments/5i53ij/const_v_static/

I think it's because in this example, @show f() compiles f and inlines the constant. In the ODE example it must realize that it has to recompile. That sounds like JuliaLang/julia#265 behavior, which can be mysterious but should be fixed soon.

@antoine-levitt
Copy link
Author

I see, so it is a Julia issue and not a DifferentialEquations.jl issue, sorry for the noise and thanks for the explanation!

If anybody finds this thread and is as confused as I am, if I understand correctly, the official advice is "don't redefine functions", and the recommended workflow for the modify/test loop is to put everything inside modules, where function redefinition is allowed (because it's this case, it's the module that gets redefined, and inter-module inlining is not allowed, I guess?) I hope it'll get fixed and function redefinitions are allowed, though...

@ChrisRackauckas
Copy link
Member

Or you can use anonymous functions. They are just as performant and you can even add dispatches to them, as I showed above. They don't have function re-definition problems.

@ChrisRackauckas
Copy link
Member

Closing this because this isn't actionable, but it'll stay around in search for whoever else runs into this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants