www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Unified function call syntax

reply Frank Benoit <keinfarbton googlemail.com> writes:
This feature is planned for D2 and is currently available for array types.

If a global function exists like this:

bool equals(char[] a, char[] b){
  return a == b;
}

It is possible to use it like this:
char[] str1 = ...;
char[] str2 = ...;

str1.equals( str2 ); // compiles OK

But if this is used from within a class that also has a method with the
name "equals" the syntax above does not work any more:

class A {
  bool equals( Object o ){ ... }
  void foo (){
    bool res = str1.equals(str2); // compile error
      // equals(Object) does not
      // match parameter types (char[],char[])

    bool res2 = .equals(str1,str2); // compile OK
  }
}

Is this a bug or feature?

Will that syntax work with the planned unified function call syntax in D2?
Sep 05 2008
next sibling parent reply "Manfred_Nowak" <svv1999 hotmail.com> writes:
Frank Benoit wrote:

 Is this a bug or feature?
It should be a feature. One should be able to introduce the global `equal' by an alias within the body of the class: alias .equal equal; -manfred -- If life is going to exist in this Universe, then the one thing it cannot afford to have is a sense of proportion. (Douglas Adams)
Sep 05 2008
parent reply Sergey Gromov <snake.scaly gmail.com> writes:
Manfred_Nowak <svv1999 hotmail.com> wrote:
 Frank Benoit wrote:
 Is this a bug or feature?
It should be a feature. One should be able to introduce the global `equal' by an alias within the body of the class: alias .equal equal;
I think it should be a bug. When defining bool equals(char[] a, char[] b) {...} you essentially define (semantically) class char[] { bool equals(char[] b) {...} } Therefore calling A.equals() instead of char[].equals() is not correct. Generally speaking, for any given expression, expr.method(), the unified function call mechanism should only consider methods accessible from typeof(expr) context, not from current scope.
Sep 07 2008
next sibling parent Frank Benoit <keinfarbton googlemail.com> writes:
Sergey Gromov schrieb:
 Manfred_Nowak <svv1999 hotmail.com> wrote:
 Frank Benoit wrote:
 Is this a bug or feature?
It should be a feature. One should be able to introduce the global `equal' by an alias within the body of the class: alias .equal equal;
I think it should be a bug. When defining bool equals(char[] a, char[] b) {...} you essentially define (semantically) class char[] { bool equals(char[] b) {...} } Therefore calling A.equals() instead of char[].equals() is not correct. Generally speaking, for any given expression, expr.method(), the unified function call mechanism should only consider methods accessible from typeof(expr) context, not from current scope.
http://d.puremagic.com/issues/show_bug.cgi?id=2343
Sep 07 2008
prev sibling parent reply "Manfred_Nowak" <svv1999 hotmail.com> writes:
Sergey Gromov wrote:

 you essentially define (semantically)
 
      class char[] {
           bool equals(char[] b) {...}
      }
But then one semantically inherets that class---and therefore should be able to override/overload the inhereted methods, but you deny this. Why? -manfred -- If life is going to exist in this Universe, then the one thing it cannot afford to have is a sense of proportion. (Douglas Adams)
Sep 07 2008
parent reply Sergey Gromov <snake.scaly gmail.com> writes:
Manfred_Nowak <svv1999 hotmail.com> wrote:
 Sergey Gromov wrote:
 
 you essentially define (semantically)
 
      class char[] {
           bool equals(char[] b) {...}
      }
But then one semantically inherets that class---and therefore should be able to override/overload the inhereted methods, but you deny this. Why?
You cannot derive from an array. When you define class A { bool equals(Object o) {...} } you define a method, A.equals(), which cannot be called for an object of char[] class. Of course not everything is that nice. Consider bool equals(char[] a, char[] b) {...} class A { bool equals(char[] a, char[] b) {...} bool foo() { char[] x, y; bool r1 = equals(x, y); // I expect A.equals() to be called bool r2 = x.equals(y); // I expect .equals() to be called } } Here syntax dictates different expectations for something which semantically must be the same. So I personally put this 'unified function call' feature in the same basket with property call syntax: a 'sugar' which brings more ambiguity to the language than it actually helps rapid development.
Sep 08 2008
next sibling parent reply "Denis Koroskin" <2korden gmail.com> writes:
On Mon, 08 Sep 2008 11:11:30 +0400, Sergey Gromov <snake.scaly gmail.com>  
wrote:

 Manfred_Nowak <svv1999 hotmail.com> wrote:
 Sergey Gromov wrote:

 you essentially define (semantically)

      class char[] {
           bool equals(char[] b) {...}
      }
But then one semantically inherets that class---and therefore should be able to override/overload the inhereted methods, but you deny this. Why?
You cannot derive from an array. When you define class A { bool equals(Object o) {...} } you define a method, A.equals(), which cannot be called for an object of char[] class. Of course not everything is that nice. Consider bool equals(char[] a, char[] b) {...} class A { bool equals(char[] a, char[] b) {...} bool foo() { char[] x, y; bool r1 = equals(x, y); // I expect A.equals() to be called bool r2 = x.equals(y); // I expect .equals() to be called } } Here syntax dictates different expectations for something which semantically must be the same. So I personally put this 'unified function call' feature in the same basket with property call syntax: a 'sugar' which brings more ambiguity to the language than it actually helps rapid development.
There is not that much of an ambiguity. First of all, member functions can not be used as Unified Function Call, only free ones. That's why your example is perfectly valid, I think that everyone expect the same behaviour. It's just a compiler who is doing things wrong (and bugs are already reported). Second, I suggest marking functions to be used as a UFC or their first argument with something. Examples: bool equal(char[] this, char[] other) // note that you can't normally use `this' as an argument in functions. I like this one { return this[] == other[]; } or bool equal(this char[] first, char[] second) // that's the approach used { return first[] == second[]; } so that other function won't be misused as in the following example: void copy(void[] dst, void[] src) in { assert(dst.length >= src.length); } body { memcpy(dst.ptr, src.ptr, src.length); } int[] array1, array2; array1.copy(array2); // what is going to be copied and where?
Sep 08 2008
next sibling parent reply "Manfred_Nowak" <svv1999 hotmail.com> writes:
Denis Koroskin wrote:

 First of all, member functions can  
 not be used as Unified Function Call, only free ones.
What is the motivation for this rule? My question is motivated by the observation, that there might be no functions in D, that can be called "free". This is because every function belongs to a `module', which can be interpreted as the definition of a singleton `class'. -manfred -- If life is going to exist in this Universe, then the one thing it cannot afford to have is a sense of proportion. (Douglas Adams)
Sep 08 2008
parent "Denis Koroskin" <2korden gmail.com> writes:
On Mon, 08 Sep 2008 14:09:12 +0400, Manfred_Nowak <svv1999 hotmail.com>  
wrote:

 Denis Koroskin wrote:

 First of all, member functions can
 not be used as Unified Function Call, only free ones.
What is the motivation for this rule? My question is motivated by the observation, that there might be no functions in D, that can be called "free". This is because every function belongs to a `module', which can be interpreted as the definition of a singleton `class'. -manfred
Okay, I stand corrected. I just don't see member functions as those that can be used as UFC (except, static ones), but your example can change my mind. Inner functions should also be usable as UFC.
Sep 08 2008
prev sibling parent Sergey Gromov <snake.scaly gmail.com> writes:
Denis Koroskin <2korden gmail.com> wrote:
 On Mon, 08 Sep 2008 11:11:30 +0400, Sergey Gromov <snake.scaly gmail.com>  
 wrote:
 
 Manfred_Nowak <svv1999 hotmail.com> wrote:
 Sergey Gromov wrote:

 you essentially define (semantically)

      class char[] {
           bool equals(char[] b) {...}
      }
But then one semantically inherets that class---and therefore should be able to override/overload the inhereted methods, but you deny this. Why?
You cannot derive from an array. When you define class A { bool equals(Object o) {...} } you define a method, A.equals(), which cannot be called for an object of char[] class. Of course not everything is that nice. Consider bool equals(char[] a, char[] b) {...} class A { bool equals(char[] a, char[] b) {...} bool foo() { char[] x, y; bool r1 = equals(x, y); // I expect A.equals() to be called bool r2 = x.equals(y); // I expect .equals() to be called } } Here syntax dictates different expectations for something which semantically must be the same. So I personally put this 'unified function call' feature in the same basket with property call syntax: a 'sugar' which brings more ambiguity to the language than it actually helps rapid development.
There is not that much of an ambiguity. First of all, member functions can not be used as Unified Function Call, only free ones. That's why your example is perfectly valid, I think that everyone expect the same behaviour. It's just a compiler who is doing things wrong (and bugs are already reported).
What is a 'free' function? How do you define a search rule? Consider: bool equals(char[] a, char[] b) {...} class A { bool equals(char[] a, char[] b) {...} bool foo() { bool equals(char[] a, char[] b) {...} char[] x, y; bool r1 = equals(x, y); // calls local equals() bool r2 = x.equals(y); // should call local equals(), too } } Here x.equals(y) cannot be rewritten as .equals(x, y) because it will call global equals() instead of the local one. This means that for x.equals(y) only local and global functions must be considered but any methods should be ignored, despite the fact that they are perfectly accessible from the call scope. This requires inventing new scoping rules => not quite a 'syntax sugar' anymore.
Sep 08 2008
prev sibling parent "Manfred_Nowak" <svv1999 hotmail.com> writes:
Sergey Gromov wrote:

 Here syntax dictates different expectations for something which 
 semantically must be the same.
In fact the current implementation is consistent with my expectations, i.e. that both calls are semantically identical. Your expectation, that "syntax dictates different expectations" might be a pitfall you built yourself. -manfred -- If life is going to exist in this Universe, then the one thing it cannot afford to have is a sense of proportion. (Douglas Adams)
Sep 08 2008
prev sibling parent BLS <nanali nospam-wanadoo.fr> writes:
Frank Benoit schrieb:
 This feature is planned for D2 and is currently available for array types.
 
 If a global function exists like this:
 
 bool equals(char[] a, char[] b){
   return a == b;
 }
 
 It is possible to use it like this:
 char[] str1 = ...;
 char[] str2 = ...;
 
 str1.equals( str2 ); // compiles OK
 
 But if this is used from within a class that also has a method with the
 name "equals" the syntax above does not work any more:
 
 class A {
   bool equals( Object o ){ ... }
   void foo (){
     bool res = str1.equals(str2); // compile error
       // equals(Object) does not
       // match parameter types (char[],char[])
 
     bool res2 = .equals(str1,str2); // compile OK
   }
 }
 
 Is this a bug or feature?
 
 Will that syntax work with the planned unified function call syntax in D2?
 
 
bool res = str1.equals(str2); // compile error should become consequently str1..equals(str2); seams to be reasonable, bjoern
Sep 08 2008