From 76128efbcbdd53dbcb5fc50bde33efa960da05ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Raz=20Guzm=C3=A1n=20Macedo?= Date: Tue, 28 Nov 2017 08:19:06 -0600 Subject: [PATCH 1/8] add @pure docstring and example 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 | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/base/expr.jl b/base/expr.jl index 602c7499edcef..ac9b1664eec59 100644 --- a/base/expr.jl +++ b/base/expr.jl @@ -184,6 +184,56 @@ 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. +Do not use if the function involved: + +- Involves globals, pointers +- Recurses +- Does not return exactly (`===`) the same result for the same input +- Gets its methods extended after it is called + +### Example + +```julia-repl + +julia> immutable 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# + +Body: + begin + return ((Core.apply_type)(Main.Discrete, false, false)::Type{Discrete{_,_}} where _ where _)()::Discrete{_,_} where _ where _ + end::Discrete{_,_} where _ where _ + +julia> immutable Discrete{apply_map,scale_by_time} end + +julia> Base.@pure Discrete2(;apply_map=false,scale_by_time=false) = Discrete{apply_map,scale_by_time}() +Discrete + +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# + +Body: + begin + return $(QuoteNode(Discrete{false,false}())) + end::Discrete{false,false} +``` +""" macro pure(ex) esc(isa(ex, Expr) ? pushmeta!(ex, :pure) : ex) end From d36e196ce80c87fb3f2660a8fffc8a8cf935b1af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Raz=20Guzm=C3=A1n=20Macedo?= Date: Tue, 28 Nov 2017 08:44:49 -0600 Subject: [PATCH 2/8] Change immutable to mutable struct --- base/expr.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/base/expr.jl b/base/expr.jl index ac9b1664eec59..5abc66b97aec8 100644 --- a/base/expr.jl +++ b/base/expr.jl @@ -191,6 +191,7 @@ Annotates a function to ease type inference by strictly specifying the output is completely determined by the input. Note: Misuse can lead to regressions. + Do not use if the function involved: - Involves globals, pointers @@ -202,7 +203,7 @@ Do not use if the function involved: ```julia-repl -julia> immutable Discrete{apply_map,scale_by_time} end +julia> mutable struct Discrete{apply_map,scale_by_time} end julia> Discrete(;apply_map=false,scale_by_time=false) = Discrete{apply_map,scale_by_time}() Discrete @@ -216,7 +217,7 @@ Body: return ((Core.apply_type)(Main.Discrete, false, false)::Type{Discrete{_,_}} where _ where _)()::Discrete{_,_} where _ where _ end::Discrete{_,_} where _ where _ -julia> immutable Discrete{apply_map,scale_by_time} end +julia> mutable 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 From 75c08e7246f05b75d7ef3bebd3ddc4a5c93c9c2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Raz=20Guzm=C3=A1n=20Macedo?= Date: Tue, 28 Nov 2017 08:52:02 -0600 Subject: [PATCH 3/8] discard mutable --- base/expr.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base/expr.jl b/base/expr.jl index 5abc66b97aec8..912968d24a5e9 100644 --- a/base/expr.jl +++ b/base/expr.jl @@ -203,7 +203,7 @@ Do not use if the function involved: ```julia-repl -julia> mutable struct Discrete{apply_map,scale_by_time} end +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 @@ -217,7 +217,7 @@ Body: return ((Core.apply_type)(Main.Discrete, false, false)::Type{Discrete{_,_}} where _ where _)()::Discrete{_,_} where _ where _ end::Discrete{_,_} where _ where _ -julia> mutable struct Discrete2{apply_map,scale_by_time} end +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 From 53f4feba36ddf3f5d2d233ebb1aea553b5ddcc32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Raz=20Guzm=C3=A1n=20Macedo?= Date: Tue, 28 Nov 2017 13:37:51 -0600 Subject: [PATCH 4/8] reduce verbosity in description --- base/expr.jl | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/base/expr.jl b/base/expr.jl index 912968d24a5e9..ed107568a91cb 100644 --- a/base/expr.jl +++ b/base/expr.jl @@ -187,10 +187,8 @@ 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. +Usage can easily lead to whole program corruption or crashes and should be avoided +by beginners. Do not use if the function involved: @@ -198,6 +196,7 @@ Do not use if the function involved: - Recurses - Does not return exactly (`===`) the same result for the same input - Gets its methods extended after it is called +- Uses dispatch on one of its arguments ### Example From 8bf15615e4d0e483e018137f03eec5c61ea802e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Raz=20Guzm=C3=A1n=20Macedo?= Date: Tue, 28 Nov 2017 18:19:33 -0600 Subject: [PATCH 5/8] elide example, correct usability point --- base/expr.jl | 37 +------------------------------------ 1 file changed, 1 insertion(+), 36 deletions(-) diff --git a/base/expr.jl b/base/expr.jl index ed107568a91cb..739fb1bfc8012 100644 --- a/base/expr.jl +++ b/base/expr.jl @@ -188,7 +188,7 @@ end @pure Usage can easily lead to whole program corruption or crashes and should be avoided -by beginners. +by all users. Do not use if the function involved: @@ -198,41 +198,6 @@ Do not use if the function involved: - Gets its methods extended after it is called - Uses dispatch on one of its arguments -### Example - -```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# - -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 - -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# - -Body: - begin - return $(QuoteNode(Discrete{false,false}())) - end::Discrete{false,false} -``` """ macro pure(ex) esc(isa(ex, Expr) ? pushmeta!(ex, :pure) : ex) From 5320afe9ec4eb8fdda540c95018d1cf3c591d374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Raz=20Guzm=C3=A1n=20Macedo?= Date: Tue, 28 Nov 2017 19:07:49 -0600 Subject: [PATCH 6/8] any in dispatch misuse --- base/expr.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/expr.jl b/base/expr.jl index 739fb1bfc8012..3c5d92044eb2c 100644 --- a/base/expr.jl +++ b/base/expr.jl @@ -196,7 +196,7 @@ Do not use if the function involved: - Recurses - Does not return exactly (`===`) the same result for the same input - Gets its methods extended after it is called -- Uses dispatch on one of its arguments +- Uses dispatch on any of its arguments """ macro pure(ex) From 4a1034a8d640828776b8275515787d572e55b037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Raz=20Guzm=C3=A1n=20Macedo?= Date: Tue, 28 Nov 2017 22:35:17 -0600 Subject: [PATCH 7/8] restore description --- base/expr.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/base/expr.jl b/base/expr.jl index 3c5d92044eb2c..fd343aef25714 100644 --- a/base/expr.jl +++ b/base/expr.jl @@ -187,13 +187,15 @@ end """ @pure +Annotates a function to ease type inference by strictly specifying the +output is completely determined by the input. + Usage can easily lead to whole program corruption or crashes and should be avoided by all users. Do not use if the function involved: - Involves globals, pointers -- Recurses - Does not return exactly (`===`) the same result for the same input - Gets its methods extended after it is called - Uses dispatch on any of its arguments From 15a9c64e3ce49c472da4dc04c880b288151be452 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Raz=20Guzm=C3=A1n=20Macedo?= Date: Tue, 28 Nov 2017 23:37:46 -0600 Subject: [PATCH 8/8] ENGAGE PHOTON BLASTERS --- base/expr.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base/expr.jl b/base/expr.jl index fd343aef25714..98dcb9c13e9bb 100644 --- a/base/expr.jl +++ b/base/expr.jl @@ -185,7 +185,7 @@ macro noinline(ex) end """ - @pure + @hyperpure Annotates a function to ease type inference by strictly specifying the output is completely determined by the input. @@ -201,7 +201,7 @@ Do not use if the function involved: - Uses dispatch on any of its arguments """ -macro pure(ex) +macro hyperpure(ex) esc(isa(ex, Expr) ? pushmeta!(ex, :pure) : ex) end