www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - "static" UFCS

reply Jacob Carlborg <doob me.com> writes:
UFCS can be used to emulate adding new members/instance methods to a 
class or struct:

class Foo
{
}

void bar (Foo foo, int x) {}

auto foo = new Foo;
foo.bar(3);

Is it possible, somehow, to emulate adding new _static_ methods to a 
class, something like this:

void fooBar (/*something*/, int x) {}

Making this possible:

Foo.fooBar(4);

-- 
/Jacob Carlborg
Jun 13 2012
next sibling parent reply Gor Gyolchanyan <gor.f.gyolchanyan gmail.com> writes:
On Thu, Jun 14, 2012 at 10:46 AM, Jacob Carlborg <doob me.com> wrote:
 UFCS can be used to emulate adding new members/instance methods to a class
 or struct:

 class Foo
 {
 }

 void bar (Foo foo, int x) {}

 auto foo = new Foo;
 foo.bar(3);

 Is it possible, somehow, to emulate adding new _static_ methods to a class,
 something like this:

 void fooBar (/*something*/, int x) {}

 Making this possible:

 Foo.fooBar(4);

 --
 /Jacob Carlborg

I'd expect it to look like this: void fooBar(Foo)(int x) {} -- Bye, Gor Gyolchanyan.
Jun 14 2012
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2012-06-14 12:25, Gor Gyolchanyan wrote:
 Yes, that does look bad. How about this?

 void fooBar(T : Foo)(int x) { }

I don't like that it's a template function, there's really no reason. It seems to just be a limitation in the syntax. -- /Jacob Carlborg
Jun 14 2012
parent Jacob Carlborg <doob me.com> writes:
On 2012-06-14 13:30, Gor Gyolchanyan wrote:

 It doesn't matter whether a function is a template or not. The only
 thing that matters is the number of instances it produces. A template
 function, which produces only one instance is equivalent to a
 non-template function. The function above can produce only one
 instance (unless overloaded).

Yeah, except when it's an instance method, which will make it non-virtual. In this case it's not though. -- /Jacob Carlborg
Jun 14 2012
prev sibling parent =?ISO-8859-15?Q?Alex_R=F8nne_Petersen?= <alex lycus.org> writes:
On 14-06-2012 11:52, Regan Heath wrote:
 On Thu, 14 Jun 2012 10:43:43 +0100, Gor Gyolchanyan
 <gor.f.gyolchanyan gmail.com> wrote:

 On Thu, Jun 14, 2012 at 10:46 AM, Jacob Carlborg <doob me.com> wrote:
 UFCS can be used to emulate adding new members/instance methods to a
 class
 or struct:

 class Foo
 {
 }

 void bar (Foo foo, int x) {}

 auto foo = new Foo;
 foo.bar(3);

 Is it possible, somehow, to emulate adding new _static_ methods to a
 class,
 something like this:

 void fooBar (/*something*/, int x) {}

 Making this possible:

 Foo.fooBar(4);

 --
 /Jacob Carlborg

I'd expect it to look like this: void fooBar(Foo)(int x) {}

That looks too much like a template function to me. What about: void fooBar(static Foo, int x) {}

static? Oh boy, here we go again ... ;)
 Note: no parameter name for the "static" Foo parameter (as it's not
 really a parameter - simply a placeholder to indicate it's UFCS).


 C# doesn't have static UFCS (called "extension methods" in C# parlance)
 tho some people have wanted it:
 http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/8ac0e6bf-c859-4cc4-919f-c80eedfccf63


 I guess the reason it doesn't exist is that there is no technical reason
 for it, all it gives you is a nicer syntax.

 You can get fairly close with a custom static class, static method
 taking an instance of the class you want to 'extend'.

 R

-- Alex Rnne Petersen alex lycus.org http://lycus.org
Jun 14 2012
prev sibling next sibling parent "Regan Heath" <regan netmail.co.nz> writes:
On Thu, 14 Jun 2012 10:43:43 +0100, Gor Gyolchanyan  
<gor.f.gyolchanyan gmail.com> wrote:

 On Thu, Jun 14, 2012 at 10:46 AM, Jacob Carlborg <doob me.com> wrote:
 UFCS can be used to emulate adding new members/instance methods to a  
 class
 or struct:

 class Foo
 {
 }

 void bar (Foo foo, int x) {}

 auto foo = new Foo;
 foo.bar(3);

 Is it possible, somehow, to emulate adding new _static_ methods to a  
 class,
 something like this:

 void fooBar (/*something*/, int x) {}

 Making this possible:

 Foo.fooBar(4);

 --
 /Jacob Carlborg

I'd expect it to look like this: void fooBar(Foo)(int x) {}

That looks too much like a template function to me. What about: void fooBar(static Foo, int x) {} Note: no parameter name for the "static" Foo parameter (as it's not really a parameter - simply a placeholder to indicate it's UFCS). C# doesn't have static UFCS (called "extension methods" in C# parlance) tho some people have wanted it: http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/8ac0e6bf-c859-4cc4-919f-c80eedfccf63 I guess the reason it doesn't exist is that there is no technical reason for it, all it gives you is a nicer syntax. You can get fairly close with a custom static class, static method taking an instance of the class you want to 'extend'. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Jun 14 2012
prev sibling next sibling parent Gor Gyolchanyan <gor.f.gyolchanyan gmail.com> writes:
On Thu, Jun 14, 2012 at 1:52 PM, Regan Heath <regan netmail.co.nz> wrote:
 On Thu, 14 Jun 2012 10:43:43 +0100, Gor Gyolchanyan
 <gor.f.gyolchanyan gmail.com> wrote:

 On Thu, Jun 14, 2012 at 10:46 AM, Jacob Carlborg <doob me.com> wrote:
 UFCS can be used to emulate adding new members/instance methods to a
 class
 or struct:

 class Foo
 {
 }

 void bar (Foo foo, int x) {}

 auto foo =3D new Foo;
 foo.bar(3);

 Is it possible, somehow, to emulate adding new _static_ methods to a
 class,
 something like this:

 void fooBar (/*something*/, int x) {}

 Making this possible:

 Foo.fooBar(4);

 --
 /Jacob Carlborg

I'd expect it to look like this: void fooBar(Foo)(int x) {}

That looks too much like a template function to me. =C2=A0What about: void fooBar(static Foo, int x) {} Note: no parameter name for the "static" Foo parameter (as it's not reall=

 parameter - simply a placeholder to indicate it's UFCS).


 C# doesn't have static UFCS (called "extension methods" in C# parlance) t=

 some people have wanted it:
 http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/8ac0e6=

 I guess the reason it doesn't exist is that there is no technical reason =

 it, all it gives you is a nicer syntax.

 You can get fairly close with a custom static class, static method taking=

 instance of the class you want to 'extend'.

 R

 --
 Using Opera's revolutionary email client: http://www.opera.com/mail/

Yes, that does look bad. How about this? void fooBar(T : Foo)(int x) { } --=20 Bye, Gor Gyolchanyan.
Jun 14 2012
prev sibling next sibling parent Gor Gyolchanyan <gor.f.gyolchanyan gmail.com> writes:
On Thu, Jun 14, 2012 at 3:17 PM, Jacob Carlborg <doob me.com> wrote:
 On 2012-06-14 12:25, Gor Gyolchanyan wrote:
 Yes, that does look bad. How about this?

 void fooBar(T : Foo)(int x) { }

I don't like that it's a template function, there's really no reason. It seems to just be a limitation in the syntax. -- /Jacob Carlborg

It doesn't matter whether a function is a template or not. The only thing that matters is the number of instances it produces. A template function, which produces only one instance is equivalent to a non-template function. The function above can produce only one instance (unless overloaded). -- Bye, Gor Gyolchanyan.
Jun 14 2012
prev sibling next sibling parent reply deadalnix <deadalnix gmail.com> writes:
Le 14/06/2012 08:46, Jacob Carlborg a crit :
 UFCS can be used to emulate adding new members/instance methods to a
 class or struct:

 class Foo
 {
 }

 void bar (Foo foo, int x) {}

 auto foo = new Foo;
 foo.bar(3);

 Is it possible, somehow, to emulate adding new _static_ methods to a
 class, something like this:

 void fooBar (/*something*/, int x) {}

 Making this possible:

 Foo.fooBar(4);

I already think that static method was a bad idea from the everything have to be an object time. The need for static function is pretty weak when we have free function and that they can access private objects data as needed. What would be the use case for such a feature ?
Jun 14 2012
next sibling parent reply "Regan Heath" <regan netmail.co.nz> writes:
On Thu, 14 Jun 2012 13:33:23 +0100, deadalnix <deadalnix gmail.com> wrot=
e:

 Le 14/06/2012 08:46, Jacob Carlborg a =E9crit :
 UFCS can be used to emulate adding new members/instance methods to a
 class or struct:

 class Foo
 {
 }

 void bar (Foo foo, int x) {}

 auto foo =3D new Foo;
 foo.bar(3);

 Is it possible, somehow, to emulate adding new _static_ methods to a
 class, something like this:

 void fooBar (/*something*/, int x) {}

 Making this possible:

 Foo.fooBar(4);

I already think that static method was a bad idea from the =AB everyth=

 have to be an object =BB time.

 The need for static function is pretty weak when we have free function=

 and that they can access private objects data as needed.

Good point. A module level free function in D is essentially a static = class method for /all/ classes in the module. I think people like stati= c = methods over free functions for aesthetic/organisational reasons, not fo= r = functional ones. Except.. if it's a static method then as it's called = with syntax like <class>.<method> it cannot collide with a free function= = called <method>. So, perhaps it helps with function lookup and = collisions, much like namespaces do.
 What would be the use case for such a feature ?

Assuming; 1. You have no control over the class Foo, nor it's module 2. You don't want private or protected access to Foo's members Then all you'd get with static UFCS is nicer calling syntax, and possibl= y = less lookup/collisions, that's it really. R -- = Using Opera's revolutionary email client: http://www.opera.com/mail/
Jun 14 2012
next sibling parent Jacob Carlborg <doob me.com> writes:
On 2012-06-14 15:57, Regan Heath wrote:

 Good point. A module level free function in D is essentially a static
 class method for /all/ classes in the module. I think people like static
 methods over free functions for aesthetic/organisational reasons, not
 for functional ones. Except.. if it's a static method then as it's
 called with syntax like <class>.<method> it cannot collide with a free
 function called <method>. So, perhaps it helps with function lookup and
 collisions, much like namespaces do.

 What would be the use case for such a feature ?

Assuming; 1. You have no control over the class Foo, nor it's module 2. You don't want private or protected access to Foo's members Then all you'd get with static UFCS is nicer calling syntax, and possibly less lookup/collisions, that's it really.

Exactly. -- /Jacob Carlborg
Jun 14 2012
prev sibling parent deadalnix <deadalnix gmail.com> writes:
Le 14/06/2012 15:57, Regan Heath a crit :
 Good point. A module level free function in D is essentially a static
 class method for /all/ classes in the module. I think people like static
 methods over free functions for aesthetic/organisational reasons, not
 for functional ones. Except.. if it's a static method then as it's
 called with syntax like <class>.<method> it cannot collide with a free
 function called <method>. So, perhaps it helps with function lookup and
 collisions, much like namespaces do.

 What would be the use case for such a feature ?

Assuming; 1. You have no control over the class Foo, nor it's module 2. You don't want private or protected access to Foo's members Then all you'd get with static UFCS is nicer calling syntax, and possibly less lookup/collisions, that's it really. R

Or for the namespace reason. It is a valid point. But UFCS is no help when it come to name collisions. Actually, it can increase it. So it is still unclear to me what is the benefit of static UFCS .
Jun 14 2012
prev sibling next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2012-06-14 14:33, deadalnix wrote:

 I already think that static method was a bad idea from the  everything
 have to be an object  time.

 The need for static function is pretty weak when we have free function
 and that they can access private objects data as needed.

 What would be the use case for such a feature ?

Originally the idea pop up in my head when I was thinking if it was possible to implement, in library code, the magic meta namespace the community has been talking about a couple of times in the past. Something like this: import std.meta; class Foo { void bar (){} } auto methods = Foo.meta.methods; -- /Jacob Carlborg
Jun 14 2012
parent Jacob Carlborg <doob me.com> writes:
On 2012-06-14 17:41, Artur Skawina wrote:

 Polluting local namespaces with magic identifiers is a really bad idea.
 What's wrong with "auto methods = meta!Foo.methods;" which works right now?

There's nothing wrong with that except for the syntax doesn't look as nice as "Foo.meta.methods". And If I recall correctly the syntax of of the suggested meta namespace was: "Foo.meta.methods". I actually did tak a look in the archives and I was wrong. The suggestion looked like this: meta.compiles(XXX) meta.isArithmetic; // note, property syntax OK if no arguments meta.isArithmetic(int*); -- /Jacob Carlborg
Jun 14 2012
prev sibling next sibling parent Artur Skawina <art.08.09 gmail.com> writes:
On 06/14/12 16:19, Jacob Carlborg wrote:
 On 2012-06-14 14:33, deadalnix wrote:
 
 I already think that static method was a bad idea from the « everything
 have to be an object » time.

 The need for static function is pretty weak when we have free function
 and that they can access private objects data as needed.

 What would be the use case for such a feature ?

Originally the idea pop up in my head when I was thinking if it was possible to implement, in library code, the magic meta namespace the community has been talking about a couple of times in the past. Something like this: import std.meta; class Foo { void bar (){} } auto methods = Foo.meta.methods;

Polluting local namespaces with magic identifiers is a really bad idea. What's wrong with "auto methods = meta!Foo.methods;" which works right now? artur
Jun 14 2012
prev sibling parent "jerro" <a a.com> writes:
 I already think that static method was a bad idea from the « 
 everything have to be an object » time.

 The need for static function is pretty weak when we have free 
 function and that they can access private objects data as 
 needed.

I sometimes use structs with static members in a way similar to ML functors: struct A { alias SomeType T; T foo(){ ... } void bar(T a, T b){ ... } } struct B(S) { // some static members that use S.T, S.foo and S.bar } ... B!(A).someMember();
 What would be the use case for such a feature ?

I haven't ever felt a need to have the feature discussed in this thread either.
Jun 14 2012
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/13/2012 11:46 PM, Jacob Carlborg wrote:
 Is it possible, somehow, to emulate adding new _static_ methods to a class,
 something like this:

 void fooBar (/*something*/, int x) {}

 Making this possible:

 Foo.fooBar(4);

What's the compelling use case?
Jun 15 2012
parent reply Jacob Carlborg <doob me.com> writes:
On 2012-06-16 02:50, Walter Bright wrote:

 What's the compelling use case?

The use case is like with UFCS you can emulate adding new instance methods to a class. With this you can emulate adding new static methods to a class. -- /Jacob Carlborg
Jun 16 2012
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 06/16/2012 03:37 PM, Jacob Carlborg wrote:
 On 2012-06-16 02:50, Walter Bright wrote:

 What's the compelling use case?

The use case is like with UFCS you can emulate adding new instance methods to a class. With this you can emulate adding new static methods to a class.

That is not a use case. It is a description of the feature. The most compelling use case for UFCS is function call chains.
Jun 16 2012
prev sibling next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 6/14/12, Jacob Carlborg <doob me.com> wrote:
 Is it possible, somehow, to emulate adding new _static_ methods to a
 class, something like this:

Of course there is, this is D not Java! Enjoy: import std.stdio; import std.metastrings; void fooBar(T : Foo)(int x) { writeln(x); } struct Foo { static auto opDispatch(string name, Params...)(Params params) { enum strOf = typeof(this).stringof; enum str = Format!("return .%s!%s(params);", name, strOf); mixin(str); } } void main() { Foo.fooBar(4); }
Jun 15 2012
parent Jacob Carlborg <doob me.com> writes:
On 2012-06-16 03:18, Andrej Mitrovic wrote:

 Of course there is, this is D not Java! Enjoy:

 import std.stdio;
 import std.metastrings;

 void fooBar(T : Foo)(int x) { writeln(x); }

 struct Foo
 {
      static auto opDispatch(string name, Params...)(Params params)
      {
          enum strOf = typeof(this).stringof;
          enum str = Format!("return .%s!%s(params);", name, strOf);
          mixin(str);
      }
 }

 void main()
 {
      Foo.fooBar(4);
 }

That's cheating :) -- /Jacob Carlborg
Jun 16 2012
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 6/16/12, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:
     static auto opDispatch(string name, Params...)(Params params)

Maybe "auto ref" there actually.
Jun 15 2012
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 6/16/12, Jacob Carlborg <doob me.com> wrote:
 That's cheating :)

You're right, I didn't think of a non-intrusive way to do this. :)
Jun 17 2012
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 14 Jun 2012 02:46:13 -0400, Jacob Carlborg <doob me.com> wrote:

 UFCS can be used to emulate adding new members/instance methods to a  
 class or struct:

 class Foo
 {
 }

 void bar (Foo foo, int x) {}

 auto foo = new Foo;
 foo.bar(3);

 Is it possible, somehow, to emulate adding new _static_ methods to a  
 class, something like this:

 void fooBar (/*something*/, int x) {}

 Making this possible:

 Foo.fooBar(4);

The main benefit of having a static method vs. a free function is namespace. That is, avoiding polluting the global namespace. But a UFCS function *will* pollute the namespace. There is no way around it. I see no compelling reason to have this. BTW, you can always replace the . with a _: Foo_fooBar(4); We need there to be a really compelling use case to add things like this -- just adding features for the sake of "just in case it's useful" doesn't fly. -Steve
Jun 25 2012