# Should I use parametric types with parameters of type Symbol or not?

**URL:** <https://discourse.julialang.org/t/should-i-use-parametric-types-with-parameters-of-type-symbol-or-not/15178>\
**Category:** General Usage\
**Tags:** question\
**Created:** [September 19, 2018, 2:34pm UTC](https://discourse.julialang.org/t/should-i-use-parametric-types-with-parameters-of-type-symbol-or-not/15178 "2018-09-19T14:34:14Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![jbrea](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jbrea/32/3879_2.png) [@jbrea](https://discourse.julialang.org/u/jbrea)\
**Post date:** [September 19, 2018, 2:34pm UTC](https://discourse.julialang.org/t/should-i-use-parametric-types-with-parameters-of-type-symbol-or-not/15178/1 "2018-09-19T14:34:15Z")

</div>

This may be a silly design question, but I had it often enough to feel like asking it here.  
In the following example, would you recommend version 1, where `name` is a parameter or version 2, where `name` is a field? What are your considerations when deciding on such a design question?

```julia
julia> struct FoodItem{name}                                                                   
           weight::Float64                                                                     
           taste::String                                                                       
       end    
                                                                                 
julia> name(::FoodItem{T}) where T = T
                                                                                
julia> @generated function isfruit(::FoodItem{name}) where name                                
           if name == :Apple || name == :Orange                                                
               return :(true)                                                                  
           else                                                                                
               return :(false)                                                                 
           end                                                                                 
       end                                                                                     
isfruit (generic function with 1 method)                                                       
                                                                                               
julia> struct FoodItem2                                                                        
           name::Symbol                                                                        
           weight::Float64                                                                     
           taste::String                                                                       
       end 

julia> name2(x::FoodItem2) = x.name                                                                                    
                                                                                               
julia> isfruit2(x::FoodItem2) = x.name == :Apple || x.name == :Orange                          
isfruit2 (generic function with 1 method)                                                      
                                                                                               
julia> x = FoodItem{:Apple}(.4, "sweet")                                                       
FoodItem{:Apple}(0.4, "sweet")                                                                 
                                                                                               
julia> x2 = FoodItem2(:Apple, .4, "sweet")                                                     
FoodItem2(:Apple, 0.4, "sweet")                                                                
                                                                                               
julia> using BenchmarkTools                                                                    
julia> @benchmark isfruit($x)                                                                  
BenchmarkTools.Trial:                                                                          
  memory estimate: 0 bytes                                                                    
  allocs estimate: 0                                                                          
  --------------
  minimum time: 0.018 ns (0.00% GC)
  median time: 0.022 ns (0.00% GC)
  mean time: 0.021 ns (0.00% GC)
  maximum time: 0.061 ns (0.00% GC)
  --------------
  samples: 10000
  evals/sample: 1000

julia> @benchmark isfruit2($x2)
BenchmarkTools.Trial:
  memory estimate: 0 bytes
  allocs estimate: 0
  --------------
  minimum time: 1.963 ns (0.00% GC)
  median time: 1.976 ns (0.00% GC)
  mean time: 1.984 ns (0.00% GC)
  maximum time: 13.419 ns (0.00% GC)
  --------------
  samples: 10000
  evals/sample: 1000

julia> @benchmark isfruit(x)
BenchmarkTools.Trial:
  memory estimate: 0 bytes
  allocs estimate: 0
  --------------
  minimum time: 12.185 ns (0.00% GC)
  median time: 12.294 ns (0.00% GC)
  mean time: 12.435 ns (0.00% GC)
  maximum time: 33.543 ns (0.00% GC)
  --------------
  samples: 10000
  evals/sample: 998

julia> @benchmark isfruit2(x2)
BenchmarkTools.Trial:
  memory estimate: 0 bytes
  allocs estimate: 0
  --------------
  minimum time: 3.576 ns (0.00% GC)
  median time: 3.588 ns (0.00% GC)
  mean time: 3.606 ns (0.00% GC)
  maximum time: 14.649 ns (0.00% GC)
  --------------
  samples: 10000
  evals/sample: 1000

```

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [September 19, 2018, 2:43pm UTC](https://discourse.julialang.org/t/should-i-use-parametric-types-with-parameters-of-type-symbol-or-not/15178/2 "2018-09-19T14:43:38Z")

</div>

I prefer version 2. Unless there are strong reasons to include something in the type don’t do it. Just one simple argument; maybe you want to store `Food` in a container, like a vector. With version 2 you can have the vector concretely typed, whereas with version 1 you need it abstractly typed.

There are some sections in the manual about “value types” that you might find useful:  
[https://docs.julialang.org/en/v1/manual/performance-tips/#Types-with-values-as-parameters-1](https://docs.julialang.org/en/v1/manual/performance-tips/#Types-with-values-as-parameters-1)  
[https://docs.julialang.org/en/v1/manual/performance-tips/#The-dangers-of-abusing-multiple-dispatch-(aka,-more-on-types-with-values-as-parameters)-1](https://docs.julialang.org/en/v1/manual/performance-tips/#The-dangers-of-abusing-multiple-dispatch-(aka,-more-on-types-with-values-as-parameters)-1)

---

<div class="post-metadata">

**Author:** ![jbrea](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jbrea/32/3879_2.png) [@jbrea](https://discourse.julialang.org/u/jbrea)\
**Post date:** [September 19, 2018, 2:52pm UTC](https://discourse.julialang.org/t/should-i-use-parametric-types-with-parameters-of-type-symbol-or-not/15178/3 "2018-09-19T14:52:03Z")

</div>

Thanks!
