44[ ![ 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 )
55[ NEWS] ( NEWS.md )
66
7- [ ![ SimpleTraits] ( http://pkg.julialang.org/badges/SimpleTraits_0.5.svg )] ( http://pkg.julialang.org/?pkg=SimpleTraits )
87[ ![ SimpleTraits] ( http://pkg.julialang.org/badges/SimpleTraits_0.6.svg )] ( http://pkg.julialang.org/?pkg=SimpleTraits )
8+ [ ![ SimpleTraits] ( http://pkg.julialang.org/badges/SimpleTraits_0.7.svg )] ( http://pkg.julialang.org/detail/SimpleTraits )
99
1010This package provides a macro-based implementation of traits, using
1111[ Tim Holy's trait trick] ( https://github.com/JuliaLang/julia/issues/2345#issuecomment-54537633 ) .
@@ -78,15 +78,15 @@ Notes:
7878
7979It can be checked whether a type belongs to a trait with ` istrait ` :
8080``` julia
81- using Base . Test
81+ using Test
8282@test istrait (IsNice{Int})
8383@test ! istrait (BelongTogether{Int,Int}) # only BelongTogether{Int,String} was added above
8484```
8585
8686Functions which dispatch on traits are constructed like:
8787``` julia
88- @traitfn f {X; IsNice{X}} (x :: X ) = " Very nice!"
89- @traitfn f {X; !IsNice{X}} (x :: X ) = " Not so nice!"
88+ @traitfn f (x :: X ) where {X; IsNice{X}} = " Very nice!"
89+ @traitfn f (x :: X ) where {X; ! IsNice{X}} = " Not so nice!"
9090```
9191This means that a type ` X ` which is part of the trait ` IsNice ` will
9292dispatch 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
101101
102102Similarly for ` BelongTogether ` which has two parameters:
103103``` julia
104- @traitfn f {X,Y; BelongTogether{X,Y}} (x :: X ,y :: Y ) = " $x and $y forever!"
104+ @traitfn f (x :: X ,y :: Y ) where {X,Y; BelongTogether{X,Y}} = " $x and $y forever!"
105105@test f (5 , " b" )== " 5 and b forever!"
106106@test_throws MethodError f (5 , 5 )
107107
108- @traitfn f {X,Y; !BelongTogether{X,Y}} (x :: X ,y :: Y ) = " $x and $y cannot stand each other!"
108+ @traitfn f (x :: X ,y :: Y ) where {X,Y; ! BelongTogether{X,Y}} = " $x and $y cannot stand each other!"
109109@test f (5 , 5 )== " 5 and 5 cannot stand each other!"
110110```
111111
@@ -172,8 +172,8 @@ Example:
172172@traitdef Tr{X}
173173
174174fn (x:: Integer ) = 1 # a normal method
175- @traitfn fn {X<:AbstractFloat; Tr{X}} (x :: X ) = 2
176- @traitfn fn {X<:AbstractFloat; !Tr{X}} (x :: X ) = 3
175+ @traitfn fn (x :: X ) where {X<: AbstractFloat ; Tr{X}} = 2
176+ @traitfn fn (x :: X ) where {X<: AbstractFloat ; ! Tr{X}} = 3
177177
178178@traitimpl Tr{Float32}
179179@traitimpl Tr{Int} # this does not impact dispatch of `fn`
@@ -188,15 +188,15 @@ one trait. Continuing above example, this *does not work* as one may
188188expect:
189189``` julia
190190@traitdef Tr2{X}
191- @traitfn fn {X<:AbstractFloat; Tr2{X}} (x :: X ) = 4
191+ @traitfn fn (x :: X ) where {X<: AbstractFloat ; Tr2{X}} = 4
192192
193193@traitimpl Tr2{Float16}
194194fn (Float16 (5 )) # -> 4; dispatch through traits
195195fn (Float32 (5 )) # -> MethodError; method defined in previous example
196196 # was overwritten above
197197```
198198This last definition of ` fn ` just overwrites the definition `@traitfn
199- f{X; Tr{X}}(x::X) = 2` from above.
199+ f(x::X) where {X; Tr{X}} = 2` from above.
200200
201201If you need to dispatch on several traits in a single trait-method,
202202then 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.)
327327
328328Note also that trait functions can be generated functions:
329329``` julia
330- @traitfn @generated fg {X; IsNice{X}} (x :: X ) = (println (x); :x )
330+ @traitfn @generated fg (x :: X ) where {X; IsNice{X}} = (println (x); :x )
331331```
332332
333333# Innards
@@ -346,16 +346,16 @@ julia> macroexpand(:(@traitimpl Tr{Int}))
346346SimpleTraits. trait {X1 <: Int} (:: Type{Tr{X1}} ) = Tr{X1}
347347SimpleTraits. istrait {X1 <: Int} (:: Type{Tr{X1}} ) = true # for convenience, really
348348
349- julia> macroexpand (:(@traitfn g {X; Tr{X}} (x :: X ) = x+ 1 ))
349+ julia> macroexpand (:(@traitfn g (x :: X ) where {X; Tr{X}}= x+ 1 ))
350350
351- @inline g {X} (x:: X ) = g (trait (Tr{X}), x) # this is Tim's trick, using above grouping-function
352- g {X} (:: Type{Tr{X}} ,x:: X ) = x + 1 # this is the logic
351+ @inline g (x:: X ) where {X} = g (trait (Tr{X}), x) # this is Tim's trick, using above grouping-function
352+ g (:: Type{Tr{X}} ,x:: X ) where {X} = x + 1 # this is the logic
353353
354- julia> macroexpand (:(@traitfn g {X; !Tr{X}} (x :: X ) = x+ 1000 ))
354+ julia> macroexpand (:(@traitfn g (x :: X ) where {X; ! Tr{X}}= x+ 1000 ))
355355
356356# the trait dispatch helper function needn't be defined twice,
357357# only the logic:
358- g {X} (:: Type{ Not{Tr{X}} } , x:: X ) = x + 1000
358+ g (:: Type{ Not{Tr{X}} } , x:: X ) where {X} = x + 1000
359359```
360360
361361For a detailed explanation of how Tim's trick works, see
@@ -372,8 +372,8 @@ definitions.
372372Example, dispatch on whether an argument is immutable or not:
373373
374374``` julia
375- @traitfn f {X; IsImmutable{X}} (x :: X ) = X (x. fld+ 1 ) # make a new instance
376- @traitfn f {X; !IsImmutable{X}} (x :: X ) = (x. fld += 1 ; x) # update in-place
375+ @traitfn f (x :: X ) where {X; IsImmutable{X}} = X (x. fld+ 1 ) # make a new instance
376+ @traitfn f (x :: X ) where {X; ! IsImmutable{X}} = (x. fld += 1 ; x) # update in-place
377377
378378# use
379379mutable struct A; fld end
0 commit comments