Re: Closures versus objects

Robbert Haarman <[email protected]>
Newsgroups gmane.comp.lang.lightweight
Message-ID <[email protected]>
On Thu, Feb 15, 2007 at 11:13:36AM -0800, Mike Newhall wrote:
> 
> 	If the main use of closures is to associate data with code, and 
> 	the mechanism of capturing the lexical context is merely a means 
> 	to an end, then "closure-like" objects are possible even in 
> 	languages with no concept of capturing the stack.

Indeed, both closures and objects allow the association of data with 
functions (AKA methods), so that this data does not have to be passed as 
arguments each time the function is called, nor reside in a global 
binding. Besides reducing clutter in the rest of the program, this also 
ensures that there exists a reference to the data as long as there 
exists a reference to the function.

As far as capturing the stack is concerned, this is not necessarily 
something closures do and objects don't. For example, in Java, anonymous 
inner classes can refer to bindings in the environment in which they 
were created - as long as these bindings are declared final (i.e. they 
are constant).

> 	Nevertheless closures would seem to have the edge when you need 
> 	something that behaves exactly like a function.  But some OO 
> 	languages allow you to invoke an object with function-like 
> 	syntax.  In C++, this is merely syntactic sugar, but there's no 
> 	reason a language couldn't be designed to allow objects to be 
> 	invoked in a way semantically identical to functions (ignoring 
> 	CLOS generics for the moment, surely some OO languages already 
> 	do this; Python?  JavaScript?), invoking some default method.  
> 	This equivalence can break down however when, for example, an 
> 	external entity like the OS requires a callback function, and 
> 	the semantics of invoking the callback are outside the playpen 
> 	where this equivalence is implemented, so that only true 
> 	closures would work in the context.  But this could be said of 
> 	many language features.  It's of particular concern in the C++ 
> 	world where C calling conventions for OS callbacks are the norm 
> 	and object invocation is not an option.  (For that matter, any 
> 	language with closures attempting to use a C callback has to 
> 	solve this problem.)

Exactly.

> 	Objects would seem to have the edge when you want the 
> 	relationship between functions that share state to be explicit 
> 	both syntactically and in the language.

Couldn't you accomplish the same by replacing the object with a closure 
that takes a "function identifier" as its first argument? E.g., in 
OCaml:

let make_pair x y = function
	  `Car -> x
	| `Cdr -> y

let p = make_pair 1 2

p `Car (* returns 1 *)
p `Cdr (* returns 2 *)

>       This may be necessary
> 	to enforce inheritance & access rules and so on.

To me, inheritance is the winning feature of many object systems. If you 
can make inheritance elegant and efficient using closures, I don't know 
why pou would need a separate object system baked into the language.

>       Also it would 
> 	seem that if everyone rolled their own OO system with closures 
> 	they would inevitably be incompatible, although a standard 
> 	library might obviate that.

Yes, and then I would even argue that the (supposed) possibility of 
everyone rolling their own object systems is a Good Thing, because it 
allows better (in general or for specific tasks) object systems to be 
developed in time.

> 	Or could closures and objects be unified into a single datum, 
> 	such that foo() invokes "the" closure function but foo.method() 
> 	invokes other functions sharing the same state?  (This is the 
> 	same semantics suggested above but with the extension that 
> 	lexical closures do exist in the language, and any time a 
> 	closure is captured, it generates an object indistinguishable 
> 	from those produced by constructors.)

I am sure that could be done. However, is it useful?

> 	As a perhaps separate thought, what are closures useful for?  

Well, really, for passing to higher order functions. Someone already 
mentioned mapcar, but I would like to make specific mention of 
callbacks, as well. If you've ever done callbacks with anonymous (or 
even named) classes in Java, you will have noticed how clumsy it is. As 
far as I can tell, closures do not make things possible that couldn't be 
accomplished another way, but they make certain things much more 
elegant.

Regards,

Bob

-- 
"Common sense is not so common."
signature.asc (application/pgp-signature, 189 B)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (GNU/Linux)

iD8DBQFF1OOafb9wcmD+WN4RAshbAKCqooY7pSKmGsuNia8rqFBwwyljiACfZjih
E8NK1A+U2dtCCeeHvdop7tI=
=3+pr
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.