www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 6579] New: Calling static method should *require* using type and not instance

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

           Summary: Calling static method should *require* using type and
                    not instance
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: schveiguy yahoo.com



05:33:42 PDT ---
Consider:

struct S
{
   static int i;
   int x;
   static void reset() {i = i.init;}
}

S instance;
assert(instance.x == 0);
instance.x = 5;

instance.reset();

assert(instance.x == 0); // fails!

This appears to affect instance, but actually it does nothing to the instance,
it only affects the static data.

I think it should require using the type, via:

S.reset();

or

typeof(instance).reset();

This makes it clear that the instance plays no role in the function call.

This also paves the way for bug 3345

I think also this should apply to member fields.  However, enums and aliases
should continue to be accessible using the instance.

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




08:47:13 PDT ---
This is in response to: http://d.puremagic.com/issues/show_bug.cgi?id=3345#c3

It's only a poorly chosen name because of the way you can call static functions
on instances.

What would be a better name, resetStatic()?  I mean, why must I repeat that
it's static, I've already said it was static!

The problem is the coupling between static function names and instances is not
an obvious connection.  When naming a static function one seldom considers how
it will read if called on an instance, because one's expecting people to use
the class/struct name to call it.

Another example, let's say you have a File struct (not unheard of).  Then you
want a static method to open a file.  A logical thing to do would be:

struct File
{
   static File open(string name) {...}
}

expecting the usage:

auto f = File.open("blah.txt");

However, that makes this also valid:

File f;

f.open("blah.txt");

Which doesn't do even close to what you would expect it to, yet compiles
happily.

I can't even think of a way to name that function which makes it look like
"you're doing the wrong thing" on the instance, yet is good enough to be used
as a function name.

A solution can be to just put the function outside the struct, calling it
openFile.  But it almost feels like D is discouraging static methods, use
global functions instead.

I dispute that this is more annoying for generic code.  Calling a static method
from an instance is not a usual occurrence, and typically type names in generic
code are T or S.  How horrible is it to do T.foo() vs. t.foo()?

Note that even though this would be a breaking change, it would be a loud one,
not a silent one.  Any existing code relying on calling static methods from
instances would not compile.

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


Steven Schveighoffer <schveiguy yahoo.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|Calling static method       |Calling static method
                   |should *require* using type |should *require* using type
                   |and not instance            |and not instance, unless
                   |                            |specified by author



09:35:19 PDT ---
Revised proposal:

One cannot call a static method using an instance method unless the author
aliases it into the instance namespace.

Andrei pointed out that one can design a static method *intending* it to be
used on an instance, for example to save a virtual method call when it's not
needed, but still implement a generic interface.

For the cases where a static method was intended to be callable from an
instance, there should be a provision for that.

A sample proposal:

struct S
{
   static void foo() {}
   alias foo this.foo;
}

Now an instance of S can be used to call foo.

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


art.08.09 gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |art.08.09 gmail.com




 Revised proposal:
 
 One cannot call a static method using an instance method unless the author
 aliases it into the instance namespace.
 
 Andrei pointed out that one can design a static method *intending* it to be
 used on an instance, for example to save a virtual method call when it's not
 needed, but still implement a generic interface.
 
 For the cases where a static method was intended to be callable from an
 instance, there should be a provision for that.
 
 A sample proposal:
 
 struct S
 {
    static void foo() {}
    alias foo this.foo;
 }
 
 Now an instance of S can be used to call foo.
a) I don't see any real need to separate type and instance methods b) OTOH i don't think it can do much harm either. But overloading alias further does not seem like the best idea. 'static method void foo() {}' - method is needed for UFCS too, where it would do something similar. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jun 02 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=6579


Gor Gyolchanyan <gor boloneum.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |gor boloneum.com



---


 Revised proposal:
 
 One cannot call a static method using an instance method unless the author
 aliases it into the instance namespace.
 
 Andrei pointed out that one can design a static method *intending* it to be
 used on an instance, for example to save a virtual method call when it's not
 needed, but still implement a generic interface.
 
 For the cases where a static method was intended to be callable from an
 instance, there should be a provision for that.
 
 A sample proposal:
 
 struct S
 {
    static void foo() {}
    alias foo this.foo;
 }
 
 Now an instance of S can be used to call foo.
a) I don't see any real need to separate type and instance methods b) OTOH i don't think it can do much harm either. But overloading alias further does not seem like the best idea. 'static method void foo() {}' - method is needed for UFCS too, where it would do something similar.
It hinders overloading. For so long I wanted to be able to have both static and non-static opDispatch and opCall and couldn't because of this. This behavior is not doing any good anyway. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jun 03 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=6579





 It hinders overloading. For so long I wanted to be able to have both static and
 non-static opDispatch and opCall and couldn't because of this. 
This is a very good argument. opCall&co are a bit special, but doing that should be possible w/o special-casing them.
 This behavior is not doing any good anyway.
It has worked like that for a long time, and it is useful sometimes. But the old behavior can be easily emulated with something like static int f() {}; auto f(A...)(A a) { return typeof(this).f(a); } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jun 03 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=6579


timon.gehr gmx.ch changed:

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




 It hinders overloading. For so long I wanted to be able to have both static and
 non-static opDispatch and opCall and couldn't because of this. This behavior is
 not doing any good anyway.
This issue is not closely related to overloading. Slightly refining the overloading rules as proposed in issue 3345 would already solve the problem. struct S{ static void foo(){...} void foo(){...} } struct T{ static void foo(){...} void bar(){...} } void main(){ S s; T t; S.foo(); // calls the static version s.foo(); // calls the instance version T.foo(); // ok t.foo(); // ok // T.bar() // error t.bar(); // ok } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jun 03 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=6579





 Slightly refining the overloading rules as proposed in issue 3345 would already
 solve the problem.
 struct T{
     static void foo(){...}
     void bar(){...}
 }
     t.foo(); // ok
This seems too dangerous to allow (by default). Do static and non-static methods form one overload set? struct S { static auto opCall(int) {...} auto opCall(string) {...} } Oh, and i just noticed the suggestion in this report that static fields should not be accessible via an instance - no, that would a break a lot of code, for almost no gain (you can already place the static data in another struct and embed that one in an (anonymous) union) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jun 03 2012
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=6579




10:01:16 PDT ---


 Oh, and i just noticed the suggestion in this report that static fields should
 not be accessible via an instance - no, that would a break a lot of code, for
 almost no gain (you can already place the static data in another struct and
 embed
 that one in an (anonymous) union)
That is not as important as the method calls. At least with instance access to static data, you are addressing the data named by the call. So for my original example: instance.i = 5; This is correctly addressing a variable named i, even though it's not part of the instance. However, with: instance.reset(); This implies you are passing instance as a parameter when you are actually not. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jun 04 2012