Ranges and Algorithms -- Templates, Delegates, or Ranges?
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Tue Feb 22 06:11:22 PST 2011
On 2/22/11 5:15 AM, Mafi wrote:
> Am 22.02.2011 11:29, schrieb %u:
>> Having learned functional programming in Scheme a couple months ago, I
>> tried my hand at using map(), reduce(), and filter() in D:
>>
>> int addend = 5;
>> map(delegate int(int x) { return x + addend; }, iota(1, 5));
>>
>> but it didn't work. It turned out that map() actually took the mapper
>> as its _template_ argument, not as a function argument. Not too much of
>> a problem, it probably seemed to be...
>> except that it's a critical problem. It makes map(), reduce(),
>> filter(), etc. to become 10x less useful, because there's no way to
>> change
>> their behavior at runtime, depending on program's state.
>>
>
> I did never try and so I'm unsure but shouldn't you be able to give a
> delegate variable as template parameter.
> std.algorithms.map's parameter is an alias parameter so it should be
> able alias your variable and use it's runtime value.
> If it does not work this way it's a bug IMO.
>
> Mafi
>
Indeed. The solution to OP's problem is std.algorithm.map. Local
instantiation should take care of aliases that refer to local symbols,
so OP's original complaint about std.algorithm.map is invalid (albeit
for a subtle reason). The following code compiles as expected:
import std.algorithm, std.stdio;
auto fun(int[] a)
{
auto y = 3;
auto m = map!((x) { return x < y; })(a);
return m;
}
void main()
{
auto a = [ 1, 2, 3, 4, 5 ];
auto m = fun(a);
writeln(m);
}
Note how map's lambda refers to a symbol local to fun.
Local instantiation, invented by Walter, is a very innovative feature -
perhaps one of D's most innovative. When a template is instantiated with
a local alias (as e.g. map is inside fun) it is in fact instantiated
within the function, so it has access to its locals.
As this is a new feature and a rather subtle one, it has bugs and
limitations. In fact the function above has a bug, it prints:
[false, false, false, false, true]
although it should print
[true, true, false, false, false]
But I'm 100% convinced this is the way to go. I just submitted a bug
report reduced from the code above, see
http://d.puremagic.com/issues/show_bug.cgi?id=5641.
Andrei
More information about the Digitalmars-d
mailing list