An example from Base/float.jl that dispatches on the type itself (this is 
just one use of many reasonable ones):

## precision, as defined by the effective number of bits in the mantissa

precision(::Type{Float16}) = 11
precision(::Type{Float32}) = 24
precision(::Type{Float64}) = 53
precision{T<:AbstractFloat}(::T) = precision(T)


On Thursday, March 10, 2016 at 2:15:05 PM UTC-5, Jeffrey Sarnoff wrote:
>
> There are situations in which dispatching off of Type(s) is necessary. 
> Dispatching through Types by way of typed instances (realizations) is more 
> common, and the only way to go when you want to do something with the 
> fields' values of a typed instance.  Rather than look at the two as 
> better/worse, consider them two manners of expression that are available to 
> you.  Using whichever feels more natural and/or writes itself more simply 
> is always helpful.  If you are treating the dice and the coin as singleton 
> entities, then it makes sense to code them that way.  As a bonus, that can 
> simplify later elaborations and alterations that you may choose to make. 
>  If your dice and coin are conceptual abstractions that permeate all 
> possible realizations of dice-ness and coin-ness, then it makes sense to 
> operate on --and dispatch through-- their type-ness.
>
>
> On Thursday, March 10, 2016 at 1:42:56 PM UTC-5, ben wrote:
>>
>> Thanks. I understand that, but is there a specific reason why doing:
>>
>> takedecision{H <: Dice}(::Type{H})
>>
>> is bad / not as good?
>>
>> On Thursday, March 10, 2016 at 1:06:01 PM UTC-5, Jeffrey Sarnoff wrote:
>>>
>>> when you do
>>> immutable Dice end
>>> or
>>> type Dice end
>>> you create a singleton type -- there can be only one instance (or all 
>>> instances are that identical single instance).
>>>
>>> To realize a singleton type, call it:
>>> myDice = Dice(); myCoin = Coin()
>>>
>>> now, you can use 
>>> choose(x::Dice) = println("throw the dice")
>>> choose(myDice)
>>> throw the dice
>>>
>>>
>>> On Thursday, March 10, 2016 at 12:02:09 PM UTC-5, ben wrote:
>>>>
>>>> Hi everyone,
>>>>
>>>> One of the many cool things we can do in Julia is use multiple dispatch 
>>>> to avoid a "method" argument followed by a "if" construct sending to 
>>>> back-end functions. I sometimes get confused about which of the following 
>>>> two ways of achieving this is better:
>>>>
>>>> ~~~
>>>> immutable Dice end
>>>> immutable Coin end
>>>>
>>>> takedecision{H <: Dice}(::Type{H})=println("throw a dice")
>>>> takedecision{H <: Coin}(::Type{H})=println("flip a coin")
>>>> makedecision(::Dice)=println("throw a dice")
>>>> makedecision(::Coin)=println("flip a coin")
>>>>
>>>> takedecision(Dice)
>>>> takedecision(Coin)
>>>> makedecision(Dice())
>>>> makedecision(Coin())
>>>> ~~~
>>>>
>>>> If the method has "tuning parameters" (like the type of Dice or of 
>>>> Coin), the second way is much better, using inner fields 
>>>> `method.tuningparameter` and constructor `Method(tuningparameter)`. But if 
>>>> the method type is a pure "label" type without any additional content, 
>>>> both 
>>>> ways work. The first one is uglier in the source code but nicer for the 
>>>> user and may be more faithful to the concept (I want to make a decision by 
>>>> throwing a coin, not by throwing this particular coin). Indeed see the 
>>>> confusion caused by Gridded(Linear()) in this other topic:
>>>> https://groups.google.com/forum/#!topic/julia-users/0cV6v-FJD7c
>>>>
>>>> Am I missing something key in terms of the pros and cons of each of 
>>>> these two ways? Is there a principled good practice?
>>>>
>>>> Best
>>>>
>>>> Ben
>>>>
>>>>

Reply via email to