9 ms·
Closures and Objects Are Equivalent
- tel 12y agoClosures are an implementation technique and objects a semantics. To equate them is to confuse implementation and interface. (Functions + tuples + recursion) is powerful enough to embed objects very nicely though!
- jonahx 12y agohi tel, would you mind elaborating on what you mean by "objects [are] a semantics"?
- kd0amg 12y agoA closure is a data structure commonly used to represent a first-class function (containing a function pointer for the code and some sort of structure mapping the environment's bound variables to their values). Implementing a language with first-class functions does not require using closures. You could have an interpreter that performs beta reduction on the syntax tree, and first-class functions would still behave the same way. So closures are an implementation detail. In OOP, there are pieces of data that have operations associated with them. Two objects are free to have their own "version" of the same operation (same-named), and when you invoke it on an object, you get that object's version. In writing one of those operations, you have a handle on the thing you're operating on without having to take it as an argument. This specifies what result you'll compute and what side effects you'll cause by invoking an operation (i.e., the semantics). It does not specify things like where in program memory the code for that operation will live or how invoking it will work (implementation).
- agumonkey 12y agoYou need a term to distinguish non closing over closing functions, hence the closure leakage. Or maybe HOF ?
- deleted 12y ago[deleted]
- tel 12y agoFunctions that don't "close over the environment" are ones that are defined in the null environment. Normally you have Gamma, x : a |- e : b -------------------------- Gamma |- \x -> e : b But you could also have "bare functions" if you liked x : a |- e : b ---------------------- . |- \x -> e : b This would force all names to be explicitly applied, I think.
- agumonkey 12y agoThe use of 'closure' is an idiomatic shortcut to express that.
- tel 12y agoSort of. It's also a didactic method to talk about it and it often is quickly followed with people talking about stack pointers or environment frames. You can blur the lines if you like, but I find it tends to pay to be precise here.
- ExpiredLink 12y ago... but this would eliminate huge amounts of internet discussions. We better leave it as it is.
- emillon 12y agoI like to see this as a sort of duality: closures are objects that have a single method (call) and objects are made of functions that can only capture one variable (this).
- bunderbunder 12y agoThe spot I start to feel fuzzy, though, is if you start talking about higher-level abstractions. E.g, are interfaces equivalent to type classes?
- TheLoneWolfling 12y agoDepends if you have multiple inheritance.
- noblethrasher 12y agoInterfaces—at least in C#/Java—are equivalent to product types; they let you express the notion of conjunction within the type system. Similarly, “implementation inheritance” (where every class is either sealed/final or abstract) is how we express sum types. We can simulate type classes in C# by using implicit casts to abstract classes (interestingly, it’s not so straightforward to simulate the awesomeness of type classes in F#). The key to all of this is to realize that “types” and “classes” are not equivalent, even though C# and Java conflate them.
- jerf 12y agoYou have to specify the language; there's no (useful) definition of type classes and interfaces outside of the context of a specific language that is specific enough to make reliable comparisons. If you mean "Are Haskell type classes equivalent to Go interfaces?", the answer is no, Haskell type classes are substantially more powerful, even before you start turning on extensions. For instance, "Go" can not express the Monad typeclass at all.
- bunderbunder 12y agoI was more thinking Haskell type classes vs. C# or Java interfaces. They're a bit more powerful than Go interfaces because they can be used in combination with generics.
- jmount 12y agoClosures are used as objects quite a lot in R, as the standard structures are all actually immutable (to first order the only common user facing mutable things in R are variable bindings / environments, there are reference classes like RC and R6 but they are not considered core language). A lot of R users may not know this as value mutability is simulated through aggressive variable re-binding.
- deleted 12y ago[deleted]
- userbinator 12y agoConceptually they're both just a combination of some data and code that (usually) makes use of that data. I think a great example of this is function objects in C++.
- curtis 12y agoJust reading the submission title instantly reminded me of "Anton van Straaten's Koan", and for good reason -- it's quoted in the submitted page, and indeed makes up the first 3 paragraphs. Here it is: The venerable master Qc Na was walking with his student, Anton. Hoping to prompt the master into a discussion, Anton said "Master, I have heard that objects are a very good thing - is this true?" Qc Na looked pityingly at his student and replied, "Foolish pupil - objects are merely a poor man's closures." Chastised, Anton took his leave from his master and returned to his cell, intent on studying closures. He carefully read the entire "Lambda: The Ultimate..." series of papers and its cousins, and implemented a small Scheme interpreter with a closure-based object system. He learned much, and looked forward to informing his master of his progress. On his next walk with Qc Na, Anton attempted to impress his master by saying "Master, I have diligently studied the matter, and now understand that objects are truly a poor man's closures." Qc Na responded by hitting Anton with his stick, saying "When will you learn? Closures are a poor man's object." At that moment, Anton became enlightened. Now I will be the first to admit that I usually just don't get koans. But I think I get this one. Objects and closures are equivalent in the sense that what you can do with one you can do with the other. However, for each particular case one may be better (easier to use, more natural, whatever) than the other. You should use which ever one is the best for each particular problem. This is of course easier if you are using a programming language that natively supports both closures and objects...
- zzzcpan 12y agoThey are not exactly equivalent though. It is not possible to completely abstract away state changes with objects. You always end up with at least two calls that you have to keep track of.
- tel 12y agoI'm not sure that I would agree here. Do you have a simple example?
- zzzcpan 12y agofoo.DoSomething() ... // remember not to return // without foo.Done() called // (EDITed for clarity: // foo is the state, that changes, // so you have to keep track of // its changes) foo.Done() vs DoSomething (func(){ ... // don't have to remember // a thing, no side-effects, // equivalent of .Done() is // called afterwards for you }) EDIT2: exact behavior is not the point, keeping track of things is.
- agumonkey 12y agoSee Kiselyov fp-oo relation ML thread http://okmij.org/ftp/Scheme/oop-in-fp.txt http://okmij.org/ftp/Scheme/oop-in-fp.txt
- dorfsmay 12y agoWouldn't closure be more like a single-method-objectin a class that has no class methods? A clojure carries its own states (variables) that it, only, can modify. While the states (variables) of an object can be changed by another method for the same object, or by a class method, or even methods from another object if it uses method variables.
- detrino 12y agoA closure is 1 function and an environment. An object is N functions and an environment. Objects are more useful as you don't need to repeat the environment to implement more than 1 operation. Both objects and closures can be type erased so that the environment is not part of their type.
- jusssi 12y agoThat single closure function could return e.g. a map containing more functions that share the same environment.
- deleted 12y ago[deleted]