Since a class is just a module, this already cleanly falls out of the concept of currying modules, as described in S06. There it gives the example of:
(use IO::Logging).assuming(logfile => ".log");
So you can also presumably curry the invocants of all the methods:
constant $defobj = ...;
(use Some::Class).assuming($defobj:);
Note however that this is much better than merely forcing the class to carry its own default object. Instead, we encourage the user module to declare its own default object and use that, which means that different modules can have different default objects, each lexically scoped to its own module. You can still have a global default object if you like, but all the modules that want to use that global default object will have to explicitly declare that that is what they want, rather than being forced to share whether they want to or not.
The particular syntax given above is a bit problematic in several ways, but even if the syntax changes, the principle will remain that you'll be able to use some form of currying to supply an aliased view of a module or class, and that mechanism will certainly allow you to curry the invocants of a class, essentially turning a class of methods into a module of subs that assume the curried invocant.
In any case, this is not a terribly new idea: the currying of classes into modules was already explicitly mentioned in A06 back in 2003. | [reply] [d/l] [select] |
| [reply] [d/l] [select] |
If you only want to curry some of the methods into subs, you can always fall back on function currying, the syntax of which is run-time-ish, so how you pick the functions to curry and how you then bind the new functions to names is external to the curry itself. It would still be possible to hook this into the "use" apparatus, since that has built-in the notion that it is constructing a view of something elsewhere, so a module that you think of as Foo can be a version of Bar with all the names and arguments messed around with.
As for having to repeat the class name, yes, that's currently an issue, particularly since you have to declare the type of your $defobj before the use. But I think I mentioned the current syntax is still negotiable, and would certainly be open to suggestions for syntax that is both composable and succinct. We could go as far as to have a variant usesingle that autocurries a singleton, but then we have to decide how it composes with the filters you also requested above, and where the singleton object ends up getting stored, if it's to have some kind of user-accessible name. For composability there are times you might want to return the singleton, and times you might want to return the class's protoobject. It's difficult to do both of those simultaneously.
| [reply] [d/l] [select] |
| [reply] |
But the advantage of functional programming is that there are no side effects - this simplifies reasoning about the program. If there is an implicit object that 'receives' all the operations then it would also receive the side effects wouldn't it? Or perhaps I don't get your proposal. | [reply] |
| [reply] |