On Monday, 5 November 2012 at 08:37:49 UTC, Faux Amis wrote:
Ok, good to see that you are replying to incorrectly scoped variables, but this is not the point I am trying to make. I know you should always keep the scope as small as possible.

Eh? I'm confused. The second half of my post certainly was a bit of a rant on incorrectly scoped variables (which is related to the discussion, but it was my response to bearophile), but the first part of my post is supporting the viewpoint that you should avoid using module-scoped variables (and even static struct member variables) and suggesting an alternative.

Can you think of a setting in which we have legitimate private struct members? If so, then add to this setting that you only want one instantiation of the data in this struct. As a solution, what is wrong with dropping the struct encapsulation? There is no other code except the struct in the module.

I sincerely want to know if there is any difference. As I understand it the scope is exactly the same or even smaller as you can't leak instances of modules as you can structs.

From my understanding, you're trying to get a specific viewpoint on this idea?

From a good-coding standpoint, do you think there is a difference between these two options?

--
module a;

int a;
--
module b;

struct S{//otherwise unused wrapper
static int b;
}
--

I think the first option is "better" than the second. The second seems to be a misuse of struct to me. I can't see why you'd use a struct in the second option.

That said, they're effectively equivalent pieces of code. That is, they're both static data that is a shared resource among all functions that have access to them. And, thus, they're both "equally bad" in terms of how they will affect the understandability and testability of the code. It's possible that it would cause the code to have more bugs in it than it would otherwise.

That is, both of them are not as good of choices as this:
---
void good(ref int b) pure {
    // code using/setting b
}
void good2(int b) pure {
    // code using b, but not setting it
}

// No b in module scope or statically allocated

// Sometimes a better idea, depending on circumstances:
int better(int b) pure {
   // code using b, and putting changes into changedB
   return changedB;
}

// example uses:
void main() {
    int a = 1, b = 2, c = 3;
    good(a);
    good2(b);
    c = better(c);
}
---

Because this creates code that is honest about its dependencies and allows for the overall state of the program to be consistent between runs of functions. This is essential for testability, but it's also important for a programmer to reason about the behavior of their code.

Of course, I'm sure you can give examples of code that couldn't be written like that, and that's okay. I'm only arguing that you should avoid static data when it's realistic to do so, not that it will open a black hole in your living room if you use it under any circumstances :-). Though if you're using it as your "primary data encapsulation," I have to wonder whether you're using it in instances it could have been avoided.

Reply via email to