Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Re^5: Experimenting with Lvalue Subs

by TimToady (Parson)
on Jan 25, 2005 at 03:31 UTC ( #424780=note: print w/ replies, xml ) Need Help??


in reply to Re^4: Experimenting with Lvalue Subs
in thread Experimenting with Lvalue Subs

Would you also like:

$x->location++;
to Just Work? How 'bout:
my_increment($x->location);
presuming that the argument is declared rw. And what about:
$ref = \$x->location; $$ref++;
and such?

You've got yer blinders on if you think that's all just "language theory".

Though it's kind of nice to be accused of being a language theorist for a change. Usually I'm accused of sacrificing theory on the altar of practicality.


Comment on Re^5: Experimenting with Lvalue Subs
Select or Download Code
Re^6: Experimenting with Lvalue Subs
by BrowserUk (Pope) on Jan 25, 2005 at 04:03 UTC

    If any of those take the value of the attribute outside it's defined range, then no, I don't want it to "Just work". I want it to "Just NOT work".


    Examine what is said, not who speaks.
    Silence betokens consent.
    Love the truth but pardon error.

      If any of those take the value of the attribute outside it's defined range, then no, I don't want it to "Just work". I want it to "Just NOT work".

      Most of the time, this isn't needed. A normal variable $foo can have any value and I don't understand why instance variables should be different in this.

      Still, because value validation is a nice thing to have, tie with a STORE handler isn't a bad idea. But this shouldn't be specific to OO - the solution should apply to all variables. Our implementation, however, cheats by ignoring normal variables. This was easier :)

      sub foo : Property { $_ < 10 } main->foo = 9; main->foo++; # dies

      Perl 6 will provide a real solution, with a nice syntax even! In fact, more than one nice syntax!

      has $foo where { $_ < 10 };
      This extends to non-instance variables too. Just use "our" or "my" instead of "has".
      my $foo where { $_ < 10 }; $foo = 9; $foo++; # dies

      Juerd # { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }

        Be warned. This reply drifts way off the topic you raised/responded to. Sorry! Feel free to ignore it--not that you need me to tell you that :)

        Most of the time, this isn't needed. A normal variable $foo can have any value and I don't understand why instance variables should be different in this.

        I'm not sure that I agree with that. If the value of $foo comes from "outside" my program, and the use to which it is put requires that it be positive, then I am going to validate that it is. And I am going to validate it just after it receives it's value from that external source.

        I would like that same ability for lvalue subs. I'm sticking with the use of that term for a reason. The lvalue sub, may be a method tied directly to an attribute. But it may also be a completely transient value untied(sic) to any permanent attribute of the class which it is a part of, and used to effect some change of state of the object without being a directly accessed attribute.

        I hate giving examples, especially when related to OO things, because they always sound contrived, but I'll do it anyway. The one that springs to mind relates to a real test set by the US Navy I was reading about recently.

        The object is an instance of a TrackedObject class in a radar detection system. At some point, the radar detects a new contact and creates an instance to track it. Some time later, an ident (FriendOrFoe) is received from the object, and it is assigned to the object:

        $trackedObject->Ident = $ident;

        The ident itself (some alphanumeric code), isn't stored in the object. It could change anytime and is pretty meaningless except for the significance it carries. The ident must be verified against the current database of valid ident code for this day, this location etc. That means calling another system to get that verified, but before doing so, I must at least verify that it is of the right format for a valid ident.

        In order to get the proper verification (which will be responsible for marking this currently unknown object as freind or foe), I must also pass the current datetime, and the location of the ship or aircraft that is detecting it, and the heading of the contact.

        ... method Ident: lvalue { LVALUE{ my $ident }; reject( $ident ), return unless $ident =~ $RE_IDENT{$LOCATION}{$DATETIME}; $self->FreindOrFoe = ValidateIdent( $ident, $self->currentHeading, $LOCATION, $DATETIME ); } ...

        Yes. It is contrived, but it demonstrates 3 things;

        1. The lvalue method need not be attached to a permenant attribute.
        2. The validation can be complex. More complex than can easily be accomodated by any generalised trait mechanism. It can be very specific to this particular method.
        3. It can require reference to instance specific information, and global state.

          All this is available, by definition has to be available, right there at the point of validation directly after the lvalue is assigned.

        And that's the cruz of my argument. Everything, whatever that may be, required for validating the value assigned has to be available at the point of assignment. So why try and move it elsewhere?

        I sit down to code to this object--I look up the "attributes" available and see the one I want to assign to. If I want to know what values I should be assigning, if the docs are vague or non-existant, I should be able to go to the definition of the method and read what validation is done.

        I simple do not understand why it would be put anywhere else--except if it is technically infeasible. It isn't, so why not put it in the (to me:) obvious place?

        I realise that this is more a case of syntax that semantics (or is that the other way around? :), and I realise that there is a move in P6 to make as much as possible declarative rather than imperative, but I don't believe that everything can be done declaratively.

        Actually, the more time I spend thinking about it, the less likely do I think that much of the declarative stuff in P6 will get a lot of use. It (IMO) requires a style of programming, and a way of thinking, that I do not see fits with the tradition of Perl.

        In many ways, it requires much deeper "systems design" than P5, and detracts from the immediacy and the "rapid prototyping" way of working that I think is Perl's greatest strength.

        Time will tell on that one I guess.


        Examine what is said, not who speaks.
        Silence betokens consent.
        Love the truth but pardon error.
Re^6: Experimenting with Lvalue Subs
by demerphq (Chancellor) on Jan 25, 2005 at 09:19 UTC

    It seems to me that you are viewing :lvalues as a C programmer would, something that behaves as a piece of memory. Wheras most people here are viewing lvalues as a VB or Java programmer would: disguised method calls. Maybe the solution is to provide both? I sure would like to have a way for

    $obj->method=$foo;
    be the same as
    $obj->method($foo);

    It would be nice if Perl automagically made

    $obj->method++;

    be the same as

    $obj->method($obj->method()+1);

    But it wouldn't bother me too much if it didn't.

    The point here is that folk would be happy to forgo some of the more extreme uses of :lvalue subs like you and ysth post if they could just easily write validation code for the simpler cases. And we'd really like to do it in Perl 5. :-)

    UPDATE: This was discussed in the CB and there seemed to be some agreement that there is room for the souped up, can do anything :lvalue as well as a more constrained :assignable version that has much simpler semantics. In fact it seems to me that the :assignable version could probably be implemented with :lvalue and better callbacks once Perl 6 is around tested and stable.

    ---
    demerphq

      I sure would like to have a way for $obj->method=$foo; be the same as $obj->method($foo);

      Oh ... that just looks horrible. You're creating a syntax that has side-effects that aren't obvious from reading the code. Then again, the entire lvalue thing is ... it's just plain stupid, in my opinion. Function calls that, depending on if they're being assigned to, will behave one way or another. And, frankly, unless you bring a lot of outside knowledge to the table, you don't know which ones can do it and which ones can't.

      lvalue subs work in Javascript because Javascript is built to treat methods and attributes identically - it's a slot-based OO language like Self. And, I still have problems with the entire concept. It assumes that I, the programmer, don't need to know what is data and what is behavior. I may not want to know it at times, but I would certainly like to be able to know it, if I want to see the difference.

      Perl5 is not like Self. Perl5 is like C. Perl6 may be more like Self, in which case lvalue subs will be built into the language and they will work and they will work just fine. I have complete faith in Larry, Damian, et al that they will not screw this up. But, C does not have lvalue functions. C++ doesn't have lvalue functions.

      You know what - lvalue mutators just seem wrong to me. What's the client doing screwing around inside the object's internals? That's what lvalue mutators mean you to do ...

      Being right, does not endow the right to be rude; politeness costs nothing.
      Being unknowing, is not the same as being stupid.
      Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
      Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

        You're creating a syntax that has side-effects that aren't obvious from reading the code.

        I cant think of any situation where I want a user to be able to have set access to a property of my object and not have side effects. It seems a simple rule, if you are assigning to a method that there will probably be side effects.

        It seems to me that your expectations are completely in line with current :lvalue subs, do you find them useful? I certainly dont, and it seems to be a general consensus of folks who write a lot of perl that :lvalue subs as currently implemented dont solve a problem any of us need solved, wheras there seems to be a general consensus that such an equivelency as I mention is exactly what we want. To many of us it seems bizarre that VB and Java both provide easy ways to have validatable assignable methods and Perl doesnt.

        I think juerd has posted a number of examples of where such behaviour would be very useful indeed. Hopefully he will reply with a link.

        ---
        demerphq

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://424780]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (16)
As of 2014-10-30 13:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (208 votes), past polls