-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Wishlist: delete_method #20048
Comments
wonder if this is implementable by setting the max world age for that method to be very low? |
It's probably conceptually similar. However, I currently only tracked additive edges. To delete something, you have to track the deletion edges also. I didn't do that already since I think it would make adding methods and ambiguity detection more expensive (these are the main costs of incremental deserialization). It might be possible for someone to backload more of the work onto the actual deletion to make this feasible. |
What if there were an |
Even without any change in Base, we could replace the deleted method with an |
Not sure that would work. What if you regret introducing a specialization but have multiple fallbacks, which one should you call? You'd have to do a lot of julia-code reflection to determine how to write that method. Conversely, if we introduce an |
Create a dummy function with all methods of f except the ones that were deleted, then use |
@vtjnash, I looked into this a bit more. Is there anything wrong with this? # Notes on deleting functions
using Base.Test
# Example in https://github.com/JuliaLang/julia/issues/20048
foo(x) = bar(x)
bar(x) = 1
bar(x::Int) = 2
@test bar(7) == 2
@test foo(7) == 2
# We're going to delete the bar(::Int) specialization.
# Figure out who calls it. In this demo, I haven't gotten around to *using* this information yet,
# so this is just to show it can be done.
callers = Set{Method}()
for c in methods(bar)
isdefined(c, :specializations) || continue
tme = c.specializations
isa(tme, TypeMapEntry) || continue
mi = tme.func
for b in mi.backedges
push!(callers, b.def)
end
end
# Now delete the bar(x::Int) method
ml = methods(bar)
mt = ml.mt
mt.cache = nothing # recompile all. TODO: drop only the TypeMapEntry for the method we're deleting
# The method we want to delete is the most specific, so it's first. Drop it.
mt.defs = mt.defs.next
# Delete the first signature
deleteat!(ml.ms, 1)
@test bar(7) == 1
# TODO: invalidate the appropriate methods in `callers`
@test foo(7) == 1 |
Closed by timholy/Revise.jl#57 |
@timholy is your post two posts up still an acceptable way to do it? (like how revise does it) just wondering before i check something into julz edit: i just used delete_method from the pull request above |
As Jameson says, it's a bit broken and apparently risks crashing your session. It also doesn't yet handle I just skimmed Julz, and it seems like it's kind of like |
Julz is a wrapper for Pkg.generate but also loads every file and gives you a little bit of a framework to work off of // see: include_all_files and export_all_files (and the like) |
With #265 fixed, there has been a substantial drop in the number of reasons to restart a julia session. One of the remaining reasons, changing a type definition, seems hard to fix. However, another reason (one that might be pretty easy now?) is to remove a method specialization that affects dispatch. For example, let's say I've defined
If later I decide I didn't need/want that specialization
bar(x::Int)
, it seems my only choices are to (1) define it to have the same code as the genericbar
method, or (2) restart julia.The text was updated successfully, but these errors were encountered: