How to refactor isdefined(OtherModule, :field) to @isdefined? (v0.7)


#1

"I must be missing something obvious"™️ spoiler alert, but basically, like the title says, I can’t figure out how to refactor instances of isdefined(OtherModule, :field) to the new @isdefined. The documentation does not cover this scenario and everything I tried, fails.


#2

Core.eval(Base, :(@isdefined r)) works but I’m not sure that is the best way to do it.


#3

Neat trick, but yeah, looks like overkill :smiley:


#4

That’s better: Core.isdefined(Base, :sin)


#5

I’ve been getting deprecation warnings for isdefined (the function) in 0.7 so I thought the idea was to stop using it? Although the “what’s new in 0.7” readme does not mention deprecation, only the addition of the macro. So I’m not sure…


#6

Why do you want to do it at all? The two are completely different.


#7

That’s identical to isdefined(Base, :sin).

No. isdefined the function is not deprecated. The signature that is deprecated is isdefined(::Symbol) which people tend to think it does what @isdefined currently do but is really isdefined(current_module(), ::Symbol). With the implementation of @isdefined the now deprecated signature will only add confusion and with current_module() gone it’s also impossible to implement anything like that anymore.


#8

@yuyichao I see, that makes total sense. My bad then, I completely misunderstood the deprecation message. Thanks for the clarification.


#9

I agree that the deprecation warning

isdefined(:symbol) is deprecated, use @isdefined symbol instead

does not imply that there is no method for isdefined that has a different signature, and is not deprecated. But, it is suggestive. I’m sure many people are scratching their heads over this these days. Fortunately, this thread is easy to find.


#10

It does not explicitly imply that there’s any other functions that’s not deprecated either. It actually does imply (implicitly) that other signatures are not deprecated since it explicitly says that only single symbol argument is deprecated. There has been many deprecation of method but not functions and I don’t think this is any different.


#11

There has been many deprecation of method but not functions and I don’t think this is any different.

No one is going to ask a question about

julia> ucfirst("cat")
┌ Warning: `ucfirst` is deprecated, use `uppercasefirst` instead.

it explicitly says that only single symbol argument is deprecated.

This is not accurate. It explicitly says no more and no less than that the method of isdefined that takes a single argument of type Symbol is deprecated AND that it has been replaced by @isdefined.

I don’t question the reasons for the addition of @isdefined and change to isdefined. But, people will continue to be confused by it even if we think they ought not be confused, even after the deprecation becomes an error and is forgotten… Adding “see also” the doc string of both the macro and the function might help.


#12

That is NOT an example of deprecating method but not functions, it’s just a deprecation of the function. Just look at ANY use of @deprecate in this file that specifies the signature, those are deprecation of method. In particular, these deprecate some methods of a function to some other methods of a different function, pretty much exactly the same as what’s going on here.

Exactly, only the method of `isdefined` that takes a single argument of type Symbol, so how do you get the idea/confusion that ANY other signature is deprecated as well? If it didn’t metion the :symbol then yes, that should be fixed.

No. You are just saying that a message that says f(::A) is deprecated should somehow make it clear that f(::B) or any other signatures aren’t? How is specifying the signature not clear enough? FWIW, the deprecation message is NOT a doc, it should be a short and concise string telling people what is deprecated and how to fix it. If someone wonders about the reason behind the deprecation or the current (new) behavior, they should have no issue finding the doc since the function and macros involved here are very clear.

OTOH, what IS special about this particular deprecation, which has NOTHING to do with isdefined(::Module, ::Symbol), is that there isn’t an exact substitute of isdefined(::Symbol) anymore, @isdefined ... isn’t it. If you want to improve the deprecation message, linking to the PR that removed such function will be helpful. This doesn’t seem to be causing a lot of problems though so I also kind of doubt if it’s worth doing.


#13

And I assume the OP had this question because he wasn’t familiar with multiple method in the same function. At least I get similar confusions before I got familiar with the concept as well (and now getting the opposite confusion in other languages occasionally when I haven’t got enough sleep…).

This is a very core concept in julia though and

  1. If you want to explain it in depwarn you will have to repeat it in literally everywhere.
  2. Even if you want to repeat it everywhere in the doc, the depwarn is really not the right place to teach people about this…

#14
  1. Both the OP and I are very well aware of multiple methods in the same function. I can see that you object strongly to people being confused about isdefined and @isdefined. In fact, I don’t think it would have taken me long to figure it out. I tried this forum first and got lucky.

  2. That is NOT an example of deprecating method but not functions, it’s just a deprecation of the function.

Thanks for writing this. I think I understand now. If a warning says "foo is deprecated.", this means the function and all of its methods. If a warning says "foo(arg::SomeType) is deprecated", then I know that this method is deprecated, and that there exists at least one other method that is not deprecated. If this understanding is correct, then it would be useful to have this written somewhere users can find it. Maybe this thread is enough. I think referring them to 1753 lines of expression surgery is imprudent. I just took your word for it.

If I had known this, then it would have been clear how to upgrade my calls to isdefined.

  1. Regarding the documentation. This misunderstanding is on me; I should have explained better. I did not mean to refer to the deprecation messages. I was thinking of the doc string for isdefined and the doc string for @isdefined. Neither one mentions the other. So if I saw the deprecation of (a method) of isdefined to @isdefined, and then typed ? @isdefined, I might still be scratching my head for a while.

  2. I seem always to be sleep deprived, maybe that has something to do with the confusion! I just read advice in a book about programming practice: if you are banging your head against something for a while, its a good idea to give it a rest.


#15

I believe that. I’m talking about always having it in mind/knowing it deeply by heart. AFAICT this is just something one get used to after using it many times, rather than something one can just learn after reading some doc.

Not necessarily of course.

This is literally what you said yourself

(any other method of isdefined being deprecated is clearly “more” than that) so I really don’t know what you are asking about. The only thing this thread clearify, I think, is that one method could be deprecated without the other ones being deprecated at the same time. This should be obvious for anyone after being very used to having multiple methods in a single function. Again, as mentioned above, it’s totally normal (by my standard) to not be used to it for long time and before that this is just one of the many places one can get confused subconsciously. Stressing this point more in the doc in more places (but not overdone) is OK as long as it’s not added to error/deprecation messages. If you think this thread is enough though, I have no problem with it.

Sure that can be good. If you want to add it, do make sure to make it clear what’s the difference. I don’t think simply adding See also ... is always a good idea especially for functions/macros with similar functions since the user will have to manually compare the two doc to find the difference.


#16

Thanks for responding. It’s clear now.

I opened an issue about improving the documentation #27978 and prepared a branch that just adds “See also”. If it requires more than this, maybe someone else can weigh in.