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

The generator sure could do this for the programmer; I'm also pretty sure we will see idioms akin to Perl5's AUTOLOAD+eval on-the-fly generation of accesors soon after Perl6 enters the stage. It doesn't seem like something that must be solved on the language level, provided the knobs and dials are there to do this in streamlined fashion from the source end. And what I've read so far makes me hopeful that this will be the case.

“Proxying” the sub (I think that's the wrong term) as you show is probably fine for trivial cases, but somehow it doesn't feel to me like you'll get far with that if the sub does anything even remotely complex.

Makeshifts last the longest.

Replies are listed 'Best First'.
Re^13: Experimenting with Lvalue Subs
by BrowserUk (Patriarch) on Jan 25, 2005 at 10:44 UTC

    I'm simply saying that every time the desirability of the syntactic sugar of Lvalue subs comes up, in the vast majority of the responses, the inability to validate the assignment, is cited as the primary reasons people do not code their subs in that fashion. And that P5 reality should play some part in what becomes the P6 reality.

    The technique of tieing the attributes in order to provide for verification has been muted over and over--and reject by most, over and over. In part because of the performance hit this entails. In part because applying that technique to every attribute of every class, either manually or through a generator module adds complexity that many feel outweights the advantage of the syntactic sugar.

    I'm saying that the requirement to validate is so important (based on the overwelming strength of arguments here), that it should be codified into the language and provided by the language. If it can be done by the Perl programmer, it can be done by the code generator in a standardized manner that simplifies the life of every programmer writing classes--which in P6 is going to be nearly every programmer, nearly every time.

    “Proxying” the sub (I think that's the wrong term) as you show is probably fine for trivial cases, but somehow it doesn't feel to me like you'll get far with that if the sub does anything even remotely complex.

    Given the current design, the sub cannot do anything complex--only return an lvalue. Not even validate the value assigned to that lvalue.

    Using a localised "stand-in" (proxy seems as accurate a term as any?), for the sub, means that the sub doesn't get called to do anything, unless the temporised value is finally 'realised' into becoming the permanent value.

    Cheap, and efficient.

    More efficient that calling the real sub in order to obtain a reference and localising that--especially if that sub does anything complex to obtain the value--like hitting the database with a long running query to retrieve the current value. Effort that would be entirely wasted if the value is going to be overwritten. Doubly so if the reference is going to be temporised and undone, and ultimately the value is never changed.

    I'm saying that if the ability to temporise lvalue subs ,is the only reason for not allowing lvalue subs--by default, every mutator in every class in p6--to validate their assigments, then the mechanism I threw together above demonstrates that there is a simple, efficient alternative that could be transparently put in place by P6 itself that would negate that reason.

    Better to temporise the sub transparently, on those (rare?) occasions where that is required, than force every programmer to tie every attribute of every class (whether through a module or not).

    Let's face it. If we are forced to do the validation by employing a tie class, then we will rapidly get a Params::Validate::General...and a Params::Validate::Long...and a Params::Validate::(Short|Quick|Easy|Better|Formal|Clever) et al.

    I'm saying that if the ability to temporise the lvalue is not the only reason for preventing classes from validating values assigned to their attributes, then whatever that other reason is--bring it out in the open and show us what has such a high priority that it overides the need to validate?


    Examine what is said, not who speaks.
    Silence betokens consent.
    Love the truth but pardon error.
      Please take no offense; I understand that you see a real gap in what perl allows, but from my point of view, you want to highjack the existing mechanism to allow subs that can act like the substr builtin in order to provide quite different (and non-compatible) functionality.

      I'm not sure I can sum up what's wanted from the existing :lvalue better than "subs that can do what substr does", and I have not been able to figure out what you mean by "temporise". Does that come even close to answering your question?

        None taken.

        You are not the first to suggest that I am looking for something different and incompatible. I say that I am not. I want everything that an lvalue sub or method has now in p5 (actually more as I would like for list context lvalue subs to work properly). The only difference is that I would like to be able to validate the assignment.

        One of the reasons given for why the this is not possible without resorting to callbacks in the form of a tie, is that it would make localising (temporising) lvalue subs difficult or impossible.

        The term "temporise", and all discussion relating to it, comes directly from Apocalypse 6.

        But in particular, note that we want to be able to temporize object attributes, which is why there's a TEMP method in our proxy. In Perl 5 you could only temporize (localize) variables. But we want accessors to be usable exactly as if they were variables, which implies that temporization is part of the interface. When you use a temp or let context specifier:

        temp $obj.foo = 42; let $obj.bar = 43;

        the proxy attribute returned by the lvalue method needs to know how to temporize the value. More precisely, it needs to know how to restore the old value at the end of the dynamic scope.

        All I did was fall in line with the terminology used there.

        It was suggested that the ability to localise (temporise) an lvalue sub for a scoped duration was one reason why if any validation was allowed for lvalue subs, it would have to be done as a callback (via tie or similar).

        The post to which you replied and it's predecessor describe my suggestion that it would be better to localise the sub itself and a temporary lvalue, rather than the actual lvalue returned by the sub.

        In terms of the above snippet, the value assigned in temp $obj.foo = 42; would be "undone" at the end of the scope. In this case, by temporising the sub rather than fetching real lvalue, the end of scope would simply discard the temporary value assigned.

        The only time the real sub would get called is if the temporary value is made real as in the let $obj.bar = 43;

        Assuming I've understood the terminiology. FWIW: I now see the flaw in this suggestion.


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