www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 1807] New: ENHANCEMENT: Let IFTI "see through" templates to simple aliases

reply d-bugmail puremagic.com writes:
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.


-- 
Jan 25 2008
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1807






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.


-- 
Feb 20 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1807


shro8822 vandals.uidaho.edu changed:

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






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');
}


-- 
Jul 02 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1807


schveiguy yahoo.com changed:

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





*** Bug 1653 has been marked as a duplicate of this bug. ***


-- 
Nov 14 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1807


Steven Schveighoffer <schveiguy yahoo.com> changed:

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



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: -------
Mar 09 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1807


timon.gehr gmx.ch changed:

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



*** 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: -------
Feb 17 2012
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1807


dawg dawgfoto.de changed:

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



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: -------
Feb 18 2012