Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!usc!elroy.jpl.nasa.gov!decwrl!asylum!osc!jgk From: jgk@osc.COM (Joe Keane) Newsgroups: comp.object Subject: Re: Closures in C++ Summary: Implementation is separate from semantics. Keywords: lambda Message-ID: <4690@osc.COM> Date: 27 Mar 91 03:06:50 GMT References: <4684@m5.COM> <1991Mar24.020701.27641@kestrel.edu> <4687@osc.COM> <1991Mar25.180147.5735@kestrel.edu> Reply-To: jgk@osc.COM (Joe Keane) Distribution: comp Organization: Versant Object Technology, Menlo Park, CA Lines: 52 In article <4687@osc.COM> i write: >But when someone says `an object is a closure', it's understood that the >operation to be performed on the object is the first argument to the closure. >So there's really no difference at all if you take this view. In article <1991Mar25.180147.5735@kestrel.edu> Gyro@Reasoning.COM writes: >That's true. But I don't take that view. I prefer to think of >operation dispatch as happening outside the object rather than inside >it. The problem with this is that it breaks encapsulation. You don't want callers to run arbitrary functions on your object. The whole point of having methods in a class definition is that those are the only functions which should be run on instances of that class. >Why? Only because some, though certainly not all, object-oriented >languages take the same view (C++, for instance [sorry]). Actually C++ makes a good example of what i'm talking about, because it makes some things explicit which other languages hide from you. An object with virtual methods contains a pointer to a virtual function table. This table has pointers to those functions which can be run on that object. It is true that with C++ virtual methods the caller does a table lookup to find the correct function to run. But surely this is just an implementation detail. You could write a generic function which works on an object of any actual class, by looking at this virtual table pointer and jumping to the appropriate specific function. But this would be silly, since the generic function is only the couple of instructions to do the table lookup. So it makes sense to inline it, and this is exactly what C++ virtual methods are. In C++ `virtual' on a method means roughly `the caller does the table lookup'. You can still have a non-virtual method which has different semantics depending on the actual class. For example, it can call other virtual methods. So really declaring a method virtual is only specifying which implementation you want to use. What about objects without any virtual methods? There's not really any conceptual difference, it's just that all the specific functions to be called are known at compile time. Therefore, there's no reason to store function pointers in the object, it can just be pure data. If the class has all attributes protected, then this doesn't violate encapsulation in any way. It's simply a different implementation technique. Structs are a special cases of this, data with no encapsulated methods. There's no protection on which functions can be called on a struct, besides the usual type-checking. We allow the user to access the attributes of the object directly, and we assume knows what he's doing. -- Joe Keane, functional C++ programmer