Thread overview
[Issue 1807] New: ENHANCEMENT: Let IFTI "see through" templates to simple aliases
Jan 26, 2008
d-bugmail
Feb 21, 2008
d-bugmail
Jul 02, 2008
d-bugmail
Nov 14, 2008
d-bugmail
Feb 17, 2012
timon.gehr@gmx.ch
Feb 18, 2012
dawg@dawgfoto.de
January 26, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1807

           Summary: ENHANCEMENT: Let IFTI "see through" templates to simple
                    aliases
           Product: D
           Version: 2.010
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla@digitalmars.com
        ReportedBy: webmaster@villagersonline.com


I was writing a program recently where I was passing around deeply nested delegates, so I wrote a template alias to represent the type.  (Without it, it was nearly impossible to use the correct amount of nested delegates.)

My program uses IFTI heavily, and what I found out was that as soon as I implemented the template aliasing, my IFTI didn't work anymore.

After a bit of thinking, I realized that, in general, IFTI can't dive into templates and speculate about what they might be, since each template instance could represent an infinite number of types.  It's an impossible search.  But in my special case, the search is linear, and can easily be accomplished.

My request: when a template function uses some type-expression which includes an instantiation of a template, and there is only one version of that template, and that template just has a single alias (or typedef, maybe?), then replace the template reference with the alias, and use that to compute IFTI.

EXAMPLE CODE:

template wrap(T)
{
  alias void delegate(T*) wrap;
}

alias void delegate(int*) wrap_int;

void Foo1(T)(void delegate(T*)) {}
void Foo2(T)(wrap!(T))          {}
void Foo3   (wrap_int)          {}

void delegate(T*) Bar1(T)( T  arg) { return null; }
wrap!(T)          Bar2(T)( T  arg) { return null; }
wrap_int          Bar3   (int arg) { return null; }

void main()
{
  int i;
  Foo1(Bar1(i));
  Foo1(Bar2(i));
  Foo1(Bar3(i));
// these three have IFTI failures because the only way
// figure out the parameter T for template function Foo2
// is to realize that wrap!(T) is a template alias, and
// it seems that DMD doesn't realize that.
//
//  Foo2(Bar1(i));
//  Foo2(Bar2(i));
//  Foo2(Bar3(i));
  Foo3(Bar1(i));
  Foo3(Bar2(i));
  Foo3(Bar3(i));
}

END EXAMPLE CODE

My analysis: IFTI works quite well with delegates (see Foo1).  IFTI also works
quite well with aliases (DMD looks right through the alias, see Foo3).  IFTI
doesn't work when the alias is inside a template.  What I'm suggesting is that
DMD should look at the Foo2 function and realize that the type
  wrap!(T)
while a template expression, will always be equivalent to
  void delegate(T*)
due to the fact that:
  1) There is only declartion of the template
  2) The declaration only includes a single alias

Once DMD knows that Foo2 is actually
    void Foo2(T)(void delegate(T*)) {}
IFTI should work quite nicely.

Also note, BTW, that this transformation should happen on any number of expressions in the function declaration, it should recurse, and it should be OK if the template parameter is a tuple.  See my background code below.



BACKGROUND - A SNIPPET OF THE ACTUAL CODE WHERE I FOUND THIS PROBLEM:

template RegisterFor_mailbox(TPL...)
{
  alias void delegate(TPL) RegisterFor_mailbox;
}

template RegisterFor_retval(TPL...)
{
  alias void delegate(RegisterFor_mailbox!(TPL)) RegisterFor_retval;
}

RegisterFor_retval!()
RegisterFor_char()
                (Registry reg,char c)
{
  ...
}

// this function supports chaining of registrations, in this case chaining an // IDENTIFIER to a pre-existing chain

RegisterFor_retval!(IDENTIFIER,TPL)
RegisterFor_IDENTIFIER(TPL...)
                      (Registry reg,
                       RegisterFor_retval!(TPL) chain)
{
  ...
}

void main()
{
  Registry reg = <whatever>;

  // as explained below, I currently have to explicitly instantiate these
  // function calls.  I'd like IFTI to do it for me, as I show here:
  RegisterFor_char      (reg, '{',  // my code also has chain-to-char
  RegisterFor_IDENTIFIER(reg,
  RegisterFor_IDENTIFIER(reg,
  RegisterFor_char      (reg, '}'))))
  (delegate void(IDENTIFIER id1,IDENTIFIER id2)
   {
     <mailbox code resides here>
   });
}

// in a chain, the deepest element (the last in the chain) should be easy to // IFTI; the return value from that is one of the args for the next-deepest, // and if IFTI worked the way I hoped, then that would allow us to IFTI the // next-deepest, and so on up the chain.

END BACKGROUND CODE

You can see from the above that if I had to replace all of my nice
RegisterFor_retval!(...) expressions with the actual delegate code, the
complexity shoots through the roof.  (I have even worse places in my code.  In
one place, I have a paramter to a function which is
function-pointer-taking-delegate-argument-returning-delegate-nested-3-deep-deepest-delegate-taking-pointer-to-struct-argument.)

It's very hard to live without these aliases.  So right now, I am forcing the calling code specifically choose the template parameters.  That's ugly.


-- 

February 21, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1807





------- Comment #1 from bugzilla@digitalmars.com  2008-02-21 01:02 -------
This enhancement request is a special case of issue 1454, which is marked as invalid. I agree with Russ that the general case is intractable, but this special case might be doable, so it's a good idea for an enhancement request.


-- 

July 02, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1807


shro8822@vandals.uidaho.edu changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |shro8822@vandals.uidaho.edu




------- Comment #2 from shro8822@vandals.uidaho.edu  2008-07-02 16:10 -------

BUMP

Another cases where this would be handy

public template Foo(T: char) {alias Foo_dwc!(T) Foo; }
public template Foo(T: wchar) {alias Foo_dwc!(T) Foo; }
public template Foo(T: dchar) {alias Foo_dwc!(T) Foo; }

private void Foo_dwc(T)(T arg) { }

void main(char[][] args)
{
Foo('a');
}


-- 

November 14, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1807


schveiguy@yahoo.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |schveiguy@yahoo.com




------- Comment #3 from schveiguy@yahoo.com  2008-11-14 14:00 -------
*** Bug 1653 has been marked as a duplicate of this bug. ***


-- 

March 09, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=1807


Steven Schveighoffer <schveiguy@yahoo.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bearophile_hugs@eml.cc


--- Comment #4 from Steven Schveighoffer <schveiguy@yahoo.com> 2010-03-09 04:15:46 PST ---
*** Issue 3904 has been marked as a duplicate of this issue. ***

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 17, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=1807


timon.gehr@gmx.ch changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |kyfolee@gmail.com


--- Comment #5 from timon.gehr@gmx.ch 2012-02-17 14:20:38 PST ---
*** Issue 7529 has been marked as a duplicate of this issue. ***

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 18, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=1807


dawg@dawgfoto.de changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |dawg@dawgfoto.de


--- Comment #6 from dawg@dawgfoto.de 2012-02-18 09:40:40 PST ---
One issue with this is that treating certain kinds of templates different that others will make it very difficult to understand why matching might fail.

If we want to have alias templates to behave different than plain templates they should have a language construct that enforces the limitations and resembles struct templates.

alias(T) void delegate(T*) wrap;
expands to:
template wrap(T) { alias void delegate(T*) wrap; }

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------