D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 3772 - Extension methods
Summary: Extension methods
Status: RESOLVED WONTFIX
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: Other Linux
: P2 enhancement
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-02-05 06:20 UTC by Witold Baryluk
Modified: 2016-10-14 01:26 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Witold Baryluk 2010-02-05 06:20:17 UTC
Long time ago there was a idea to have extending (well this isn't best name) of the class implementations.

This is my proposition:

==========================
module m1;
class A {
   int x() { retutn 5 }
}

==========================
module m2;
import m1;
@extend(A)
float y(A a) { return a.x() * 11.1; }

@extend(A)
@property
float z(A a) { return a.y() + 22.1; }


module test;
import m1, m2;
A a = new A();
assert(a.y() == 55.5);
assert(a.z == 77.6);

==========================
Questoin remains if y(a) is valid function call.
This is not necasarly best way becuase it would be best if y, z method will have access to private fields of A. It also should be possible tu use this in them (this can be emulated using with:

@extend(A)
float y(A this) { with(this) { return x() * 11.1; } }



Actually this is similar to my suggested problem with array (and not only) methods.
I.e. a.find(b) is transleted to find(a, b).

It should be explicitly be written:
@extend(string)
int find(string a, string b) ....


Othere asspect is interference with the template functions. One can't easly have things like:

@extend(T)
int something(T)(T a) { return 42; }

becuase this method can extend all types. And this is problematic for two reasons:
 - conflicts of such widely applicable functions.
 - efficiency of searching for such functions. (but it shouldn't be actually so big problem if this information is cached for each type on first usage).

This also makes questionably if it should have such syntax, more appropriate will be nonredudant:

@extend_first_argument
int something(T)(T a)  { return 42; }


Other possiblity (AFAIK used in C#, but don't remember exactly, is to use this):

int something(this A a) { } 

or
int something(this A this) { }

Where first this is indicating that this is extending function.
Second this is just convinient name for usage inside of something(A) function (preferably with with, evetntually with(this) should be automatically put there).
Comment 1 Andrei Alexandrescu 2016-10-14 01:26:05 UTC
Please follow the DIP flow for such a proposal. Thanks!