Le mercredi 24 juin 2015 à 01:18 -0700, [email protected] a écrit : > Hi all, > > I've got an issue I don't really like in one of my modules, and I was > wondering the best thing (if anything) to do about it. > > The module if for dependent bootstraps, but the problem is more of a > project design issue. I have a type for each bootstrap method, e.g. > `StationaryBootstrap`, `MovingBlockBootstrap` e.t.c. and they are all > sub-types of an abstract `BootstrapMethod`. Then I have functions > that can be called over these different bootstrap method types and > multiple dispatch will make sure the appropriate code is called, e.g > `bootindices(::StationaryBootstrap)` or > `bootindices(::MovingBlockBootstrap)`. This all works nicely. > > I now want to define some keyword wrapper type functions in the > module for users who don't want to learn much about how the types > within the module work. For example, my wrapper might let the user > describe the bootstrap procedure they want with a string, eg > `bootindices(...; bootstrapmethod::ASCIIString="stationary")`. > > The keyword wrapper is called, and I have a variable > `bootstrapMethod` which is a string. I need to convert it into the > appropriate bootstrap method type so I can then call the appropriate > method via multiple dispatch. Currently I have one function that does > this and looks something like this: > > function boot_string_to_type(x::ASCIIString) > x == "stationary" && return(StationaryBootstrap()) > x == "movingBlock" && return(MovingBlock()) > ... > end > > The problem is that this function is not type-stable. > > Should I be worried? Does anyone have a better way of dealing with > this kind of issue? Maybe something involving symbols or expressions, > or anonymous functions etc? > > Note, the situation can sometimes get quite a bit more complicated > than this, with multiple key-word arguments, all of which need to be > combined into the constructor for the relevant type. I think the most Julian way to do this is to have users pass a type instead of a string. They would write bootindices{T<:BootstrapMethod}(...; method::Type{T}=StationaryBootstrap)
That's simpler for the user as passing a string (since autocompletion w ill work), you don't need to define boot_string_to_type(), and it's type-stable. This is the idiom used by fit() in StatsBase.jl (and GLM.jl) to choose which type of model should be estimated. Hope this helps PS: in the cases where you still want to pass a string as an argument, rather than a type, consider using symbols instead, as it is more efficient.
