On 2009-Oct-20, at 8:04 am, Jon Lang wrote:
The above example is of course trivial. A more serious example might be one based off of a coordinate system:

   role point {
       has Num $x, Num $y;
method angle() is rw( { $.x = .r * cos($_); $.y = .r * sin($_) } ) { return atn($.y/$.x) } method r() is rw( { $.x = $_ * cos(.angle); $.y = $_ * sin(.angle) } ) { return sqrt($.x * $.x + $.y * $.y ) }
   }

This strikes me as being much more readable than the current approach of explicitly returning a proxy object. I'd even be fine if the above were treated as syntactic sugar for the creation of a proxy object -

And/or some sugar for using special STORE methods on a variable, e.g.:

    has $angle is set { $.x = .r * cos($_); $.y = .r * sin($_) };

(Well, in this example that makes extra storage space for the $angle attribute which we don't actually want, but there are many cases where an easy way to override STORE is really what is useful rather than an lvalue sub.)

But one of the problems with lvalue subs that don't simply return a variable (or equivalently, my "is set" example) is that you can't say things like "temp lvalue()" unless "temp" is receiving an actual variable to work on.

In the case where angle() (or $.angle) is changing $.x and $.y, should trying to temporize it do "temp $.x" and "temp $.y" as well? Should it be impossible? Can Perl tell whether it should be impossible or not? Does it need to be illegal to change other variables inside a STORE?


Meanwhile, the flip side to wanting an easy way to do "is set" is that often when someone reaches for an lvalue sub, all he really wants is a way to pass an arg to the sub that looks like assignment. For example wanting "foo($x) = $y" to be a prettier way to write "foo($x, $y)". This could be handled by, say, having a special "rvalue" keyword in signatures, e.g.:

    sub foo($x, rvalue $y?) { ... }

    foo(42);         # $y is undef
    foo(42) = 24;    # $y is 24
    foo(42, 24);     # syntax error

This has the advantage of often doing what people want, and the disadvantage of not working with "temp", etc. At least Perl could know that "temp" isn't allowed to work with such subs, though. On the other hand, something that looks like an assignment ought to work like an assignment, including "temp"....

Especially since if you want something that looks more assignment-y than passing a regular arg, we already have a way to do that, namely, using the "==>" syntax to feed args into a slurpy parameter. But in your angle example, we really do want an assignment because the net result is to assign stuff. Perhaps "method angle is setting ($.x, $.y) ..." to indicate that whatever is done to "angle" should really affect $x and $y, and any other attributes that aren't specified may not be used.


-David

Reply via email to