Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Re: Doing "it" only once

by QM (Parson)
on Sep 22, 2005 at 13:47 UTC ( [id://494113]=note: print w/replies, xml ) Need Help??


in reply to Doing "it" only once

In my frenzy to chase down novel (to me) ideas, I neglected to comment on L~R's main point, which I'll immodestly restate as:
What if Perl had a language construct for "Do this only once"?
(We can argue about whether this should be "once" or "N times".)

The core idea is once the test fails, it's removed from the optree.

What would we use for syntax?

once (/foo/) { print "I've seen foo\n"; }
or more often
once (my $i;/foo/;$i++ < 42) { print "I've seen foo $i times\n"; }
Would it be useful? It seems it's only merit is in speeding up tight loops, where even checking a boolean is noticeable.

Would it cause bugs? Yes, definitely. There would be a cargo cult of "Use once to optimize conditionals", when very few situations actually benefit from it.

Is it more convenient than anything existing? Yes, indeed. I have yet to see anything that approaches the efficiency of once.

I'll be interested in seeing if this idea catches fire, implemented, and how many bugs it generates.

-QM
--
Quantum Mechanics: The dreams stuff is made of

Replies are listed 'Best First'.
Re^2: Doing "it" only once
by diotalevi (Canon) on Sep 22, 2005 at 14:15 UTC

    If you rework this as actual perl code, its even possible to do today, with no changes to the perl parser. Really though, Limbic~Region should just be using lisp if he wants to have such flexibility. If this is too much overhead, the ifonce() function could be inlined like I described in my other node.

    sub ifonce { my ( $test, $block, $else ) = @_; if ( $test->() ) { $block->(); # Perform the appropriate B magic to remove this function call + from execution. } else { $else->(); } }
      diotalevi,
      I never said I was for or against this functionality, but why shouldn't it be considered for inclusion in Perl6? While I have already had this conversation with you in the Chatterbox, I believe it is worth repeating here for the sake of others.

      The meditation is about the possibility of Perl6 having the ability to modify the optree (or its equivalent) while it is running as core functionality and what you would do with it if it were available. The majority of the monks have missed this because they apparently focused on the code and didn't bother reading the commentary.

      You have stressed that you think I should learn Lisp before asking such questions and I would argue that you should read what I wrote and not assume to know what I was musing about. I respect you and your abilities a great deal, but I am probably going to come off sounding like a jerk. Regardless of our differences in opinion - thank you for your contributions.

      I know that there are many ways of achieving the same functionality currently and even included an example. Perhaps that was my downfall. People have been so eager to point out more ways or to recommend using another language that they have failed to see the forest through the trees.

      I was taught in school that the final paragraph should always bring the point you are trying to make home. I think I did that and have no explanation as to why so many people missed it.

      Cheers - L~R

        I was taught in school that the final paragraph should always bring the point you are trying to make home. I think I did that and have no explanation as to why so many people missed it.
        That's artificial, i.e., not a valid expectation in most contexts, including this one. You were expecting everyone to read all the way through - some do, and some don't. Sometimes your first sentence will generate an idea in my head that has to be followed now, before the shine wears off.

        On the other hand, I'd hazard that some of the "misplaced" responses are due to the respondents' lack of Perl6- or optree-fu, and they replied according to their own experience.

        Your acceptance of all well-intentioned responses, and gentle prodding in the direction of interest, has already resulted in more on-target replies.

        -QM
        --
        Quantum Mechanics: The dreams stuff is made of

Re^2: Doing "it" only once
by Anonymous Monk on Sep 22, 2005 at 15:35 UTC
    The keyword 'once' is very misleading. We're talking about optimizing away checking of a conditional - but it's not true that this conditional is checked only once. It continues to be checked (and needs to be checked) until it happens to be true.

    Perl6 will have a FIRST block, meaning the block will be executed only once, and to be specific, the first time the surrounding block was entered. If you write this:

    while (...) { if (/foo/) { FIRST {...; next} } ... }
    and perl can determine there are no side-effects in the conditional, perl could be made to optimize away the conditional once it was true once.

    Having said that, the original problem isn't clearly defined. Suppose there would be this 'once-only if', what should the following print:

    my @list = qw /foo bar foo/; for my $x (1, 2) { for (@list) { if (/foo/) { # Assume a 'once-only if' print "foo"; } } }
    Should it print 'foo' once, or twice? That is, is the "once-only" a property of the enclosing loop, to be reset when that loop is reentered, or a property of the condition itself, meaning that after it became true once, it will never be true in the life-time of the program?
      That is, is the "once-only" a property of the enclosing loop, to be reset when that loop is reentered, or a property of the condition itself, meaning that after it became true once, it will never be true in the life-time of the program?
      Good point. I wonder if we could make a parallel with the our/my distinction, such that a my once would reset each time the enclosing block is entered, but our once would not? Or perhaps some sort of reset operator, along with labels, to reset a once conditional.

      Seems to be a lot of possible paths there. We should probably agree on the fundamental property first. I see a few choices:

      1) a conditional, once true, never tested again
      2) a block, once entered, never entered again (including testing for any attached condition).
      3) a statement modifier, indicating the attached block will only be executed once.

      And then further choices about whether it's resettable, and the reset mechanism. [I can imagine taking the language duality of "once" as eleven in spanish, and having it context or parameter sensitive. If it's true 1 time, it's pronounced "wuns", if it's reset, it's pronounced "on-say".]

      Lots of potential. Still, is it useful? Is it practical? Or is it just cool?

      Update: Clarified (2) to be more general than (1).

      -QM
      --
      Quantum Mechanics: The dreams stuff is made of

        2) a block, once entered, never entered again (including testing for the attached condition).

        Point 2 raises some questions. You talk about an attached condition. If you only talk about blocks with an attached condition, what's the difference between 1) and 2)?

        Also, suppose you had a 'once-only' construct, what should the following do:

        for (1 .. 4) { if ($_ % 2) {print "odd"} # Assume 'once only blocks' else {print "even"} }
        Should it print "odd even even even"? But then, the else block isn't "once only". Print "odd even"? But then the conditional is still checked after being true once. Should it just print "odd"? That would violate the principle of least surprise.

        Lots of potential. Still, is it useful? Is it practical? Or is it just cool?

        Well, you (sort of) can do this in Perl6. Perl6 has FIRST blocks, which will be executed the first time the surrounding block is entered. So, effectively, you can make a "executed only once" block this way:

        { FIRST { ... } }
        that is, have nothing in the block, except a FIRST sub-block. However, that will not prevent a conditional from being executed.

        But in my opinion, the frequency of such construct isn't high enough for the extra syntactical sugar (and the subsequent pain when reset mechanisms need to be bolted on). It's really easy to simulate:

        my $flag = 1; ... if ($flag && CONDITION) { $flag = 0; ... }
        The then block will be executed only once, but it the programmer has an very easy mechanism to reset the 'once only' property. And depending on the scope of the flag, it's a 'once-only in the life time of the program' or 'once-only for each time the surrounding block was entered'. Or anything in between.

        Sure, there's the slight overhead of an extra 'if (0 && ...)' - but if your program can't deal with that, and there's nothing else to be optimized, you probably shouldn't have used Perl in the first place.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (4)
As of 2024-04-19 00:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found