Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Maybe I don't understand closures fully but take for example C#, why would I use closures when I can use classes? Am I missing something?

Note that I read this one already but my question is specific to closure: Introducing functional programming constructs in non-functional programming languages

share|improve this question

marked as duplicate by gbjbaanb, Caleb, gnat, MichaelT, Bart van Ingen Schenau Apr 19 at 17:23

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

3  
I think you're right in that you're misunderstanding closures. I don't see how closures and classes strictly relate or compete with regards to functionality. –  Steve Evers Apr 18 at 18:16
    
Closures are implicit, equivalent classes need explicit declarations. Why do you want to write more code when less is enough? –  SK-logic Apr 19 at 9:25

2 Answers 2

up vote 7 down vote accepted

It's less verbose, increases flexibility, and decreases coupling. What's not to like?

Let's compare the use of a closure for handling an event versus using a class. The class must implement a specific interface. This means the event handler must not only have specific arguments, but also a specific name. If you want that same object to be able to handle events from other sources, those sources either cannot use the same function name in the handler interface, or the event source must provide some other means of distinguishing the events.

That leads to messes like Java having an ActionListener, AdjustmentListener, AncestorListener, AWTEventListener, BeanContextMembershipListener, BeanContextServiceRevokedListener, BeanContextServices, BeanContextServicesListener, CaretListener, CellEditorListener, ChangeListener, ComponentListener, ConnectionEventListener, ContainerListener, ControllerEventListener, DocumentListener, DragGestureListener, DragSourceListener, DragSourceMotionListener, DropTargetListener, FlavorListener, FocusListener, HandshakeCompletedListener, HierarchyBoundsListener, HierarchyListener, HyperlinkListener, IIOReadProgressListener, IIOReadUpdateListener, IIOReadWarningListener, IIOWriteProgressListener, IIOWriteWarningListener, InputMethodListener, InternalFrameListener, ItemListener, KeyListener, LineListener, ListDataListener, ListSelectionListener, MenuDragMouseListener, MenuKeyListener, MenuListener, MetaEventListener, MouseInputListener, MouseListener, MouseMotionListener, MouseWheelListener, NamespaceChangeListener, NamingListener, NodeChangeListener, NotificationListener, ObjectChangeListener, PopupMenuListener, PreferenceChangeListener, PropertyChangeListener, RowSetListener, RowSorterListener, SSLSessionBindingListener, StatementEventListener, TableColumnModelListener, TableModelListener, TextListener, TreeExpansionListener, TreeModelListener, TreeSelectionListener, TreeWillExpandListener, UndoableEditListener, UnsolicitedNotificationListener, VetoableChangeListener, WindowFocusListener, WindowListener, and WindowStateListener.

Using closures removes the need to create all those different unique interfaces and worry about conflicts between them. This simplifies the library design, but also makes it easier for you as a consumer of that library. You don't have to remember or look up which interface to implement. You don't have to remember or look up whether you need to name your handler function actionPerformed or stateChanged. You don't have to create empty implementations of the parts of the interface you don't care about.

You just have to create a closure that takes the appropriate arguments, which are usually easy to make consistent throughout the system, and much of the time you don't even need those arguments because of the closure's context. It's a much smaller mental load.

Edit: I was not aware of C# delegates when I wrote the first part of my answer. They are unique to .Net (which I don't use), and most other libraries use full closures in the same situations as delegates. Languages that don't have closures usually implement an interface for each event type, which creates the naming problems I mentioned. Delegates solve that problem by enabling you to name your event handler whatever you want.

That being said, closures are generally a much more concise way to solve the same problem. They don't require the programmer to explicitly put their state into a class. They don't require their own names. They are encapsulated within the function where they are defined, and therefore very limited in scope, which makes it very easy to create as many as you need without worrying about conflicting with each other.

Just don't forget about principles like DRY. If you find yourself copying and pasting a closure, you should probably refactor it out so it is shareable and has a useful name.

share|improve this answer
1  
Hmm... Instead of all those classes, why not just have a Listener class that returns an object that can be cast to the proper class with a factory method? Or even a Listener<T>? –  Robert Harvey Apr 18 at 19:31
1  
Those are all interfaces, @Robert. You still would have the issue of needing to avoid name conflicts if you need to implement multiple handlers. How would you know what to name your handler functions? –  Karl Bielefeldt Apr 18 at 19:59
2  
Java has had closures since Java 1.1. (Inner classes close over their lexical environment.) That didn't stop the proliferation of SAM interfaces. What would have stopped them is a standardized interface such as .NET's Func. –  Jörg W Mittag Apr 18 at 20:04
1  
@KarlBielefeldt: .NET does it by passing the untyped object that's raising the event to the event handler. Most of those are derived from Control, but you can cast it to the correct class, if you know it (which you should, since you subscribed to the event). The handler events are generally named ControlName_EventName(object sender, EventArgs e). –  Robert Harvey Apr 18 at 20:06
2  
@KarlBielefeldt given your comment about research for delegates, I would think that site visitors would benefit if you edit what you learned into the answer –  gnat Apr 19 at 7:36

Maybe I don't understand closures fully but take for example C#, why would I use closures when I can use classes?

Are you really going to write a whole new class for every single .Where clause in your code? I mean you can do that, but using closures allows you to concisely write anonymous functions in the spot they're used.

share|improve this answer
    
Can you really do that? What does code look like that creates a class instead of closing over a variable? –  Steve Evers Apr 18 at 18:24
    
@SteveEvers - If I remember correctly, closures are directly translatable to classes as long as you can do ref, though they get real ugly, real quick. –  Telastyn Apr 18 at 18:31
    
When I google what closure is, I find lots of examples that makes me think it is not much different than using classes. I agree with your example even though it kind of in the syntactic side. –  mohican Apr 18 at 18:34

Not the answer you're looking for? Browse other questions tagged or ask your own question.