Thread overview | ||||||
---|---|---|---|---|---|---|
|
May 01, 2012 "static" means too many things | ||||
---|---|---|---|---|
| ||||
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 02, 2012 Re: "static" means too many things | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | 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 02, 2012 Re: "static" means too many things | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | 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 02, 2012 Re: "static" means too many things | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | 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.
|
Copyright © 1999-2021 by the D Language Foundation