From c46caf751957ee3fe0afe96c1624055294e63ba1 Mon Sep 17 00:00:00 2001 From: Mauro Werder Date: Mon, 19 Feb 2018 10:50:53 +0100 Subject: [PATCH] Update NEWS, README, CI and REQUIRE Also revert disabled IsConcrete-test --- .travis.yml | 1 - NEWS.md | 5 +++++ README.md | 36 +++++++++++++++++------------------ REQUIRE | 3 +-- appveyor.yml | 2 -- src/SimpleTraits.jl | 11 +++-------- test/base-traits-inference.jl | 9 ++++----- test/base-traits.jl | 1 - 8 files changed, 31 insertions(+), 37 deletions(-) diff --git a/.travis.yml b/.travis.yml index fb8791b..e55dcb5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,6 @@ os: - linux - osx julia: - - 0.6 - nightly # matrix: # allow_failures: diff --git a/NEWS.md b/NEWS.md index de70052..4fabc5b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,8 @@ +# 2018-02-19 + +Transitioned to where-function syntax. Dropped Julia 0.6 support, +with the last release supporting it v0.5.2. + # 2017-11-23 Dropped Julia 0.5 support, last release supporting it is v0.5.1 diff --git a/README.md b/README.md index aa5c03b..e827f4d 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ [![Build Status](https://ci.appveyor.com/api/projects/status/github/mauro3/SimpleTraits.jl?branch=master&svg=true)](https://ci.appveyor.com/project/mauro3/simpletraits-jl/branch/master) [NEWS](NEWS.md) -[![SimpleTraits](http://pkg.julialang.org/badges/SimpleTraits_0.5.svg)](http://pkg.julialang.org/?pkg=SimpleTraits) [![SimpleTraits](http://pkg.julialang.org/badges/SimpleTraits_0.6.svg)](http://pkg.julialang.org/?pkg=SimpleTraits) +[![SimpleTraits](http://pkg.julialang.org/badges/SimpleTraits_0.7.svg)](http://pkg.julialang.org/detail/SimpleTraits) This package provides a macro-based implementation of traits, using [Tim Holy's trait trick](https://github.com/JuliaLang/julia/issues/2345#issuecomment-54537633). @@ -78,15 +78,15 @@ Notes: It can be checked whether a type belongs to a trait with `istrait`: ```julia -using Base.Test +using Test @test istrait(IsNice{Int}) @test !istrait(BelongTogether{Int,Int}) # only BelongTogether{Int,String} was added above ``` Functions which dispatch on traits are constructed like: ```julia -@traitfn f{X; IsNice{X}}(x::X) = "Very nice!" -@traitfn f{X; !IsNice{X}}(x::X) = "Not so nice!" +@traitfn f(x::X) where {X; IsNice{X}} = "Very nice!" +@traitfn f(x::X) where {X; !IsNice{X}} = "Not so nice!" ``` This means that a type `X` which is part of the trait `IsNice` will dispatch to the method returning `"Very nice!"`, otherwise to the one @@ -101,11 +101,11 @@ function. Thus there is no extra mental gymnastics required for a Similarly for `BelongTogether` which has two parameters: ```julia -@traitfn f{X,Y; BelongTogether{X,Y}}(x::X,y::Y) = "$x and $y forever!" +@traitfn f(x::X,y::Y) where {X,Y; BelongTogether{X,Y}} = "$x and $y forever!" @test f(5, "b")=="5 and b forever!" @test_throws MethodError f(5, 5) -@traitfn f{X,Y; !BelongTogether{X,Y}}(x::X,y::Y) = "$x and $y cannot stand each other!" +@traitfn f(x::X,y::Y) where {X,Y; !BelongTogether{X,Y}} = "$x and $y cannot stand each other!" @test f(5, 5)=="5 and 5 cannot stand each other!" ``` @@ -172,8 +172,8 @@ Example: @traitdef Tr{X} fn(x::Integer) = 1 # a normal method -@traitfn fn{X<:AbstractFloat; Tr{X}}(x::X) = 2 -@traitfn fn{X<:AbstractFloat; !Tr{X}}(x::X) = 3 +@traitfn fn(x::X) where {X<:AbstractFloat; Tr{X}} = 2 +@traitfn fn(x::X) where {X<:AbstractFloat; !Tr{X}} = 3 @traitimpl Tr{Float32} @traitimpl Tr{Int} # this does not impact dispatch of `fn` @@ -188,7 +188,7 @@ one trait. Continuing above example, this *does not work* as one may expect: ```julia @traitdef Tr2{X} -@traitfn fn{X<:AbstractFloat; Tr2{X}}(x::X) = 4 +@traitfn fn(x::X) where {X<:AbstractFloat; Tr2{X}} = 4 @traitimpl Tr2{Float16} fn(Float16(5)) # -> 4; dispatch through traits @@ -196,7 +196,7 @@ fn(Float32(5)) # -> MethodError; method defined in previous example # was overwritten above ``` This last definition of `fn` just overwrites the definition `@traitfn -f{X; Tr{X}}(x::X) = 2` from above. +f(x::X) where {X; Tr{X}} = 2` from above. If you need to dispatch on several traits in a single trait-method, then you're out of luck. But please voice your grievance over in pull @@ -327,7 +327,7 @@ Julia 0.5 one could use a generated function but not anymore in Julia 0.6.) Note also that trait functions can be generated functions: ```julia -@traitfn @generated fg{X; IsNice{X}}(x::X) = (println(x); :x) +@traitfn @generated fg(x::X) where {X; IsNice{X}} = (println(x); :x) ``` # Innards @@ -346,16 +346,16 @@ julia> macroexpand(:(@traitimpl Tr{Int})) SimpleTraits.trait{X1 <: Int}(::Type{Tr{X1}}) = Tr{X1} SimpleTraits.istrait{X1 <: Int}(::Type{Tr{X1}}) = true # for convenience, really -julia> macroexpand(:(@traitfn g{X; Tr{X}}(x::X)= x+1)) +julia> macroexpand(:(@traitfn g(x::X) where {X; Tr{X}}= x+1)) -@inline g{X}(x::X) = g(trait(Tr{X}), x) # this is Tim's trick, using above grouping-function -g{X}(::Type{Tr{X}},x::X) = x + 1 # this is the logic +@inline g(x::X) where {X} = g(trait(Tr{X}), x) # this is Tim's trick, using above grouping-function +g(::Type{Tr{X}},x::X) where {X} = x + 1 # this is the logic -julia> macroexpand(:(@traitfn g{X; !Tr{X}}(x::X)= x+1000)) +julia> macroexpand(:(@traitfn g(x::X) where {X; !Tr{X}}= x+1000)) # the trait dispatch helper function needn't be defined twice, # only the logic: -g{X}(::Type{ Not{Tr{X}} }, x::X) = x + 1000 +g(::Type{ Not{Tr{X}} }, x::X) where {X} = x + 1000 ``` For a detailed explanation of how Tim's trick works, see @@ -372,8 +372,8 @@ definitions. Example, dispatch on whether an argument is immutable or not: ```julia -@traitfn f{X; IsImmutable{X}}(x::X) = X(x.fld+1) # make a new instance -@traitfn f{X; !IsImmutable{X}}(x::X) = (x.fld += 1; x) # update in-place +@traitfn f(x::X) where {X; IsImmutable{X}} = X(x.fld+1) # make a new instance +@traitfn f(x::X) where {X; !IsImmutable{X}} = (x.fld += 1; x) # update in-place # use mutable struct A; fld end diff --git a/REQUIRE b/REQUIRE index 2110260..d4b1e2d 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,3 +1,2 @@ -julia 0.6 -Compat 0.26.0 +julia 0.7 MacroTools 0.3.2 diff --git a/appveyor.yml b/appveyor.yml index 2c5a5c5..4ddedc1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,7 +1,5 @@ environment: matrix: - - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe" - - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe" - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe" - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe" diff --git a/src/SimpleTraits.jl b/src/SimpleTraits.jl index 0c9a2f6..f243c65 100644 --- a/src/SimpleTraits.jl +++ b/src/SimpleTraits.jl @@ -2,7 +2,6 @@ __precompile__() module SimpleTraits using MacroTools -using Compat const curmod = nameof(@__MODULE__) import InteractiveUtils @@ -189,7 +188,7 @@ end dispatch_cache = Dict() # to ensure that the trait-dispatch function is defined only once per pair let global traitfn - function traitfn(tfn, cur_module) + function traitfn(tfn, macro_module) # Need # f(x::X,Y::Y) where {X,Y} = f(trait(Tr1{X,Y}), x, y) # f(::False, x, y)= ... @@ -338,7 +337,7 @@ let end # Create the trait dispatch function ex = fn - key = (cur_module, fname, typs0, strip_kw(args0), trait0_opposite) + key = (macro_module, fname, typs0, strip_kw(args0), trait0_opposite) if !(key ∈ keys(dispatch_cache)) # define trait dispatch function if !haskwargs ex = if oldfn_syntax @@ -413,11 +412,7 @@ Defines a function dispatching on a trait. Examples: Note that the second example is just syntax sugar for `@traitfn f(x::X,y::Y) where {X,Y; Not{Tr1{X,Y}}} = ...`. """ macro traitfn(tfn) - @static if isdefined(Base, Symbol("@__MODULE__")) - esc(traitfn(tfn, __module__)) - else - esc(traitfn(tfn, current_module())) - end + esc(traitfn(tfn, __module__)) end ###### diff --git a/test/base-traits-inference.jl b/test/base-traits-inference.jl index a9abbbd..5413742 100644 --- a/test/base-traits-inference.jl +++ b/test/base-traits-inference.jl @@ -5,7 +5,7 @@ # Dict with base-traits to check using value[1] as type and value[2] # as number of lines allowed in llvm code cutoff = 5 -basetrs = [VERSION:Int : :IsConcrete=>:Int, +basetrs = [#VERSION:Int : :IsConcrete=>:Int, :IsBits=>:Int, :IsImmutable=>:Int, :IsContiguous=>:(SubArray{Int64,1,Array{Int64,1},Tuple{Array{Int64,1}},false}), @@ -15,7 +15,6 @@ basetrs = [VERSION:Int : :IsConcrete=>:Int, :IsCallable=>:(typeof(sin)), :IsIterator=>:(Dict{Int,Int})] -# for (bt, tp) in basetrs -# @show bt -# @test @eval @check_fast_traitdispatch $bt $tp true -# end +for (bt, tp) in basetrs + @test @eval @check_fast_traitdispatch $bt $tp true +end diff --git a/test/base-traits.jl b/test/base-traits.jl index 87445bc..8fae39e 100644 --- a/test/base-traits.jl +++ b/test/base-traits.jl @@ -1,5 +1,4 @@ using SimpleTraits.BaseTraits -using Compat: view @test istrait(IsAnything{Any}) @test istrait(IsAnything{Union{}})