www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - feature req: extend property syntax func calls to classes, interfaces,

reply Downs <default_357-line yahoo.de> writes:
It is my understanding that the current method of calling functions on arrays
was first introduced accidentally.
The largely positive reaction this change has received in the D community
warrants,
in my (admittedly nsh) opinion, a look at extending the same kind of syntax to
types other than arrays.
This proposal has two parts, the second of which builds upon the first.
1) to extend the property syntax to classes and interfaces, _maybe_ even arrays
and primitive types.
Such a change would allow one to write "interface barf { } void test(barf b) {
do stuff; } myBarf.test; "

Should this proposal be implemented, it would also become possible to
2) allow interfaces to contain actual methods, bringing them closer to abstract
classes.
I am not talking of Multiple Inheritance, as the resulting methods would not
reside in the vtable.
Instead, an interface of the form

  interface test { void MethodWithCode() { /* do stuff */ } }

would be equivalent to writing
  interface test { } void MethodWithCode(test hiddenref) { with (hiddenref) {
/* do stuff */ } }

with the exception of access to private class members. In that sense, the function would always be final. In the case of a class deriving from multiple interfaces which include the same method signature, this would not present an ambiguity, but a syntax error, as the following (currently working) example shows:
  interface foo { } interface bar { }
  class whee : foo, bar { }

  void test(foo fee) { } void test(bar bee) { }
  void main() { test(new whee); }

  test57.d:5: function test57.test called with argument types:
          (whee)
  matches both:
          test57.test(foo)
  and:
          test57.test(bar)

What do you think? -- downs
May 21 2007
next sibling parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
I get the shakes just thinking about how awesome this would be.

For reference, here's how you do something similar in C#3:

class test { void foo() { /* do stuff */ } }

Is the same as:

class test {}
void foo(test this) { /* do stuff */ }

I'm not 100% sure if I like how they require you to explicitly mark
methods as extensions of a particular type, but if it makes it easier to
implement for Walter, I can live with it :)

	-- Daniel

-- 
int getRandomNumber()
{
    return 4; // chosen by fair dice roll.
              // guaranteed to be random.
}

http://xkcd.com/

v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D
i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/
May 21 2007
parent reply Downs <default_357-line yahoo.de> writes:
Daniel Keep wrote:
 I get the shakes just thinking about how awesome this would be.
 
 For reference, here's how you do something similar in C#3:
 
 class test { void foo() { /* do stuff */ } }
 
 Is the same as:
 
 class test {}
 void foo(test this) { /* do stuff */ }
 
 I'm not 100% sure if I like how they require you to explicitly mark
 methods as extensions of a particular type, but if it makes it easier to
 implement for Walter, I can live with it :)
 
 	-- Daniel
 

For obvious reasons, non-final functions will still have to be actually _inside_ the class, if only to allow a valid vtable to be constructed. So "class test { } void foo(test this) { }" would actually be equivalent to "class test { *final* void foo() { } }". Hate to disappoint, but there you go ^^ -- downs
May 22 2007
parent Daniel Keep <daniel.keep.lists gmail.com> writes:
Downs wrote:
 Hate to disappoint, but there you go ^^

You forgot to end the sentence with a period, never mind the dubious nature of "^^". See, I can play the nitpicking game, too! :) -- Daniel -- int getRandomNumber() { return 4; // chosen by fair dice roll. // guaranteed to be random. } http://xkcd.com/ v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
May 22 2007
prev sibling next sibling parent reply "David B. Held" <dheld codelogicconsulting.com> writes:
Downs wrote:
 [...]
 1) to extend the property syntax to classes and interfaces, _maybe_ even 
 arrays and primitive types.
 Such a change would allow one to write "interface barf { } void 
 test(barf b) { do stuff; } myBarf.test; "

This is related to a proposal to allow both member and free function call syntax. That is: a.foo(); could also be called as: foo(a); The main problem with this feature is that it severely complicates the lookup rules, and Walter doesn't want D to end up in the morass of C++'s ADL and namespace hell. However, Scala has it, and generics really needs it (and Andrei strongly favors it), so there's a fighting chance that it will make it into the language.
 [...]
  >  interface test { void MethodWithCode() { /* do stuff */ } }
 
 would be equivalent to writing
 
  >  interface test { } void MethodWithCode(test hiddenref) { with 
 (hiddenref) { /* do stuff */ } }
 
 with the exception of access to private class members.
 In that sense, the function would always be final.
 [...]

I don't know that Walter will allow method bodies in interfaces, but if the free/member proposal goes through, you can achieve it by simply writing the second form to get the effect of the first. Since access scope is module-private, as long as the interface is in the same module, it will have access. Is that good enough? Dave
May 21 2007
parent Oskar Linde <oskar.lindeREM OVEgmail.com> writes:
Henning Hasemann skrev:
 On Mon, 21 May 2007 22:54:43 -0700
 "David B. Held" <dheld codelogicconsulting.com> wrote:
 
 Downs wrote:
 [...]
 1) to extend the property syntax to classes and interfaces, _maybe_ even 
 arrays and primitive types.
 Such a change would allow one to write "interface barf { } void 
 test(barf b) { do stuff; } myBarf.test; "

call syntax. That is: a.foo(); could also be called as: foo(a);

Maybe the Dylan language (http://www.opendylan.org) would be of interest here, where actually no such thing such class methods exists but only global multi-dispatched methods with the syntactic sugar described above.

I agree. D (as well as C++, and to a lesser extent Java and many other languages) fails horribly at providing simple and consistent rules for polymorphism. Instead, we have several different kinds of polymorphism, each with special and somewhat incompatible rules. There are at least four forms of polymorphism in D: 1) function/method argument overloading, 2) virtual method dispatch, 3) template function specialization (not yet polymorphic in DMD), 4) op_r- / op-overloading, and combinations of the above -- all with slightly different rules and behaviors. At least, D doesn't have the C++ "polymorphism by #include files". :) Techniques such as for example double dispatch is necessary only because the language isn't expressive enough. An illustration: Given: A a; B b; a.func(); // Run time polymorphism on a func(b); // Compile time polymorphism on b a.func(b); // Run time polymorphism on a and compile time on b There is no (good) reason a language shouldn't allow run time dispatch on for example both a and b for a.func(b) and func(a,b). IMHO, Dylan does it right. Remove member functions/methods altogether and unify all forms of polymorphism. I have no illusions about this ever happening in D though. ;) /Oskar
May 22 2007
prev sibling parent Henning Hasemann <hhasemann web.de> writes:
On Mon, 21 May 2007 22:54:43 -0700
"David B. Held" <dheld codelogicconsulting.com> wrote:

 Downs wrote:
 [...]
 1) to extend the property syntax to classes and interfaces, _maybe_ even 
 arrays and primitive types.
 Such a change would allow one to write "interface barf { } void 
 test(barf b) { do stuff; } myBarf.test; "

This is related to a proposal to allow both member and free function call syntax. That is: a.foo(); could also be called as: foo(a);

Maybe the Dylan language (http://www.opendylan.org) would be of interest here, where actually no such thing such class methods exists but only global multi-dispatched methods with the syntactic sugar described above. Of cause that are totally different semantics but maybe one or an other thing of dylan design/implementation is interesting for D. Henning -- GPG Public Key: http://keyserver.veridis.com:11371/search?q=0x41911851 Fingerprint: 344F 4072 F038 BB9E B35D E6AB DDD6 D36D 4191 1851
May 21 2007