www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 7135] New: [tdpl] Multiple delegate-related issues (literal syntax, system deduction)

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7135

           Summary: [tdpl] Multiple delegate-related issues (literal
                    syntax,  system deduction)
           Product: D
           Version: D2
          Platform: Other
        OS/Version: Mac OS X
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: andrei metalanguage.com



21:08:50 PST ---
This is a copy of a failing TDPL example. First, the compiler doesn't accept
the delegate literal syntax unless it includes the keyword "delegate". Fixing
that somehow makes the compiler decide the literal is  system and refuses
binding it.

module test;// Context begin
#line 1369 "0900-operators.tex"
import std.variant;

alias Variant delegate(Dynamic self, Variant[] args...) DynMethod;
// Context end
// Context begin
#line 1383 "0900-operators.tex"
class Dynamic {
   private DynMethod[string] methods;
   void addMethod(string name, DynMethod m) {
      methods[name] = m;
   }
   void removeMethod(string name) {
      methods.remove(name);
   }
   // Dispatch dynamically on method
   Variant call(string methodName, Variant[] args...) {
      return methods[methodName](this, args);
   }
   // Provide syntactic sugar with opDispatch
   Variant opDispatch(string m, Args)(Args args...) {
      Variant[] packedArgs = new Variant[args.length];
      foreach (i, arg; args) {
         packedArgs[i] = Variant(arg);
      }
      return call(m, args);
   }
}
// Context end
#line 1409 "0900-operators.tex"
unittest {
  import std.stdio;
  auto obj = new Dynamic;
  obj.addMethod("sayHello",
      delegate Variant(Dynamic, Variant[]) {
        writeln("Hello, world!");
        return Variant();
     });
  obj.sayHello();  // Prints "Hello, world!"
}

void main(){}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 18 2011
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7135




This is not the delegate literal type deduction problem.
It is a trivial mismatching of delegate types.

This is the reduced code to explain the problem.
----
struct Variant {}
class Dynamic {}
alias Variant delegate(Dynamic self, Variant[] args...) DynMethod;
void main()
{
    DynMethod dg = delegate Variant(Dynamic, Variant[]) {
        return Variant();
    };
}

Output:
----
test.d(6): Error: cannot implicitly convert expression (__dgliteral1) of type
Variant delegate(Dynamic _param_0, Variant[] _param_1) pure nthrow  safe to
Variant delegate(Dynamic self, Variant[] args...)

DynMethod has typesafe variadic parameter, but literal doesn't have.
So this is a bug of TDPL sample code, not compiler's.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 30 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7135




00:40:00 PST ---

 This is not the delegate literal type deduction problem.
 It is a trivial mismatching of delegate types.
 
 This is the reduced code to explain the problem.
 ----
 struct Variant {}
 class Dynamic {}
 alias Variant delegate(Dynamic self, Variant[] args...) DynMethod;
 void main()
 {
     DynMethod dg = delegate Variant(Dynamic, Variant[]) {
         return Variant();
     };
 }
 
 Output:
 ----
 test.d(6): Error: cannot implicitly convert expression (__dgliteral1) of type
 Variant delegate(Dynamic _param_0, Variant[] _param_1) pure nthrow  safe to
 Variant delegate(Dynamic self, Variant[] args...)
 
 DynMethod has typesafe variadic parameter, but literal doesn't have.
 So this is a bug of TDPL sample code, not compiler's.
I think (and perhaps I'm wrong) that the signature with ... and the one without must be equivalent. The ... makes a difference only in the call syntax, but in fact still passes an array. (Note that the variadics ending with "T[] param..." are not unsafe C-style variadics.) Please advise - thanks! -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 31 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7135





 I think (and perhaps I'm wrong) that the signature with ... and the one without
 must be equivalent. The ... makes a difference only in the call syntax, but in
 fact still passes an array. (Note that the variadics ending with "T[] param..."
 are not unsafe C-style variadics.) Please advise - thanks!
Hmm, current compiler always raise an error against the difference of variadic argument kind (non-variarics vs typesafe-variadics vs C-style variadics). But, from http://d-programming-language.org/abi.html
 The variadic part is converted to a dynamic array and the rest is the same as
for non-variadic functions.
So, in ABI layer, (..., T[]) and (..., T[]...) might be same... -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 31 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7135


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |clugdbug yahoo.com.au





 I think (and perhaps I'm wrong) that the signature with ... and the one without
 must be equivalent. The ... makes a difference only in the call syntax, but in
 fact still passes an array. (Note that the variadics ending with "T[] param..."
 are not unsafe C-style variadics.) Please advise - thanks!
Hmm, current compiler always raise an error against the difference of variadic argument kind (non-variarics vs typesafe-variadics vs C-style variadics). But, from http://d-programming-language.org/abi.html
 The variadic part is converted to a dynamic array and the rest is the same as
for non-variadic functions.
So, in ABI layer, (..., T[]) and (..., T[]...) might be same...
I don't think so. One difference is visible in declaration.html (there may be other). It says: "An implementation may construct the object or array instance on the stack. Therefore, it is an error to refer to that instance after the variadic function has returned: int[] test(int[] a ...) { return a; // error, array contents invalid after return } " So, it would be legal to call the delegate with the Variant[]... stored on the stack. But it would fail. It might be OK to assign a (Variant[]...) function to a (Variant[]) delegate, but I'm pretty sure the other direction doesn't work. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 31 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7135


timon.gehr gmx.ch changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |timon.gehr gmx.ch






 I think (and perhaps I'm wrong) that the signature with ... and the one without
 must be equivalent. The ... makes a difference only in the call syntax, but in
 fact still passes an array. (Note that the variadics ending with "T[] param..."
 are not unsafe C-style variadics.) Please advise - thanks!
Hmm, current compiler always raise an error against the difference of variadic argument kind (non-variarics vs typesafe-variadics vs C-style variadics). But, from http://d-programming-language.org/abi.html
 The variadic part is converted to a dynamic array and the rest is the same as
for non-variadic functions.
So, in ABI layer, (..., T[]) and (..., T[]...) might be same...
I don't think so. One difference is visible in declaration.html (there may be other). It says: "An implementation may construct the object or array instance on the stack. Therefore, it is an error to refer to that instance after the variadic function has returned: int[] test(int[] a ...) { return a; // error, array contents invalid after return } " So, it would be legal to call the delegate with the Variant[]... stored on the stack. But it would fail. It might be OK to assign a (Variant[]...) function to a (Variant[]) delegate, but I'm pretty sure the other direction doesn't work.
It should be OK to assign (scope Variant[]) to (Variant[]...). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 31 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7135


Andrei Alexandrescu <andrei metalanguage.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |INVALID



08:43:40 PST ---
OK, it looks like this is safe to close now. I compiled a slightly modified
version. There was a bug elsewhere, the line

   Variant opDispatch(string m, Args)(Args args...) {

should be

   Variant opDispatch(string m, Args...)(Args args) {

Also, the signature of the delegate should contain "...", i.e. replace

      delegate Variant(Dynamic, Variant[]) {

with

      delegate Variant(Dynamic, Variant[]...) {

The working code is:

module test;// Context begin
#line 1369 "0900-operators.tex"
import std.variant;

alias Variant delegate(Dynamic self, Variant[] args...) DynMethod;
// Context end
// Context begin
#line 1383 "0900-operators.tex"
class Dynamic {
   private DynMethod[string] methods;
   void addMethod(string name, DynMethod m) {
      methods[name] = m;
   }
   void removeMethod(string name) {
      methods.remove(name);
   }
   // Dispatch dynamically on method
   Variant call(string methodName, Variant[] args...) {
      return methods[methodName](this, args);
   }
   // Provide syntactic sugar with opDispatch
   Variant opDispatch(string m, Args...)(Args args) {
      Variant[] packedArgs = new Variant[args.length];
      foreach (i, arg; args) {
         packedArgs[i] = Variant(arg);
      }
      return call(m, args);
   }
}
// Context end
#line 1409 "0900-operators.tex"
unittest {
  import std.stdio;
  auto obj = new Dynamic;
  obj.addMethod("sayHello",
      delegate Variant(Dynamic, Variant[]...) {
        writeln("Hello, world!");
        return Variant();
     });
  obj.sayHello();  // Prints "Hello, world!"
}

void main(){}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 31 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7135


Andrei Alexandrescu <andrei metalanguage.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|INVALID                     |



10:32:43 PST ---
One more thing - the example in the book reads:

  obj.addMethod("sayHello",
      Variant(Dynamic, Variant[]...) {
        writeln("Hello, world!");
        return Variant();
     });

That doesn't work. The compilable version reads:

obj.addMethod("sayHello",
      delegate Variant(Dynamic, Variant[]...) {
        writeln("Hello, world!");
        return Variant();
     });

Can we arrange things such that the "delegate" or "function" keywords aren't
require in the literal definition?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 31 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7135





 One more thing - the example in the book reads:
 
   obj.addMethod("sayHello",
       Variant(Dynamic, Variant[]...) {
         writeln("Hello, world!");
         return Variant();
      });
 
 That doesn't work. The compilable version reads:
 
 obj.addMethod("sayHello",
       delegate Variant(Dynamic, Variant[]...) {
         writeln("Hello, world!");
         return Variant();
      });
 
 Can we arrange things such that the "delegate" or "function" keywords aren't
 require in the literal definition?
From past, omission of delegate keyword + specification of return type has been wrong syntax. So Variant(Dynamic, Varinat[]...) { ... } couldn't compile. And recent commit https://github.com/D-Programming-Language/dmd/commit/c50eb5f5726a65efa1224ff0f0fd60acbb6e3027 has been disallowed optional parameter names, because of parameter type inference. From these matters, current TDPL code never become valid. ---- Today, following literal notations has been allowed with current dmd. delegate Variant(Dynamic self, Variant[] args...) {...} delegate (Dynamic self, Variant[] args...) {...} (Dynamic self, Variant[] args...) {...} ---- Note: Unfortunately, current dmd does not support parameter type inference + type-safe variadisc like follows. //delegate (self, args...) {...} //(self, args...) {...} Because args could have three kind of infer targets. T[N] args... // T is the element type of args T[] args... // T is the element type of args T args... // T is class type, and args is translated to new T(args) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 01 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7135





 Note: Unfortunately, current dmd does not support parameter type inference +
 type-safe variadisc like follows.
 
 //delegate (self, args...) {...}
 //(self, args...) {...}
I've filed bug 7705 to allow such lambda syntax, and posted a pull request to fix it. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 13 2012
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7135


Kenji Hara <k.hara.pg gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|REOPENED                    |RESOLVED
         Resolution|                            |INVALID



---
I close this as resolved invalid.

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