What do local functions really need?



  • That's it. https://ru.stackoverflow.com/q/539509/179270 The question of planned innovations is being raised /questions/tagged/c%23 version 7.

    In particular, I was interested in so-called Local functions

    ♪ https://ru.stackoverflow.com/a/539516/179270 @VladD is an example of how Local function:

    IEnumerable<int> GetOdd(IEnumerable<int> s)
    {
        if (s == null)
            throw new ArgumentNullException();
        // обратите внимание, `Inner` без параметров
        IEnumerable<int> Inner()
        {
            foreach (var v in s)
                if (v % 2 != 0)
                    yield return v;
        }
        return Inner();
    }
    

    But I think that's a little bit of an example. I'm not sure.in this case, it would have been possible to avoid a function Inner()

    I also do not understand the following statement:

    With regard to local functions, I think that, on the contrary, the private functions of the classes are often used as a coscillary for the absence of local functions. Frequently, a dysper is placed in a privatized function from a single function that is not internal. The loco function is a better way for such functions.

    In my own code, I'm doing a separate code based on the following rules:

    1. The function which can be reused;
    2. Functioning as a separate method to support Stringency functions;
    3. Other

    For example:

    public IEnumerable<string> GetPhonesForNotice(requestId)
    {
        var requestState = GetStateOfRequest(int requestId);
        switch(requestState)
        {
            case "Открыта":
            {
                return getRecipientsForNewRequest(int requestId);
                break;
            }
            case "Закрыта":
            {
                return getRecipientsForClosedRequest(int requestId);
                break;
            }
        }
    }
    

    private IEnumerable<string> getRecipientsForNewRequest(int requestId)
    {
    }
    private IEnumerable<string> getRecipientsForClosedRequest(int requestId)
    {
    }

    If I understood correctly, then in the new language version, getRecipientsForNewRequest(int requestId)getRecipientsForClosedRequest(int requestId) to be implemented within Main function GetPhonesForNotice(int requestId) But I don't understand what's right or better than the current option?



  • I think so.

    It's not a technical issue. (If there are technical differences, they are given at the end of the reply.) On the technical side, the same privatized function can be established to which all parameters are clearly transferred. If the internal function has to be less than the parameters (e.g. because of the need for specific signatures), closures can be built. All technical issues are also addressed within old possibilities. (Same as it would be possible to use a few functions, no classes, and transfer this in methods clearly, etc.)

    The thing is, we want to not pollute the chopper-function class, but put them inside what they belong to. It is a complete analogy to the idea that the class should contain all the work he needs and not require external management. Same as here, the function contains inside. What's needed for work and private support Methods only where they are not limited to the meaning of one function, i.e. where they are understood within a framework Total

    With this approach, yes, local variables are in some way replaced by class fields, so in situations where you had to create an internal class and cause methods, it is now possible to do the same with local functions.

    In addition, the reduction of the connection code, such as the non-residential transmission of variables, is always important, so the connection code is the possibility of error.


    As another motivating example:

    void SortBy<T>(List<T> list, Func<List, double> expr, bool ascending)
    {
        int comparerAscending(T t1, T t2)
        {
            return expr(t1).Compare(expr(t2));
        }
    
    int comparerDescending(T t1, T t2)
    {
        return expr(t2).Compare(expr(t1));
    }
    
    list.Sort(ascending ? comparerAscending : comparerDescending);
    

    }

    Without local functions, you would have to create internal delegates.


    Another scenario where internal functions can be useful is coding. If you're creating an auxiliary function, you can accidentally get to the name you've already occupied, you don't know what's in the rest of the class. If the subsidiary function is &quot; packed &quot; in another function, no problem arises.


    Supplement: Let us consider, except logical, the differences between local functions and existing language tools.

    The difference between the privatized non-local function is that the local function &quot; sees &quot; variables declared in the covering function prior to it. Thus, there is no need to transfer parameters to a local function. Obviously.Which means we can control her signature more freely. (This may be important, see example SortBy.

    The difference between a local function and a similar localized delegate with a lambda-function is that

    • Delegate &apos; s variable may be redefined, the name of the local function cannot be translated
    • Lambda-Functions require a chemical syntax to perform a recurring challenge that breaks when the delegate variable is changed (Y-combinator, don't offer!), local functions have no problem.
    • Lambda-function can't be a generator.yield return)
    • You can't declare the lymbda function.Func<T, int> f = t => 1; not compromised for an unknown type Twith local functions, no problems arise
    • Productivity: Delegate means the external allocation of a delegated type copy; the local function of the deficiency is deficient and additional allocation is required only for non-trivial circuits.

    Literature: https://github.com/dotnet/roslyn/issues/3911


Log in to reply
 


Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2