-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
Annotate @doc metadata when something is a guard #7893
Conversation
I like the current approach. As I don't think we should add a new kind due to the complexity of the changes (and likely breaking changes too).
I would make it reserved. The check could see if the current module is Elixir.Kernel and, if not, raise accordingly. In case we don't have the current module when we check right now, maybe we could do the check later, when we are storing the metadata in the docs table instead of when it is set. |
@josevalim I agree, I wasn't comfortable starting on the more invasive changes.
We have access to the module, but it's going to be a bit more complex than that. Currently we're doing the check in I'm thinking of creating an internal (but not private) function Do you think this would be the right approach? |
Oh, I see. I don't like having private functions like that for Elixir only because it means folks can't have their own |
Annotated all the existing guards and added tests. The current behaviour of IEx is that it uses |
Maybe it's better to mark all the functions and macros that can be used as guards with OR... Here is a crazy? idea What do you think about having both If we go down this path, we could mark functions and macros accordingly. In addition, IEx could use |
I think |
That said, we may go with So, |
Right. Any macro marked with To clarify, my main concern was those macros in Kernel that are allowed in guards but are not marked with
I think |
Good point. We should also mark any macro allowed in guards, such as |
I tried marking all existing guards with `@doc guard: true`. Let me know if
I missed any. Currently on mobile and it would be difficult to check.
…On 2018. Jul 13., Fri at 17:53, José Valim ***@***.***> wrote:
To clarify, my main concern was those macros in Kernel that are allowed in
guards but are not marked with @doc <https://github.com/doc>
allowed_in_guard: true, like Kernel.is_nil/1.
We should also mark any guard, such as is_nil/1, as @doc guard: true. It
can even show up as defguard in the docs. The only reason why we can't
use defguard itself is for bootstrap reasons. From the user perspective, it
is exactly the same as defguard.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#7893 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAAFSGxq5HL6tlAB80V9BasvRzegXlqOks5uGMJ3gaJpZM4VOGqp>
.
|
@lackac we are talking about this part:
The idea is to mark any macro allowed in guards, even if IEx does not display the proper signature.
However, I would go with |
Here are the ones I found: There are other things that are allowed in guards, such as sigils and I guess then it becomes slightly debatable if we should say that |
|
|
@michalmuskala good point. But the error messages are good in this case so I would put it on the list for documentation purposes and let the error message guide users. I think that's better than not tagging it. Thoughts? |
lib/iex/lib/iex/introspection.ex
Outdated
defp kind_to_def(:function), do: :def | ||
defp kind_to_def(:macro), do: :defmacro | ||
defp kind_to_def(:function, _), do: :def | ||
defp kind_to_def(:macro, true), do: :defguard |
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.
Last comment, promise 😅
I would go with defmacro
here when displaying macros marked with @doc guard: true
. As I mentioned in one of the comments, some developers might think that macros with the defguard
signature are only allowed inside guards (like the macros in Bitwise
and Kernel
). I actually checked if Elixir was raising any errors if a guard defined with defguard
was used outside of a guard.
Could defmacro
+ guard: true
be easier to understand? (this would require to print guard: true
here)
Sorry for commenting this again, I just wanted to be sure this was not overlooked :)
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.
Given both defmacro and def can be used in guards, I guess showing it as guard: true
is the best way to go as it would apply in both cases. 👍
❤️ 💚 💙 💛 💜 |
Related to #7845.
This is a draft implementation after doing some experimentation with various ways of doing this. The current approach introduces the least amount of changes to make it work.
Other approaches:
:defguard
/:defguardp
as kind and move the@doc guard: true
call todefine/4
.store_definition
would be called with:defmacro
/:defmacrop
.This would have the added benefit of having more precise error messages in the
assert_*
functions.:defguard
/:defguardp
This would be the most invasive change as there are a lot of places where we do something for
:defmacro
/:defmacrop
that would have to be extended for guards. However, this would allow us to addguard: true
to the metadata inModule.compile_definition_attributes/6
which could in turn allow makingguard
a reserved metadata key. This last benefit is lost however if we need to add@doc guard: true
to builtin guards likeis_binary
which are defined as plain functions.Another thing to consider is whether to make the
guard
metadata key reserved. If we don't that might result in confusing behaviour if someone starts using it for other purposes (however unlikely). If we do, that will require a workaround for builtin guards.