-
-
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
add @pure docstring and example #24817
Conversation
I aggregated Chris Rackauckas's and mbauman's discussion form here https://discourse.julialang.org/t/pure-macro/3871/3 Into the docstring.
base/expr.jl
Outdated
Do not use if the function involved: | ||
|
||
- Involves globals, pointers | ||
- Recurses |
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.
What’s wrong with recursion?
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.
It came up during a Discourse post and @mbauman mentioned the restriction.
https://discourse.julialang.org/t/pure-macro/3871
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.
typejoin is pure and does recursion - seems to be doing OK
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! Will ammend.
base/expr.jl
Outdated
Annotates a function to ease type inference by strictly specifying the | ||
output is completely determined by the input. | ||
|
||
Note: Misuse can lead to regressions. |
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 don’t know what regression means. This should just say “Usage can easily lead to whole program corruption or crashes and should be avoided.”
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.
Did you mean to say "Usage" rather than "Misuse"? 😂
base/expr.jl
Outdated
- Recurses | ||
- Does not return exactly (`===`) the same result for the same input | ||
- Gets its methods extended after it is called | ||
|
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.
- Uses dispatch on one of its arguments.
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!
Clarifying: one, or any of its arguments?
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, any.
base/expr.jl
Outdated
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 |
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.
delete me (duplicate code)
base/expr.jl
Outdated
- Gets its methods extended after it is called | ||
- Uses dispatch on one of its arguments | ||
|
||
### Example |
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.
This example isn't wrong, but it will almost certainly be made obsolete by #24362
base/expr.jl
Outdated
- Recurses | ||
- Does not return exactly (`===`) the same result for the same input | ||
- Gets its methods extended after it is called | ||
|
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, any.
base/expr.jl
Outdated
@pure | ||
|
||
Usage can easily lead to whole program corruption or crashes and should be avoided | ||
by beginners. |
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.
"by all users."
The definition of what |
Usage is “do not use”: what’s not to like 😜? |
I think the name of the macro is what makes it so tempting to potential users, even if documented as “really, don’t use this.”. Pure is such a nice word, and people think they know what it means. It’s would be a lot of churn, but is renaming the function to something less exciting something within the realm of possibility for 1.0? |
Sure. I reserve the right to change the name whenever anyone feels so inclined. |
I've proposed |
I can put in the work to get |
Just so you're aware, |
That would explain why I couldn't find examples of it in Base -.- |
-> % rg '@pure'
NEWS.md
374: accessible via the `@pure` constructor `Val(c)`. Functions are defined as
test/inference.jl
400:Base.@pure function fpure(a=rand(); b=rand())
416:# Make sure @pure works for functions using the new syntax
417:Base.@pure (fpure2(x::T) where T) = T
709:Base.@pure b20704(@nospecialize(x)) = f20704(x)
720:Base.@pure g20704(::Int) = 1
725:Base.@pure c20704() = (f20704(1.0); 1)
729:Base.@pure function a20704(x)
980:Base.@pure plus1(x) = x + 1
base/inference.jl
78: actual::Bool # if true, we obtained `val` by actually calling a @pure function
1599:@pure function type_typeof(@nospecialize(v))
3606: # TODO: Improve this analysis; if a function is marked @pure we should really
base/broadcast.jl
153:Base.@pure function BroadcastStyle(a::A, b::B) where {A<:AbstractArrayStyle{M},B<:AbstractArrayStyle{N}} where {M,N}
base/irrationals.jl
31:@pure function convert(::Type{Rational{T}}, x::AbstractIrrational) where T<:Integer
47:@pure function (t::Type{T})(x::AbstractIrrational, r::RoundingMode) where T<:Union{Float32,Float64}
80:@pure function rationalize(::Type{T}, x::AbstractIrrational; tol::Real=0) where T
83:@pure function lessrational(rx::Rational{<:Integer}, x::AbstractIrrational)
84: # an @pure version of `<` for determining if the rationalization of
base/namedtuple.jl
135:@pure function sym_in(x::Symbol, itr::Tuple{Vararg{Symbol}})
142:@pure function merge_names(an::Tuple{Vararg{Symbol}}, bn::Tuple{Vararg{Symbol}})
152:@pure function merge_types(names::Tuple{Vararg{Symbol}}, a::Type{<:NamedTuple}, b::Type{<:NamedTuple})
base/linalg/linalg.jl
20: @propagate_inbounds, @pure, reduce, typed_vcat
base/linalg/rowvector.jl
67:@pure check_types(::Type{T1}, ::Type{T2}) where {T1,T2} = T1 === transpose_type(T2) ? nothing :
doc/src/manual/types.md
1347:julia> Base.@pure Val(x) = Val{x}() There are several places in Julia where |
Is it really necessary to change the name? Why would that stop people from using it (incorrectly)? |
The problem is that a "pure" function has a more familiar sense which this is stricter than. People refer to functions that only depend on their arguments and not on any other mutable program state as being pure. Now technically, if you include the method tables of functions as mutable program state (which it is), then the |
I would still strongly support this change.
Just in my skimming through, I'd imagine that's at least 300 too many. |
I aggregated Chris Rackauckas's and mbauman's discussion form here
https://discourse.julialang.org/t/pure-macro/3871/3
Into the docstring.