
Closures and Objects Are Equivalent - shawndumas
http://c2.com/cgi/wiki?ClosuresAndObjectsAreEquivalent
======
curtis
Just 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...

~~~
ScottBurson
The way I like to put it is that instances and closures are duals: a closure
can do exactly one thing, while an instance can, in general, do several
things. That's why, when invoking an instance, you have to supply a method
name that says which of the several things you want it to do, while when
invoking a closure no method name is necessary.

Of course it's not a hard-and-fast distinction: you can have a closure that
dispatches on one of its parameters to do one of several different things, and
you can have an instance with only one method. But it's usually valid.

~~~
jwmerrill
You can have several different functions that all close over the same state.
This situation is analogous to an object with several different methods.

~~~
mytochar
You can also do it over just one function that takes in a variable that
modifies behavior.

Imagine you have a closure with a function that takes in a string and a list
and returns a list. Depending on implementation of the function, you could
have the string be the operation you wish to perform. The method name, and the
list be the parameters. The returned list is the output.

Getters could pass an empty list and return a list with one entry

Setters could pass a list with a value and return an empty list

And so on :)

Like this:

    
    
       func NewClosure() func(string, ...float64) []float64 {
          x := float64(0)
          return func(method string, args ...float64) []float64 {
             if method == "setX" && len(args) > 0 {
                x = args[0]
                return nil
             } else if (method == "getX") {
                return []float64 { x }
             } else {
                panic("invalid method")
             }
          }
       }
    
       a := NewClosure()
       b := NewClosure()
    	
       a("setX", 50)
       b("setX", 12)
    	
       fmt.Printf("a.X = %v, b.X = %v", a("getX")[0], b("getX")[0])
    

Runnable example here:
[http://play.golang.org/p/68NTyEx6_P](http://play.golang.org/p/68NTyEx6_P)

I like it.

[edit: added working example .. and realized I'm adding to what my parent
poster was saying]

------
tel
Closures 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!

~~~
agumonkey
You need a term to distinguish non closing over closing functions, hence the
closure leakage. Or maybe HOF ?

~~~
tel
Functions 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
The use of 'closure' is an idiomatic shortcut to express that.

~~~
tel
Sort 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.

------
emillon
I 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
The spot I start to feel fuzzy, though, is if you start talking about higher-
level abstractions. E.g, are interfaces equivalent to type classes?

~~~
jerf
You 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
I 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.

~~~
jerf
The Monad type class is a pretty good test. Last I knew it wasn't properly
expressible in C# or Java either in the fully general sense, though you can
get closer than Go, certainly. Whether it gets close enough that you can call
it "done" is a bit of a judgment call; in the end, the semantics are never
quite _identical_ even in the best of cases.

------
detrino
A 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
That single closure function could return e.g. a map containing more functions
that share the same environment.

------
userbinator
Conceptually 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++.

------
jmount
Closures 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.

------
agumonkey
See 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
Wouldn'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.

------
ExpiredLink
... but this would eliminate huge amounts of internet discussions. We better
leave it as it is.

