A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/dotnet/csharplang/issues/1277 below:

modifier (perhaps "static") for local functions, to explicitly disallow captured state semantics · Issue #1277 · dotnet/csharplang · GitHub

A recurring problem I've seen a lot since the addition of local methods - and in particular in async optimizations (and not just me) is that it is very easy to accidentally introduce shared state into a local function when you really didn't want to. For example:

void Foo(int a) {
    void Bar(int val) {
         Blah(a); // <== error; this was meant to be val
    }
    // ...
    Bar(a);
}

This is a common intent when using local functions to enclose a method, without actually intending to allow shared capture state.

Currently, the only "fix" here is to move the method out:

static void Bar(int val) {
     Blah(val); // <== fixed, because the compiler told us about it
}
void Foo(int a) {    
    // ...
    Bar(a);
}

This works, but it pollutes the space and loses code locality and expressiveness. I actually find myself routinely copy/pasting local methods out and back in again to check that they still compile - to see if I've leaked state.

Proposal: allow the static modifier on local functions, to express the intent to divorce all state. I'm not 100% sure that static is the right word, but it seems close. The effect would be simply to enforce that variables (parameters and locals) declared outside the static local method are not in scope inside the local method, essentially as though the local method had been declared outside the method. The "local method", then, is simply here for code cleanliness reasons.

This has the effect of avoiding unintended captured state machinery.

Example:

void Foo(int a) {
    static void Bar(int val) {
         Blah(val); // <== fixed, because the compiler told us about it
    }
    // ...
    Bar(a);
}

There is an outstanding question of whether it is acceptable to share the this instance but nothing else; this ambiguity is perhaps the biggest thing against the static keyword.

Additional possibility: because of the lack of state, it allows re-use of the most obvious/correct variable names. I've seen lots of examples essentially like:

void Foo(int a) {
    void Bar(int innerA) {
         Blah(innerA); // <== note awkward naming
    }
    // ...
    Bar(a);
}

but this proposal allows the "obvious" names to be used consistently:

void Foo(int a) {
    static void Bar(int a) {
         Blah(a);
    }
    // ...
    Bar(a);
}

Drawaes, Joe4evr, iam3yal, benaadams, DavidArno and 42 morejnm2, MattDillard, federicoce-moravia, vasiliuk, DrSensor and 2 moreNeme12AustinBryan


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4