www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Why doesn't symbol wheelbarrowing work with function templates?

reply "TommiT" <tommitissari hotmail.com> writes:
"symbol wheelbarrowing" = "making symbols in other module(s) 
local to the current module"
(described in TDPL at page 148)

The problem:
-----------

module a;

int foo(int)
{
     return 42;
}

int bar(T)(int)
{
     return 42;
}

-----------

module b;

int foo(char)
{
     return 3;
}

int bar(T)(char)
{
     return 3;
}

-----------

module main;

import std.stdio;

import a;
import b;

// Works for foo:
alias foo = a.foo;
alias foo = b.foo;

// ...but not for bar:
alias bar = a.bar;
alias bar = b.bar; // Error: [1]

void main()
{
     writeln(foo(int.init));  // 42
     writeln(foo(char.init)); // 3

     //writeln(bar!(int)(int.init));
     //writeln(bar!(char)(char.init));
}

1. alias main.bar conflicts with alias main.bar
Jun 13 2013
next sibling parent reply "Peter Alexander" <peter.alexander.au gmail.com> writes:
On Thursday, 13 June 2013 at 09:53:54 UTC, TommiT wrote:
 1. alias main.bar conflicts with alias main.bar
This is why: they conflict. If it worked, what would you expect bar!string() return?
Jun 13 2013
next sibling parent reply "Peter Alexander" <peter.alexander.au gmail.com> writes:
On Thursday, 13 June 2013 at 10:16:40 UTC, Peter Alexander wrote:
 On Thursday, 13 June 2013 at 09:53:54 UTC, TommiT wrote:
 1. alias main.bar conflicts with alias main.bar
This is why: they conflict. If it worked, what would you expect bar!string() return?
Oops, that's a bad example: bar has a parameter. Which bar would you expect this to alias: alias bar!string barstring;
Jun 13 2013
next sibling parent "TommiT" <tommitissari hotmail.com> writes:
On Thursday, 13 June 2013 at 10:19:17 UTC, Peter Alexander wrote:
 On Thursday, 13 June 2013 at 10:16:40 UTC, Peter Alexander 
 wrote:
 On Thursday, 13 June 2013 at 09:53:54 UTC, TommiT wrote:
 1. alias main.bar conflicts with alias main.bar
This is why: they conflict. If it worked, what would you expect bar!string() return?
Oops, that's a bad example: bar has a parameter. Which bar would you expect this to alias: alias bar!string barstring;
I'd expect that to be some kind of compile time error about the ambiguity of bar!string, given that both 'a' and 'b' are imported.
Jun 13 2013
prev sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Thursday, 13 June 2013 at 10:19:17 UTC, Peter Alexander wrote:
 On Thursday, 13 June 2013 at 10:16:40 UTC, Peter Alexander 
 wrote:
 On Thursday, 13 June 2013 at 09:53:54 UTC, TommiT wrote:
 1. alias main.bar conflicts with alias main.bar
This is why: they conflict. If it worked, what would you expect bar!string() return?
Oops, that's a bad example: bar has a parameter. Which bar would you expect this to alias: alias bar!string barstring;
It is ambiguous and you get an error.
Jun 13 2013
prev sibling parent "TommiT" <tommitissari hotmail.com> writes:
On Thursday, 13 June 2013 at 10:16:40 UTC, Peter Alexander wrote:
 On Thursday, 13 June 2013 at 09:53:54 UTC, TommiT wrote:
 1. alias main.bar conflicts with alias main.bar
This is why: they conflict. If it worked, what would you expect bar!string() return?
both bar templates take a regular argument as well as a template argument, so bar!string() would be an error saying something like "no template 'bar' matches the function call". But if you'd call bar!string(int.init), then I'd expect it to return 42, and with bar!string(char.init), I'd expect 3.
Jun 13 2013
prev sibling next sibling parent reply "TommiT" <tommitissari hotmail.com> writes:
Well, I guess wheelbarrowing works with templates similar to 
functions if the template arguments are specified:

Doesn't work:
------------
import a;
import b;

void main()
{
     // Ambiguity errors:
     writeln(bar!string(int.init));
     writeln(bar!string(char.init));
}

Works:
------
import a;
import b;

alias bar = a.bar!string;
alias bar = b.bar!string;

void main()
{
     writeln(bar(int.init));  // 43
     writeln(bar(char.init)); // 3
}

... but I just realized I'm not actually asking what I'm trying 
to ask here. So, let me rephrase my question:

Why is the following ambiguous?
-----------
module a;

int foo(T)() if (is(T == int))
{
     return 42;
}

-----------
module b;

int foo(T)() if (is(T == char))
{
     return 3;
}

-----------
module main;

import std.stdio;

import a;
import b;

void main()
{
     writeln(foo!int()); // Error: ambiguous template declaration
}
Jun 13 2013
parent "TommiT" <tommitissari hotmail.com> writes:
On Thursday, 13 June 2013 at 10:52:56 UTC, TommiT wrote:
 Why is the following ambiguous?
 -----------
 module a;

 int foo(T)() if (is(T == int))
 {
     return 42;
 }

 -----------
 module b;

 int foo(T)() if (is(T == char))
 {
     return 3;
 }

 -----------
 module main;

 import std.stdio;

 import a;
 import b;

 void main()
 {
     writeln(foo!int()); // Error: ambiguous template declaration
 }
The corresponding code in C++ works nicely: ------------------------------------------- // a.h #include <type_traits> template <typename T, typename std::enable_if< std::is_same<T, int>::value, int>::type = 0> int foo() { return 42; } ------------------- // b.h #include <type_traits> template <typename T, typename std::enable_if< std::is_same<T, char>::value, int>::type = 0> int foo() { return 3; } ------------------- // main.cpp #include <iostream> #include "a.h" #include "b.h" int main() { std::cout << foo<int>() << std::endl; // 42 std::cout << foo<char>() << std::endl; // 3 return 0; } I'm just wondering whether the fact that the above (quoted) code doesn't work in D is based on some fundamental difference in how D and C++ work, or if it's some kind of a defect in D which we could change and make the above D code work.
Jun 13 2013
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 06/13/2013 11:53 AM, TommiT wrote:
 "symbol wheelbarrowing" = "making symbols in other module(s) local to
 the current module"
 (described in TDPL at page 148)

 The problem:
 -----------

 ...

 1. alias main.bar conflicts with alias main.bar
Compiler bug.
Jun 13 2013
next sibling parent reply "TommiT" <tommitissari hotmail.com> writes:
On Friday, 14 June 2013 at 05:36:32 UTC, Timon Gehr wrote:
 On 06/13/2013 11:53 AM, TommiT wrote:
 "symbol wheelbarrowing" = "making symbols in other module(s) 
 local to
 the current module"
 (described in TDPL at page 148)

 The problem:
 -----------

 ...

 1. alias main.bar conflicts with alias main.bar
Compiler bug.
Would you also go as far as to say that you'd expect the following to be perfectly valid D code? --------- module a; void foo(T : int)() { } --------- module b; void foo(T : string)() { } --------- module main; import std.stdio; import a; import b; alias foo = a.foo; alias foo = b.foo; // [1] void main() { foo!int(); foo!string(); } --------- 1) Error: alias main.foo conflicts with alias main.foo
Jun 15 2013
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 06/15/2013 11:34 AM, TommiT wrote:
 On Friday, 14 June 2013 at 05:36:32 UTC, Timon Gehr wrote:
 On 06/13/2013 11:53 AM, TommiT wrote:
 "symbol wheelbarrowing" = "making symbols in other module(s) local to
 the current module"
 (described in TDPL at page 148)

 The problem:
 -----------

 ...

 1. alias main.bar conflicts with alias main.bar
Compiler bug.
Would you also go as far as to say that you'd expect the following to be perfectly valid D code? ...
Yes, sure.
Jun 15 2013
parent "TommiT" <tommitissari hotmail.com> writes:
On Saturday, 15 June 2013 at 21:38:57 UTC, Timon Gehr wrote:
 On 06/15/2013 11:34 AM, TommiT wrote:
 Would you also go as far as to say that you'd expect the 
 following to be
 perfectly valid D code?
 ...
Yes, sure.
I'll go ahead and file a bug report then if no-one tells me otherwise.
Jun 15 2013
prev sibling parent reply Kenji Hara <k.hara.pg gmail.com> writes:
2013/6/14 Timon Gehr <timon.gehr gmx.ch>

 On 06/13/2013 11:53 AM, TommiT wrote:

 "symbol wheelbarrowing" = "making symbols in other module(s) local to
 the current module"
 (described in TDPL at page 148)

 The problem:
 -----------

 ...


 1. alias main.bar conflicts with alias main.bar
Compiler bug.
Compiler fix: https://github.com/D-Programming-Language/dmd/pull/1660 Kenji Hara
Jun 16 2013
parent "TommiT" <tommitissari hotmail.com> writes:
On Monday, 17 June 2013 at 05:19:40 UTC, Kenji Hara wrote:
 Compiler fix:
 https://github.com/D-Programming-Language/dmd/pull/1660

 Kenji Hara
Great to hear that this is just a compiler bug and that it's already being fixed.
Jun 16 2013