Skip to content
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

add @pure docstring and example #24817

Closed
wants to merge 8 commits into from
Closed
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions base/expr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,57 @@ macro noinline(ex)
esc(isa(ex, Expr) ? pushmeta!(ex, :noinline) : ex)
end

"""
@pure

Annotates a function to ease type inference by strictly specifying the
output is completely determined by the input.

Note: Misuse can lead to regressions.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t know what regression means. This should just say “Usage can easily lead to whole program corruption or crashes and should be avoided.”

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean to say "Usage" rather than "Misuse"? 😂


Do not use if the function involved:

- Involves globals, pointers
- Recurses
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What’s wrong with recursion?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It came up during a Discourse post and @mbauman mentioned the restriction.
https://discourse.julialang.org/t/pure-macro/3871

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typejoin is pure and does recursion - seems to be doing OK

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Will ammend.

- Does not return exactly (`===`) the same result for the same input
- Gets its methods extended after it is called

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Uses dispatch on one of its arguments.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!
Clarifying: one, or any of its arguments?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, any.

### Example
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example isn't wrong, but it will almost certainly be made obsolete by #24362


```julia-repl

julia> struct Discrete{apply_map,scale_by_time} end

julia> Discrete(;apply_map=false,scale_by_time=false) = Discrete{apply_map,scale_by_time}()
Discrete

julia> @code_warntype Discrete()
Variables:
#self# <optimized out>

Body:
begin
return ((Core.apply_type)(Main.Discrete, false, false)::Type{Discrete{_,_}} where _ where _)()::Discrete{_,_} where _ where _
end::Discrete{_,_} where _ where _

julia> struct Discrete2{apply_map,scale_by_time} end

julia> Base.@pure Discrete2(;apply_map=false,scale_by_time=false) = Discrete{apply_map,scale_by_time}()
Discrete
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delete me (duplicate code)


julia> Base.@pure Discrete2(;apply_map=false,scale_by_time=false) = Discrete{apply_map,scale_by_time}()
Discrete2 (generic function with 1 method)

julia> @code_warntype Discrete2()
Variables:
#self# <optimized out>

Body:
begin
return $(QuoteNode(Discrete{false,false}()))
end::Discrete{false,false}
```
"""
macro pure(ex)
esc(isa(ex, Expr) ? pushmeta!(ex, :pure) : ex)
end
Expand Down