On Sun, Feb 24, 2008 at 04:23:54PM +0000, Andy Armstrong wrote:
> I've wanted this often. I've also wanted a clean way to lexically supply a 
> default target object. For example with HTML::Tiny you often write
>  my $h = HTML::Tiny->new();
>  $h->body($h->head($h->title('FooPage')), $h->body(...));
> I'd love to be able to drop the '$h->' everywhere. Like this:
>  $h->body( head( title( 'FooPage' ) ), body( ... ) );
> I guess that would/could be a related mechanism.

In Perl 6 you can at least get it down the minimalistic indication
of a method vs function:

    given $h {
      .body( .head( .title( 'FooPage' ) ), .body( ... ) );

That can be construed as clean in a way that a functional interface
with an implicit object could not.  P6 is big on distinguishing
method calls from function calls *because* of wanting to distinguish
object-centric single dispatch from function-based multiple dispatch
(including all operator dispatch) which, by the way, is generally
controlled lexically in P6, as the OP suggests.  (It's also used in
the global (or more like super-lexical) Prelude scope by the compiler
to define the base language each compilation unit starts in.)
So we're ahead of you there...  :)

Basically anything that could be construed as language mutation is
limited lexically in P6, and mixing in user-defined multimethods can
be construed as at least semantic mutation, and is also syntactic
mutation if you define new operators rather than merely overloading
existing ones.  (We have a bias toward new operators for different
semantics, also suggested in the OP.  There's lots of Unicode operators
available, I hear...)

But back to .body etc.  To go further than that without the cooperation
of the class, you'd have to curry the invocant on a class, currently
described as something like:

    (use HTML::Tiny).assuming(:self(HTML::Tiny.new()));

which would presumably import all the methods as functions, give
or take the fact that that syntax would not intrinsically indicate
the desire to import anything, which is a problem.  It is probably
a common enough operation to give a shortcut to:

    use HTML::Tiny :singleton;

or some such, which would automatically run new, curry all the methods
on the invocant, install those resulting functions under the singleton tag
as marked for export, then import them as you would any other tag.  Then
your call reduces to:

    body( head( title( 'FooPage' ) ), body( ... ) );

But as I just described it, if you wanted to use another singleton in
a different scope, you'd end up clobbering singleton tag, so really
you want to treat that as an anonymous tag somehow.  (Import tags
are really just subpackages in P6, so an anonymous temporary subpackage
is likely not a problem.)  Then you wouldn't have colliding curries,
and the exporting module doesn't have to be aware of who is importing
from it, which is pretty bogus when you think about it.

Presumably the HTML::Tiny protoobject can then be queried for its
singleton object if you really need to have $h for some reason.


Reply via email to