digitalmars.D.learn - "static" means too many things
- bearophile (36/36) May 01 2012 This is the brief of some D code, it shows one consequence of the
- Andrej Mitrovic (18/20) May 01 2012 You can almost cheat, but you can't:
- H. S. Teoh (10/24) May 01 2012 Wait, I thought static in the context of fill() can only mean "function
- Timon Gehr (6/42) May 02 2012 'fill' should accept the 'this' pointer instead of the frame pointer,
This is the brief of some D code, it shows one consequence of the
excessive overloading of the D "static" keyword:
struct Foo {
     bool solve() {
       /*static*/ bool fill(int r, int c, Cell n) {
           // ...
           if (fill(r + i, c + j, n + 1))
             return true;
       }
       return fill(x, y, 1);
     }
}
The Foo struct has solve() instance method, solve() contains and
calls a nested (recursive) function named fill().
fill() has to use instance attributes, so it can't be a static
struct function regarding the struct Foo. On the other hand the
nested function fill() doesn't need variables defined inside the
method solve(), so it doesn't require a frame pointer to solve(),
so it's static for solve().
The problem is that "static" is used to denote both nested
functions that have no frame pointer (they are often faster and
they tend to be less buggy because they can't use names from
outer scopes, almost like pure functions), and static struct
methods :-)
So to denote a function that doesn't need a frame pointer
something like " noframe" sounds better than "static".
In practice this is not a very common situation, and fill() here
is not performance-critical, so keeping the frame pointer is not
so bad (I also annotate fill() with "pure", so despite not being
static to solve() it's able to use only immutable names from the
scope of solve()).
Where performance is very important it suffices to pull fill()
out of solve(), define it as a private instance method, and maybe
rename it to _fill() or something similar.
Bye,
bearophile
 May 01 2012
On 5/2/12, bearophile <bearophileHUGS lycos.com> wrote:This is the brief of some D code, it shows one consequence of the excessive overloading of the D "static" keyword:You can almost cheat, but you can't: struct Foo { bool solve() { auto fill = function(int r, int c, int x) { writeln(x); // can access 'x' if (fill(x, y, z)) // error: doesn't find the right 'fill' function return false; return true; }; return fill(x, y, z); } int x, y, z; } So no recursive calls I'm afraid.
 May 01 2012
On Wed, May 02, 2012 at 01:46:37AM +0200, bearophile wrote:
 This is the brief of some D code, it shows one consequence of the
 excessive overloading of the D "static" keyword:
 
 struct Foo {
     bool solve() {
       /*static*/ bool fill(int r, int c, Cell n) {
           // ...
           if (fill(r + i, c + j, n + 1))
             return true;
       }
 
       return fill(x, y, 1);
     }
 }
Wait, I thought static in the context of fill() can only mean "function
without frame pointer"? Because static members of Foo cannot be declared
inside solve(), they'd have to be directly under Foo.
Or am I misunderstanding something here?
That said, though, I do find that D overloads the keyword 'static'
excessively.
T
-- 
MASM = Mana Ada Sistem, Man!
 May 01 2012
On 05/02/2012 01:46 AM, bearophile wrote:
 This is the brief of some D code, it shows one consequence of the
 excessive overloading of the D "static" keyword:
 struct Foo {
     bool solve() {
         /*static*/ bool fill(int r, int c, Cell n) {
             // ...
             if (fill(r + i, c + j, n + 1))
             return true;
         }
         return fill(x, y, 1);
     }
 }
 The Foo struct has solve() instance method, solve() contains and
 calls a nested (recursive) function named fill().
 fill() has to use instance attributes, so it can't be a static
 struct function regarding the struct Foo. On the other hand the
 nested function fill() doesn't need variables defined inside the
 method solve(), so it doesn't require a frame pointer to solve(),
 so it's static for solve().
 The problem is that "static" is used to denote both nested
 functions that have no frame pointer (they are often faster and
 they tend to be less buggy because they can't use names from
 outer scopes, almost like pure functions), and static struct
 methods :-)
 So to denote a function that doesn't need a frame pointer
 something like " noframe" sounds better than "static".
 In practice this is not a very common situation, and fill() here
 is not performance-critical, so keeping the frame pointer is not
 so bad (I also annotate fill() with "pure", so despite not being
 static to solve() it's able to use only immutable names from the
 scope of solve()).
 Where performance is very important it suffices to pull fill()
 out of solve(), define it as a private instance method, and maybe
 rename it to _fill() or something similar.
 Bye,
 bearophile
  'fill' should accept the 'this' pointer instead of the frame pointer, 
without programmer interaction. This is a local optimisation. If you 
need to guarantee that the double pointer dereference does not occur, 
make 'fill' a private instance method. I don't see the need of 
introducing additional syntax here.
 May 02 2012








 
  
  
 
 Andrej Mitrovic <andrej.mitrovich gmail.com>
 Andrej Mitrovic <andrej.mitrovich gmail.com> 