Skip to content

Rename pure to unsafe_pure and remove unnecessary/improper uses #27432

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

Closed
wants to merge 7 commits into from

Conversation

helgee
Copy link
Contributor

@helgee helgee commented Jun 5, 2018

See dicussion here https://discourse.julialang.org/t/bug-in-doc-system-and-question-on-pure-in-docs-meaning-julia-1-0-is-close/11292

This should send a clear signal to beginners that this macro should be handled with care.

Since it is not exported, there is no deprecation and NEWS entry needed, right?

@KristofferC
Copy link
Member

It would be kind to give a deprecation anyway since we know this is frequently used outside Base.

@helgee
Copy link
Contributor Author

helgee commented Jun 6, 2018

Added the deprecation. CI is super unhappy but I do not take responsibility for this 😜

FWIW: I experienced the same hangs after UUIDs as seen on AV locally on macOS.

Copy link
Member

@vtjnash vtjnash left a comment

Choose a reason for hiding this comment

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

It's nice to see that we're so close to deprecating @pure! But I see you missed the alternate spelling (@_pure_meta) used during bootstrap – should we make these consistent?

return Const(length(argtypes[2].val))
elseif length(argtypes) == 3 && isa(argtypes[2], Const) && isa(argtypes[3], Const) &&
isa(argtypes[2].val, SimpleVector) && isa(argtypes[3].val, Int) && istopfunction(tm, f, :getindex)
# mark getindex(::SimpleVector, i::Int) as @pure
# mark getindex(::SimpleVector, i::Int) as @unsafe_pure
Copy link
Member

Choose a reason for hiding this comment

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

These two should probably say "as pure", since it's only indirectly connected to the @pure macro

@@ -1374,7 +1374,7 @@ for cases where you don't need a more elaborate hierarchy.
julia> struct Val{x}
end

julia> Base.@pure Val(x) = Val{x}()
julia> Base.@unsafe_pure Val(x) = Val{x}()
Copy link
Member

Choose a reason for hiding this comment

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

The @unsafe_pure annotation should be unnecessary (@inline should achieve the same results, but should also be unnecessary since this function is small)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removing the annotation has the added benefit of getting @[unsafe_]pure out of the manual.

@@ -403,7 +403,7 @@ _RowVector_depstring() = string("`ConjRowVector` and `RowVector` have been depre
"of the associated changes.")

@inline check_types(::Type{T1}, ::AbstractVector{T2}) where {T1,T2} = check_types(T1, T2)
@pure check_types(::Type{T1}, ::Type{T2}) where {T1,T2} = T1 === transpose_type(T2) ? nothing :
@unsafe_pure check_types(::Type{T1}, ::Type{T2}) where {T1,T2} = T1 === transpose_type(T2) ? nothing :
error("Element type mismatch. Tried to create a `RowVector{$T1}` from an `AbstractVector{$T2}`")
Copy link
Member

Choose a reason for hiding this comment

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

This isn't safe (or necessary) to mark as @pure (the transpose_type function may break the compiler if used from a function marked @pure)

@@ -135,7 +135,7 @@ BroadcastStyle(a::AbstractArrayStyle, ::Style{Tuple}) = a
BroadcastStyle(::A, ::A) where A<:ArrayStyle = A()
BroadcastStyle(::ArrayStyle, ::ArrayStyle) = Unknown()
BroadcastStyle(::A, ::A) where A<:AbstractArrayStyle = A()
Base.@pure function BroadcastStyle(a::A, b::B) where {A<:AbstractArrayStyle{M},B<:AbstractArrayStyle{N}} where {M,N}
Base.@unsafe_pure function BroadcastStyle(a::A, b::B) where {A<:AbstractArrayStyle{M},B<:AbstractArrayStyle{N}} where {M,N}
if Base.typename(A).wrapper == Base.typename(B).wrapper
Copy link
Member

Choose a reason for hiding this comment

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

This doesn't need to be marked unsafe_pure. Indeed, the inferable version is shorter:

if Base.typename(A) === Base.typename(B)
    return A(Val(max(M, N)))
end
return Unknown()

(the Val is a side-effect of likely-unnecessary complications in the constructor API above, and could also be deleted with a bit more work)

@helgee
Copy link
Contributor Author

helgee commented Jun 8, 2018

I also renamed the bootstrap version to keep it consistent and to give @vtjnash a convenient possibility to audit the remaining uses of @unsafe_pure/@_unsafe_pure_meta in Base 😉

@helgee helgee changed the title Rename pure to unsafe_pure Rename pure to unsafe_pure and remove unnecessary/improper uses Jun 8, 2018
@StefanKarpinski StefanKarpinski added the triage This should be discussed on a triage call label Jul 16, 2018
@@ -1724,6 +1724,9 @@ end

@deprecate atan2(y, x) atan(y, x)

# PR #27432
@eval @deprecate $(Symbol("@pure")) $(Symbol("@unsafe_pure")) false
Copy link
Member

Choose a reason for hiding this comment

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

I think we can keep @pure as an (non-deprecated) alias for @unsafe_pure too, to avoid breaking the package ecosystem. In the future, we'll weaken the meaning of @pure (probably to something like speculatable), but preferably, most package uses should be able to continue using @pure though that transition. That'll also let me audit Base – as you conveniently offered :) – to indicate which expect to still need the unsafe version.

@StefanKarpinski StefanKarpinski removed the triage This should be discussed on a triage call label Jul 26, 2018
@mbauman
Copy link
Member

mbauman commented Jul 26, 2018

Thanks so much for the PR! I really appreciate the time and effort you put into this — and the discussion that this prompted moved the discussion forward. Jameson's comment (#27432 (comment)) is a great thought. Triage is in support of making Base.@pure do the safer thing folks expect, and then adding a new unsafe version is a great path forward. With all the new constant propagation and optimizer and IPO goodies in 0.7, the extra guarantees of the unsafe version are even more rarely needed.

@helgee
Copy link
Contributor Author

helgee commented Jul 26, 2018

How do I define an alias for a macro? Like this?

# Alias `foo` for `bar`
macro foo(expr)
    :(@bar $expr)
end

@fredrikekre
Copy link
Member

@eval const $(Symbol("@foo")) = $(Symbol("@bar"))

@helgee
Copy link
Contributor Author

helgee commented Jul 26, 2018

I removed the deprecation and added the alias, as suggested. Should I also modify the recently added docstring for @pure, i.e. change it to @unsafe_pure?

@helgee
Copy link
Contributor Author

helgee commented Jul 29, 2018

Bump. Anything left to do?

@helgee
Copy link
Contributor Author

helgee commented Jul 31, 2018

I am not sure I understood the conclusion when this should get in. These changes are not really essential for 0.7/1.0 except for the docs change that removes @pure from the manual.

I could also open a separate PR which only changes the manual.

(OT: I suck at rebasing 😜)

@StefanKarpinski
Copy link
Member

Jameson, can you comment on what should be done here for now?

@helgee
Copy link
Contributor Author

helgee commented Aug 7, 2018

I have opened a separate PR for removing @pure from the manual: #28496

@KristofferC
Copy link
Member

#40097 is an updated version of this and it seems unlikely that we will go through the churn of renaming this.

@helgee helgee deleted the unsafe-pure branch May 10, 2022 12:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants