-
-
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
Finalizers take function as first argument (closes #16307) #24605
Conversation
If we are really going to make this non-sense change, we must document in the docstring of finalizer that the user must not use an anonymous function as finalizer. |
Please pay no attention to @yuyichao – he has been against this change for no explicable reason from the beginning. However, he is the only one who is so vehemently against fixing this lone exception to the "function arguments go first" rule. @yuyichao, please feel free to make a PR adding that to the documentation for |
base/deprecated.jl
Outdated
@deprecate finalizer(o, f::Function) finalizer(f, o) | ||
# This misses other callables but they are very rare in the wild | ||
|
||
@deprecate finalizer(o::T, f::Ptr{Void}) where {T} finalizer(f, o) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
T where T
is Any
, which is the same as applying no type annotation to the argument, so this could be simplified to match the deprecation above it.
NEWS.md
Outdated
finalized as its second (rather than the reverse). For the majorities of uses cases this | ||
will trigger deprecation warnings. However, it will not if the 'function' is not a | ||
subtype of `Function`, nor will it for the ambiguous cases where both arguments are | ||
`Function`s or `Ptr{Void}`s ([#24605]). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The indentation here is all funky. All should be aligned beneath the first `
before "finalizer" or it won't render properly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doh,
my editor has failed to detect that this is a space indented file, and so the tab key has inserted tabs.
I need to sort that out. (both in that file, and in my vim plugin configurations)
NEWS.md
Outdated
* `Base.find_in_path` is now `Base.find_package` or `Base.find_source_file` ([#24320]). | ||
|
||
* `finalizer` now takes functions or pointers as its first argument, and the object being | ||
finalized as its second (rather than the reverse). For the majorities of uses cases this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"For the majority of use cases, this change will..."
NEWS.md
Outdated
|
||
* `finalizer` now takes functions or pointers as its first argument, and the object being | ||
finalized as its second (rather than the reverse). For the majorities of uses cases this | ||
will trigger deprecation warnings. However, it will not if the 'function' is not a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"However, this change will not trigger deprecation warnings where: (1) the callable argument is not a subtype of Function
; or (2) both arguments are Function
s or Ptr{Void}
s ..."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm! Thanks @oxinabox! :)
@ararslan @StefanKarpinski, is this pull request in shape to merge by you?
NEWS.md
Outdated
* `Base.find_in_path` is now `Base.find_package` or `Base.find_source_file` ([#24320]) | ||
* `Base.find_in_path` is now `Base.find_package` or `Base.find_source_file` ([#24320]). | ||
|
||
* `finalizer` now takes functions or pointers as its first argument, and the object being |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of these lines have trailing whitespace, which is causing the CI failures. (It looks like we forgot to set up make check-whitespace
on Circle CI.)
Fixed the whitespace. |
NEWS.md
Outdated
will trigger deprecation warnings. However, it will not if the 'function' is not a | ||
subtype of `Function`, nor will it for the ambiguous cases where both arguments are | ||
* `finalizer` now takes functions or pointers as its first argument, and the object being | ||
finalized as its second (rather than the reverse). For the majorities of use cases |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"majorities" -> "majority"?
NEWS.md
Outdated
subtype of `Function`, nor will it for the ambiguous cases where both arguments are | ||
* `finalizer` now takes functions or pointers as its first argument, and the object being | ||
finalized as its second (rather than the reverse). For the majorities of use cases | ||
deprecation warnings will be triggered. However, deprecation warning will not trigger where: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"warning" -> "warnings"?
NEWS.md
Outdated
* `finalizer` now takes functions or pointers as its first argument, and the object being | ||
finalized as its second (rather than the reverse). For the majorities of use cases | ||
deprecation warnings will be triggered. However, deprecation warning will not trigger where: | ||
(1) the callable argument is not a subtype of `Function`; or (2) when both arguments are |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"when" redundant with the "where" preceding the colon?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be squashed on merge. Thanks for doing this!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @oxinabox! :)
Can someone explain this to me (with an example of what must not be done), as I absolutly don't understand what is the impact of the argument order on what can be allowed as arguments. |
It's totally unrelated, it's just a (imo bogus) argument against fixing the argument order. |
I'm still confused though. Regardless of argument order, Yichao mentioned that finalizers shouldn't use anonymous functions, and yet this change shows that at least half of all uses of |
Right, so the current argument order is clearly in no way preventing anyone – including us – from passing anonymous functions to |
Not only are half the uses in base using anon functions, there are at least a couple that are using closures over local variables that are not directly stored in the objects fields. |
It would be good to have an explanation of why passing anonymous functions to finalizer is bad. If it's considered bad enough, should we fix it in Base? Apparently it's not that bad since we're doing it all over the place. |
from #16307 (comment) :
To which @yuyichao already answered:
|
But why? Are they "bad" in the sense of:
If (1) is the case then yes, we should definitely fix all of them and probably make |
I think it is: For example: malmaud/TensorFlow.jl#342 (comment) And things like I'm not sure why |
A bit more digging into #16307 to try to understand Yichao's points, which seem to confirm point 4.:
And:
So I understand it's a matter of style (3.) rather than technical incorrectness (1. or even 2.). |
But how does replacing an anonymous function (or |
It doesn't. It neither helps nor hinders. I would suggest that the problem only exists for resources that are considered external. |
This leaves us with this conclusion:
Making it slightly syntactically less convenient to pass an anonymous function for this reason is an extremely dubious reason to violate the conventional argument order. It is clearly not effective as a preventative measure since we are already passing anonymous functions to |
I don't understand the issues related to the argument order. However, I think this change is a bit strange and I prefer the previous ordering, since I am used to thinking about attaching a finalizer function to an object and therefore the function I am attaching should come second in argument order to the item I am attaching it to. To me it is pretty strange to have the object declared in the second argument based on this experience. An argument to keep the existing order is that there are default resource cleaning functions and that declaring
However the do syntax functionality is nice with the current ordering (if it is indeed valid to pass anon functions as finalizers, which it seems is discouraged in certain circumstances) edited for clarity. |
All of those arguments apply to every function that takes a function and applies it to an object – which is way beyond the scope of this discussion. |
Note that every reply in this comment are repeating my comments in As a summary, the original order makes it possible to change the
Note that I was following the rule in the top post and I'm only commenting on the effect of the PR.
Correct, the previous comment in this thread is not at all about
For things that are not actually used (created) much, sure.
Correct.
Well, it's not incorrectness in that the code won't crash if you have infinite memory. It's technical in that it'll make it impossible to write correct/robust code. It's not just style since it makes a difference what you can and can't do as the user.
No. It only applies to functions that has clearly an object to operate on that happens to take a function as argument as well. (i.e. |
…16307) (JuliaLang#24605)" This reverts commit 52d81b0.
This closes #16307
Which is a good idea, according to #19150 (comment)
If you do not think this is a good idea, because you think #19150 is wrong, I think that #19150 is the correct place for that debate (rather than this PR).
If finalizer really is going to be deprecated outright, in favor of
close
(something I'm not really keen on).Then I guess this PR can be closed. (as can #16307 ?)
This is a breaking change, and the deprecation don't quiet cover all the cases.
(Though I doubt many of the uncovered cases exist in the wild).
Also some of the cases
finaliser(::Ptr{Void}, ::Ptr{Void})
will fail silently or segfault (though idk if that is legal code in the first place), until updated to swap their argument order.There are no ambiguities in the code.
It needs NEWS.jl, but I'll write that later.
(
Past versions of this PR:
#8775,
#12578
)