Le jeudi 10 mars 2016 à 12:40 -0800, ben a écrit :
> Thanks Milan, interesting to see others have wondered the same thing
> I did. Note that you can define dice=Dice() and
> encoding_utf8=Encoding{UTF8}() once and for all to avoid the
> parentheses (as Jeffrey points out).
Yes, but then we have three redundant ways of passing the information:
Dice, Dice(), and dice. :-)


> > 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/9ddb5067a12
> > 3da2fa46bfcdbdf6b3d3aecf9af4f/src/encodings.jl#L8 
> > 2: https://github.com/nalimilan/StringEncodings.jl/blob/9ddb5067a12
> > 3da2 
> > 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-F
> > JD7c 
> > > > > > 
> > > > > > 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