Magnus Lie Hetland <mag...@hetland.org> wrote:
I'm building a function (or template or whatever, really) that is
related to map and minPos in std.algorithm. Basically, it's the standard
mathematical argmin, except that it also returns min. It looks something
like this:
auto minArg(alias fun, Range, T)(Range range, out T minVal) {
...
}
Already there may be issues -- the return type should be
ElementType(range) and T should be the return type of fun ... but it
works. (Suggestions on these issues are welcome, but that's not really
the main point here.)
ElementType!Range minArg( alias fun, Range )( Range range, out
ReturnType!fun ) {
...
}
Might I also ask why you use an out parameter instead of a tuple return?
The thing is, because I'm also returning the actual value, I'd rather
not use the strategy of std.algorithm.minPos, which asks you to use an
inverted function to get maxPos; instead, I'd like an explicit maxArg
function. My idea was to have a common, more general optArg, which took
an operator ("<" or ">") as a compile-time argument. Then I could do
something like
alias optArg!"<" minArg;
alias optArg!">" maxArg;
Then, at some *later* time, I might want to do something like:
alias maxArg!((v) {return dist(u,v);}) farthest;
D currently does not support template currying to any good degree.
However, there is at least one library out there that does that for you:
http://www.dsource.org/projects/dranges
In the file templates.d, there is the template CurryTemplate, which
rewrites a template to a set of nested templates. This would allow you
to partially instantiate a template, and add more parameters as you go.
I've been able to make either one of these two pieces of functionality
work with some twiddling and nesting (i.e., *either* instantiating
optArg into minArg/maxArg, *or* instantiating explicitly defined
minArg/maxArg into specialized functions) but combining them has so far
eluded me (unless I start fiddling with strinc constants and mixin(),
which seems excessively hacky for such a simple thing).
dranges' templates.CurryTemplate should take care of some of your problems.
Not sure if it will fix them all.
--
Simen