Closures: why are they so useful?

前端 未结 10 647
渐次进展
渐次进展 2020-12-07 10:04

As an OO developer, maybe I have difficulty seeing its value. What added value do they give? Do they fit in an OO world?

相关标签:
10条回答
  • 2020-12-07 10:29

    Closures don't give you any extra power.

    Anything you can achieve with them you can achieve without them.

    But they are very usable for making code more clear and readable. And as we all know clean readable short code is a code that is easier to debug and contains fewer bugs.

    Let me give you short Java example of possible usage:

        button.addActionListener(new ActionListener() {
            @Override public void actionPerformed(ActionEvent e) {
                System.out.println("Pressed");
            }
        });
    

    Would be replaced (if Java had closures) with:

    button.addActionListener( { System.out.println("Pressed"); } );
    
    0 讨论(0)
  • 2020-12-07 10:30

    You can see it as a generalization of a class.

    Your class holds some state. It has some member variables that its methods can use.

    A closure is simply a more convenient way to give a function access to local state.

    Rather than having to create a class which knows about the local variable you want the function to use, you can simply define the function on the spot, and it can implicitly access every variable that is currently visible.

    When you define a member method in a traditional OOP language, its closure is "all the members visible in this class".

    Languages with "proper" closure support simply generalize this, so a function's closure is "all the variables visible here". If "here" is a class, then you have a traditional class method.

    If "here" is inside another function, then you have what functional programmers think of as a closure. Your function can now access anything that was visible in the parent function.

    So it's just a generalization, removing the silly restriction that "functions can only be defined inside classes", but keeping the idea that "functions can see whatever variables are visible at the point where they're declared".

    0 讨论(0)
  • 2020-12-07 10:31

    It's a pity, people no longer learn Smalltalk in edu; there, closures are used for control structures, callbacks, collection enumeration, exception handling and more. For a nice little example, here is a worker queue action handler thread (in Smalltalk):

    |actionQueue|
    
    actionQueue := SharedQueue new.
    [
        [
            |a|
    
            a := actionQueue next.
            a value.
        ] loop
    ] fork.
    
    actionQueue add: [ Stdout show: 1000 factorial ].
    

    and, for those who cannot read Smalltalk, the same in JavaScript syntax:

    var actionQueue;
    
    actionQueue = new SharedQueue;
    function () {
        for (;;) {
            var a;
    
            a = actionQueue.next();
            a();
        };
    }.fork();
    
    actionQueue.add( function () { Stdout.show( 1000.factorial()); });
    

    (well, as you see: syntax helps in reading the code)

    Edit: notice how actionQueue is referenced from inside the blocks, which works even for the forked thread-block. Thats what makes closures so easy to use.

    0 讨论(0)
  • 2020-12-07 10:35

    Here are some interesting articles:

    • Crossing borders: Closures - by Bruce Tate, mentions some advantages of closures
    • A Definition of Closures - by Neal Gafter (one of the people who invented one of the closures proposals for Java)
    0 讨论(0)
  • 2020-12-07 10:40

    looking at above examples, I can add my bit.

    • I appreciate the style, state-hiding part and chaining of expression but this is not enough

    • A lot can be said about simple and explicit code

    • I feel that Scala, Perl and some other Scheme type languages are designed to make kind of a shorthand for the particular way of thinking by the language designer or make them "more productive"

    I would take the simplicity of python and early syntax of java etc as better way of simplicity and explicitness

    It might be quite fast to write cryptic chained closures in a tight space. however everything can be done by simple objects and algorithms

    closures are needed but not that often to warrant them to be first class citizen .

    0 讨论(0)
  • 2020-12-07 10:43

    Closures fit pretty well into an OO world.

    As an example, consider C# 3.0: It has closures and many other functional aspects, but is still a very object-oriented language.

    In my experience, the functional aspects of C# tend to stay within the implementation of class members, and not so much as part of the public API my objects end up exposing.

    As such, the use of closures tend to be implementation details in otherwise object-oriented code.

    I use them all the time, as this code snippet from one of our unit tests (against Moq) shows:

    var typeName = configuration.GetType().AssemblyQualifiedName;
    
    var activationServiceMock = new Mock<ActivationService>();
    activationServiceMock.Setup(s => s.CreateInstance<SerializableConfigurationSection>(typeName)).Returns(configuration).Verifiable();
    

    It would have been pretty hard to specify the input value (typeName) as part of the Mock expectation if it hadn't been for C#'s closure feature.

    0 讨论(0)
提交回复
热议问题