Thread overview
Alias template parameter to a private function
Jun 24, 2017
Sebastien Alaiwan
Jun 29, 2017
Sebastien Alaiwan
Jun 29, 2017
Ali Çehreli
Jun 29, 2017
Sebastien Alaiwan
June 24, 2017
Hi,

I'm trying to call std.algorithm.iteration.filter with a private function as a predicate.
Here's a reduced example code:

// yo.d
import std.algorithm;

void moduleEntryPoint()
{
  privateFunction1();
  privateFunction2();
}

private:

void privateFunction1()
{
  auto array = [0, 1, 2, 3, 4, 5];
  auto result = filter!isValid(array); // error: 'isValid' is private
}

void privateFunction2()
{
  auto array = [0, 1, 2, 3, 4, 5];
  auto result = filter!isValid(array); // error: 'isValid' is private
}

bool isValid(int i)
{
  return i % 2 == 0;
}

Here's the compiler output:

/usr/include/dmd/phobos/std/algorithm/iteration.d(1132): Error: function yo.isValid is not accessible from module iteration
yo.d(14): Error: template instance std.algorithm.iteration.filter!(isValid).filter!(int[]) error instantiating

This seems like the compiler, when instanciating the calls to 'filter', is resolving 'isValid' from std.algorithm.iteration scope (however, this isn't actually the case, see below).
I was expecting this identifier to be resolved from yo.d, where we have access to the private functions.

Surprisingly, the following works:

void privateFunction2()
{
  static bool isValid(int i)
  {
    return i % 2 == 0;
  }

  auto array = [0, 1, 2, 3, 4, 5];
  auto result = filter!isValid(array); // error: 'isValid' is private
}

This makes the instanciation of 'filter' "see" 'isValid', however, now, the other privateFunctions can't use it.

Am I missing something here?
Thanks!

June 29, 2017
up please!
June 29, 2017
On 06/24/2017 02:04 AM, Sebastien Alaiwan wrote:

> private:
>
> void privateFunction1()
> {
>   auto array = [0, 1, 2, 3, 4, 5];
>   auto result = filter!isValid(array); // error: 'isValid' is private
> }

> bool isValid(int i)
> {
>   return i % 2 == 0;
> }

A workaround is to use a lambda:

  filter!(a => isValid(a))(array)

Such limitations are pretty annoying. There were a number of similar issues in recent dmd releases. Please file a bug if it's not already there:

  https://issues.dlang.org/

Ali

June 29, 2017
On Thursday, 29 June 2017 at 20:21:13 UTC, Ali Çehreli wrote:
> A workaround is to use a lambda:
>
>   filter!(a => isValid(a))(array)

Thanks! Nice trick, this is definitely going into my company's codebase :-)

> Such limitations are pretty annoying. There were a number of similar issues in recent dmd releases. Please file a bug if it's not already there:

Thanks, will do!