-
-
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
Defunctorize #15804
Defunctorize #15804
Conversation
Is there a point in keeping the content of |
Can't that be adressed with |
Nice net deletion of code. |
Like |
Excellent. I was hoping someone would take a crack at this (I've been wanting to myself). |
We do need to figure out a workable deprecation strategy. |
Maybe, but I think it would require an |
map!(f::Function, dest::BitArray, A::BitArray, B::BitArray) = map!(specialized_bitwise_binary(f), dest, A, B) | ||
map!(f::typeof(!), dest::BitArray, A::BitArray) = map!(~, dest, A) | ||
map!(f::typeof(zero), dest::BitArray, A::BitArray) = falses(dest) | ||
map!(f::typeof(one), dest::BitArray, A::BitArray) = trues(dest) |
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.
these should write into dest, not return a new array
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.
Well spotted. And this also indicates that tests are missing...
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.
yes, though it can be tricky to test that in place methods are actually in place, and we don't do it explicitly as often as we should
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.
Interestingly, it did work as it was as falses(dest)
and trues(dest)
do change their argument. But I'll open a separate issue or PR for that and have changed the implementation here to call fill!
.
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.
Indeed, falses(::BitArray)
and trues(::BitArray)
are undocumented methods with a behavior very different from what one could expect. I'd say your current code is fine if we keep these methods. Better open an issue/PR to document them, or remove them altogether.
EDIT: by "remove", I actually meant "restrict the signature to a tuple or varargs of integers.
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.
I was going to implement falses(::BitArray)
and trues(::BitArray)
to behave similar to zeros(::AbstractArray)
and document that. EDIT: See #15827.
How about a dedicated macro (perhaps in Compat) for conditional functorization to avoid the hassles involved in integrating this in |
That seems like a much simpler solution. I.e. something like |
@andreasnoack yes, that is exactly what I meant. |
1e9829d
to
32e9196
Compare
any idea which packages that would affect? another way to deal with this is to just skip the dep-warning (e.g. rely on backwards compatibility instead of upgrading and using Compat's forward compatibility). or the packages that care can just branch and pin the current version for v0.4 |
@vtjnash Assuming
I haven't checked where use of functors is actually performance critical and not just out of habit. But I assume even closer examination will leave enough affected packages to warrant a working deprecation strategy. Ideas so far:
Opinions? |
I like deprecating now but double-checking that the packages still work correctly (at least in cases where they work on master without this PR), and going with something like |
32e9196
to
c9a8b36
Compare
Rebased and updated to also remove functors introduced in #15585. |
|
||
function is_hermsym(A::SparseMatrixCSC, check::Func) | ||
function is_hermsym(A::SparseMatrixCSC, check::Function) |
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.
@vtjnash Did the following comment on my PR that changed the same thing as this one:
it would be better not to use ::Function in a signature, now that everything it callable, that distinction can be a bit fuzzy
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.
True, Callable
(as an alias for Union{Function,DataType}
that could easily be changed in the future) would probably be better, but Function
is used all over the place in signatures. Maybe better handled in separate PR?
Searching for
Of those, the only one not working (as tested with Edit: Somehow I missed that DataArray fails on master, too. But once that is fixed, the issue of |
Submitted a PR for |
Looks really great. I agree we can deal with the signature issue separately; at least Sorry this sat long enough to pick up a merge conflict---there's a lot of (exciting) churn right now. Can I ask you to kindly rebase, and we'll see how the tests fare again? |
c9a8b36
to
5d3a2b5
Compare
Ok, rebased. Also, I added a deprecation for Also, I'm not at all happy with the deprecation output:
is bad enough. But
is absolutely unacceptable. Is there any remedy short of tweaking the deprecation code in module.c? |
@@ -1057,6 +1057,8 @@ for (Fun, func) in [(:IdFun, :identity), | |||
(::Type{typeof($(func))})() = $(func) | |||
end | |||
end | |||
@deprecate_binding CentralizedAbs2Fun typeof(centralizedabs2fun(0)).name.primary |
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.
Can the type of the anonymous function instantiated in centralizedabs2fun
somehow be determined without calling it with a dummy argument?
AppVeyor failure looks unrelated. Any ideas? |
DictChannel not defined. Have seen it before, unrelated but annoying. |
@tkelman , can you post a link / gist of the DictChannel error? |
appveyor doesn't overwrite past logs, check the history for the previous build edit: https://ci.appveyor.com/project/JuliaLang/julia/build/1.0.684/job/pptqpykoho0d71h2 |
I imagine that you tried simply |
Just deprecating Nevertheless, being told to use |
If there's a way to avoid breaking this use case, please choose it. Even the current obscure deprecation message is better than a plain failure. |
I don't think there's a way to do that. Wouldn't the strategy here break if |
@nalimilan I wouldn't mind if it just was obscure. But it's actually really bad advise: "use Base.##557#558 instead." No, please don't! If you manage to interpret that as
Now, this is obscure. |
The following functors are deprecated: IdFun, AbsFun, Abs2Fun, ExpFun, LogFun, and ConjFun. Specialization for BitArray map! is done by dispatching on function type instead of using helper type BitFunctorUnary. Also a add a few tests for those.
Deprecate AndFun, OrFun, XorFun, AddFun, DotAddFun, SubFun, DotSubFun, MulFun, DotMulFun, RDivFun, DotRDivFun, LDivFun, IDivFun, DotIDivFun, ModFun, RemFun, DotRemFun, PowFun, MaxFun, MinFun, LessFun, MoreFun, DotLSFun, and DotRSFun. Rewrite specialization of BitArray map! to use function types and a helper type BitChunkFunctor for operations without a named function.
@martinholters I don't think anybody smart enough to find that |
@nalimilan Good point. Having found There is another range of functors which are currently defined outside of functors.jl which I have removed rather than deprecated. I could also deprecated these. For For
I'd strongly favor 1. |
Let me add that I found no uses of all of these in the wild outside of Julia, with the exception of |
5d3a2b5
to
0429c38
Compare
Rebased and added the missing "easy" deprecations. |
As a deprecation strategy, my feeling is that this (i.e., this PR combined with JuliaLang/Compat.jl#184) is probably as good as it gets---in this case, it's a particularly complex problem for which there is no perfect solution. This should catch the large majority of cases. Moreover, since functors were not an exported interface, all uses outside of base knew they were reaching into an internal implementation. There's a long tradition of not caring too much about breakages that occur from such changes. I also really like how you took the occasion of this big cleanup to notice a few loose ends and add missing tests, etc. I'll give folks a few more hours to raise any remaining concerns, but I'll merge this soon if no one else does. |
Nice cleanup! |
@martinholters Thank you for tackling this! Well done. |
Thank you all for all the positive feedback I got! Not only is Julia a nice language to program in, it also seems to be programmed by nice people. |
Someone could close #15692 now. |
PS: @martinholters Github will automatically close related issues if you include something like |
Deprecate (almost) everything in functors.jl (see #15692) and also otherwise remove now-unnecessary functor constructs. Comments on the choice of what to deprecate and what to remove are especially welcome as I was rather unsure there!
Two functor-like constructs have been kept/introduced (
Predicate
andBitChunkFunctor
) to convey additional information to dispatch upon. ForPredicate
this would be "function is pure and returns a Bool". Is there any way of wringing that out of Julia automatically, or are these tag types needed?