On Sep 26, 2005, at 6:04 PM, Neil Madden wrote:
Will Duquette wrote:
The point of [define] is simply that we want to be able to create objects which have a limited set of subcommands. Note that there's a distinct difference between writing an OO-API using a particular OO-framework for other users of that framework, and writing an object-style API for general users, many of whom might not care about the OO-framework at all. In the first case, you want to include all of the OO-framework's bells and whistles, because you expect your users to want to take advantage of them. In the latter case, you want to keep the API simple, clean, and easily documented.
That's certainly a good goal.
[define] lets us do both. With [define] "instproc" and its siblings aren't subcommands of our objects--but at the same time, "instproc" and its siblings are available to every user who cares about them.
OK. The essential thing being done here then is to break down the grab-bag of methods defined in Class and Object into a bunch of different interfaces, so that clients of an object don't have to worry about a bunch of extra "proc" and "filter" etc methods that have nothing to do with their problem domain. I can sympathise with that. However, I'm not sure [define] is the right solution, as it just creates another bag of methods elsewhere (somewhat like [info] has become). We could simply change the methods to be class- methods of [class] and [object] (i.e. procs that expect an explicit self argument, rather than instance-methods). That way by default objects don't get lots of public methods that aren't needed by clients, but you can still do, e.g.:
Actually, I don't mind [info]. Yes, it's a bag of methods; but it's nice to have a rug to sweep things under, and it's even nicer to know *which* rug without having to think too much about it.
My only argument against this notion of yours and in favor of [define] involves implementing oo::snit on top of oo::. snit::types have typemethods, and just as I want a clean interface for my objects, I'd like a clean interface for my types as well.
If we abolished [define] and defined its methods as you describe, then oo::snit types would no longer have a clean interface. I could work around that by using an oo::object as a proxy for an underlying oo::class; I'd give the oo::object a create method that forwarded to the class, and then make the oo::object forward any user-defined typemethods as well.
The difficulty here is that an oo::snit::type wouldn't be an oo::class, then. And that's a problem, because Snit's two big problems are speed and lack of inheritance. If I'm going to go to the trouble of reimplementing Snit on top of oo:: I'd like to get both.
Other than that, I could go with your scheme. I kind of like [define], though. But then, naturally, I would. :-)
Will
class method myclass someproc {args} { ... } object method myobj ... object mixin myobj ...
This also somewhat reduces the need for self.method/method (or instproc/proc) distinction. Likewise, you could also use it for the script-style of define:
class define myclass { method foo ... method bar ... }
where these are interpreted as [class method myclass ...] and not [object method myclass ...].
It sort of clashes with previous XOTcl usage, where [class instproc] means define an instproc on the object "class", but if we change the name to "method" anyway then this is less of an issue. You could even leave access to the methods using the form:
myclass class method someproc ... myobj object method ...
which leaves only one top-level method in objects (two in classes). That seems a bit more OO-y, but I don't know if it really adds much.
-- Neil
------------------------------------------------------------- will -at- wjduquette.com | Catch our weblog, http://foothills.wjduquette.com | The View from the Foothills