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