Le jeudi 10 mars 2016 à 11:15 -0800, Jeffrey Sarnoff a écrit :
> 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.
Yet this doesn't address the question of which solution is the best in
the case of singleton types, for which the type and the instance carry
the same amount of information.

FWIW, I also had the same interrogation when creating a parametric
singleton type like this [1]:
immutable Encoding{enc} end

In the end, I chose to use instances rather than types since it makes
type signatures shorter and thus clearer for documentation. For
example, I find this [2]:
readstring(stream::IO, enc::Encoding)

much nicer to read than this:
readstring{enc}(stream::IO, ::Type{Encoding{enc}})

But this has a downside that one needs to write Encoding{:UTF8}()
instead of Encoding{:UTF8}, or Dice() instead of Dice. I find the
presence of parentheses quite annoying since it doesn't add anything.
(This isn't actually an issue for Encoding since I defined a non-
standard string literal enc"UTF8" as a shortcut. But for non-parametric 
types that issue is generally more visible.)


So these are my two cents, but I'd love to hear ideas from others. If
we find strong arguments in one direction or another, we could add them
to the manual.


Regards



1: 
https://github.com/nalimilan/StringEncodings.jl/blob/9ddb5067a123da2fa46bfcdbdf6b3d3aecf9af4f/src/encodings.jl#L8
2: https://github.com/nalimilan/StringEncodings.jl/blob/9ddb5067a123da2
fa46bfcdbdf6b3d3aecf9af4f/src/StringEncodings.jl#L393
> 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.
> 
> 
> > Thanks. I understand that, but is there a specific reason why
> > doing:
> > 
> > takedecision{H <: Dice}(::Type{H})
> > 
> > is bad / not as good?
> > 
> > > 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
> > > 
> > > 
> > > > 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