16 Aug 2012 00:30
Why aren't multiple implicit argument lists allowed?
Ben Wing <ben <at> benwing.com>
2012-08-15 22:30:40 GMT
2012-08-15 22:30:40 GMT
I have created an argument-parsing library that I use in a number of projects. The current definition of the method to specify an option with an associated value is as follows:
def option[T](
name1: String, name2: String = null, name3: String = null,
name4: String = null, name5: String = null, name6: String = null,
name7: String = null, name8: String = null, name9: String = null,
default: T = null.asInstanceOf[T],
metavar: String = null,
choices: Seq[T] = null,
help: String = "")
(implicit convert: (String, String, ArgParser) => T, m: Manifest[T]) = {
optionSeq[T](nonNullVals(name1, name2, name3, name4, name5, name6,
name7, name8, name9),
metavar = metavar, default = default, choices = choices,
help = help)(convert, m)
}
The first 9 arguments look a bit strange but the purpose is to allow a declaration like this:
var k_best =
ap.option[Int]("k-best", "k", "kb",
default = 10,
help = """Value of K for use in the mean-shift algorithm
(see '--coord-strategy'). For this value of K, we choose the K best cells
and then apply the mean-shift algorithm to the central points of those cells.
Default '%default'.""")
I.e. I can use either --k-best, -k or --kb as aliases for the same argument.
This works, but in practice I **really** want to declare it like this:
def option[T](
name1: String, name2: String = null, name3: String = null,
name4: String = null, name5: String = null, name6: String = null,
name7: String = null, name8: String = null, name9: String = null,
default: T = null.asInstanceOf[T],
metavar: String = null,
choices: Seq[T] = null,
help: String = "")
(implicit convert: (String, String, ArgParser) => T)
(implicit m: Manifest[T]) = {
optionSeq[T](nonNullVals(name1, name2, name3, name4, name5, name6,
name7, name8, name9),
metavar = metavar, default = default, choices = choices,
help = help)(convert, m)
}
i.e. with two implicit argument lists.
This way the user can optionally provide their own conversion routine without having to muck around with explicitly supplying the manifest or other similar things that may be required internally but which aren't for end-user consumption. The alternative of requiring the user to explicitly supply the manifest is ugly, esp. since the manifest itself is more or less a hack required to work around a Java bug, which in an ideal world shouldn't need to be exposed at all.
Why aren't multiple implicit argument lists allowed? From a theoretical perspective there's little difference between curried and non-curried arguments, but I don't see any practical way to work around this problem -- the manifest cannot be retrieved inside of option() using manifest[T], because T has already been erased by then.
ben
RSS Feed