http://www.perlmonks.org?node_id=949240

PerlGrey has asked for the wisdom of the Perl Monks concerning the following question:

Consider this code:

# perl -MO=Concise -e '$s = "a" x 3'; 8 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v:{ ->3 7 <2> sassign vKS/2 ->8 5 <2> repeat[t2] sK/2 ->6 3 <$> const[PV "a"] s ->4 4 <$> const[IV 3] s ->5 - <1> ex-rv2sv sKRM*/1 ->7 6 <#> gvsv[*s] s ->7

compared to this:

# perl -MO=Concise -e '$s = "aaa"'; 6 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v:{ ->3 5 <2> sassign vKS/2 ->6 3 <$> const[PV "aaa"] s ->4 - <1> ex-rv2sv sKRM*/1 ->5 4 <#> gvsv[*s] s ->5

Why is "a" x 3 not considered a constant string by the compiler?

Replies are listed 'Best First'.
Re: Why is const x const not a const?
by moritz (Cardinal) on Jan 22, 2012 at 12:25 UTC

    I can think so several possible reasons:

    • If the repetition count is a big number, constant-folding the expression can take a lot of memory. Since the compiler can't know (in general) if a statement is ever executed, it is conservative not to evaluate it at compile time
    • It could be an omission
    • It might be not common enough operation for the compiler writers to care about optimizing it.
Re: Why is const x const not a const?
by JavaFan (Canon) on Jan 22, 2012 at 12:25 UTC
    Why is "a" x 3 not considered a constant string by the compiler?
    Because noone has written a patch to implement this optimization.

    Feel free to contribute.

Re: Why is const x const not a const?
by The Perlman (Scribe) on Jan 22, 2012 at 18:36 UTC
    I think for the same reason why the alias $_ is a read-only value here

     for (1,2,3) { }

    but not here

     for (1 .. 3) { }

    In the first case Perl (historically) tries to avoid the overhead to allocate a variable by pointing to the already existing literal in source code.

    At least thats what's happening in (e)Lisp, one of the languages which influenced Larry.

    Literals can only be constant since the source shouldn't be changed.

    The operators x and .. OTOH calculate the values, there are no source positions which can be used for optimization.

    I don't know if this optimization still makes sense, but I think it's at least the historical motivation.

Re: Why is const x const not a const?
by ikegami (Patriarch) on Jan 22, 2012 at 19:30 UTC

    Do you mean: why isn't constant-folding applied to x?

    It is odd that it doesn't. Maybe its weird «( EXPR ) x EXPR» syntax interferes? I doubt it, though. It was probably just overlooked.

      Hmm...

      seems like I misunderstood the question, but maybe constant-folding something like "a" x 100000 is not always efficient?

        Then why does «sprintf '%-100000s', 'a'» create a string of 100,000 characters at compile-time like «"a" x 100_000» currently does at run-time.

        And then there's 1..100_000 that creates an array and 100,000 scalars at compile-time.

        If something could fold into something that's considered too large, that particular folding should be prevented, not all foldings of that operator.

      Yes, that's what I meant. Just didn't know the term constant-folding. It's even more weird because
      use constant FOOBAR => "a" x 3;
      does what one expects. So the expression definitely can be evaluated at compile time.
        ...the expression definitely can be evaluated at compile time.

        Depends on how you define "compile time" :)

        The constant pragma implies a BEGIN block, which has its own compile and execution time — with the execution happening right after the BEGIN block has been compiled, but before the rest of the code is being parsed and compiled.

        In other words,

        use constant FOOBAR => "a" x 3;

        is roughly equivalent to

        BEGIN { my $x = "a" x 3; *::FOOBAR = sub () { $x } }

        And when you investigate it with B::Concise, you'll see that the opcodes in question have just moved to a different place and execution time, but they're still there:

        $ perl -MO=Concise,BEGIN,-main -e'use constant FOOBAR => "a" x 3; prin +t FOOBAR' | grep -C 3 '"a' 14 <$> const[PV "constant"] sM ->15 15 <$> const[PV "FOOBAR"] sM/BARE ->16 18 <2> repeat[t1] sKM/2 ->19 # <--- 16 <$> const[PV "a"] s ->17 # <--- 17 <$> const[IV 3] s ->18 # <--- 19 <$> method_named[PV "import"] ->1a BEGIN 5: -e syntax OK -- 4i <;> nextstate(main 102 -e:1) v:{ ->4j 4l <@> print vK ->4m 4j <0> pushmark s ->4k 4k <$> const[PV "aaa"] s ->4l

        The mechanism to define constants via Constant Functions is rather different from constant folding in the sense of 42+99 being replaced with 141 at compile time.

        Consider the following

        $ perl -MO=Concise -e'use constant FOOBAR => scalar <STDIN>; print FOO +BAR' abc 6 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 102 -e:1) v:{ ->3 5 <@> print vK ->6 3 <0> pushmark s ->4 4 <$> const[PV "abc\n"] s ->5 # <---

        Clearly, the value "abc" isn't part of the code, but entered via the keyboard at runtime (of the respective BEGIN block), yet it can be inlined as a constant in code sections compiled subsequently.

        So the expression definitely can be evaluated at compile time.

        Any expression can be evaluated at compile-time.

        use constant FOOBAR => time; say FOOBAR; sleep 2; say FOOBAR;
        1327438753 1327438753
Re: Why is const x const not a const?
by wilinsky (Initiate) on Jan 22, 2012 at 14:08 UTC

    I think its not considered a contant becasue it isn't a contant, Its a calculation that needs evaluating.

    While you could build optimisation into the compiler to calculate it and treat it as a constant, do you want to?. At what point to you stop?

    I think if you want a constant use a constant

      The original question isn't phrased very carefully, but it does have an interesting core.

      Perl has a "peephole optimizer" which evaluates some constant expressions at compile time. You can see that for example here:

      $ perl -c -wE '1+1; say "OH HAI"' Useless use of a constant (2) in void context at -e line 1. -e syntax OK

      Note that the -c switch means that the code is only compiled, not run. And yet the warning mentions 2 instead of 1+1, so you can see that the expression 1+1 has been evaluated at compile time, not at run time.

      The original question could thus be phrase "Why is the expresion "literal" x <literal_number> not constant-folded at compile time, as <literal_number> + <literal_number> is?"

      And yes, that's a valid and interesting question

      I think if you want a constant use a constant

      That's not very convincing. For example if I write '=' x 80, I see immediately that it's 80 equal signs. But if I write '===============================================================================', can you see immediately how many equal signs that are?

      The difference in readability is even larger when whitspaces are concerned, ' ' x 20 vs. '                    '. Imagine that being printed out on a sheet of paper. Which one do you find easier to decipher?

        That's not very convincing. For example if I write '=' x 80, I see immediately that it's 80 equal signs. But if I write ...

        You can do:

        use constant EQUALx80 => '=' x 80; ...

        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

        The start of some sanity?

Re: Why is const x const not a const?
by Anonymous Monk on Jan 22, 2012 at 09:58 UTC

    :D

    :D

    :D

    Because that is how its currently implemented :)

Re: Why is const x const not a const?
by Khen1950fx (Canon) on Jan 22, 2012 at 13:59 UTC

    Why is "a" x 3 not considered a constant string...?

    As I see it, "a" is a const with x signifying a repeat of 3. With that in mind, I went for a walk:
    #!/usr/bin/perl use strict; use warnings; use Data::Dumper::Concise; use B::Concise qw/ walk_output set_style_standard /; my $walker = B::Concise::compile('-concise', 'newFunc'); walk_output( \*STDOUT ); print Dumper ( $walker->() ); set_style_standard( 'terse' ); print Dumper ( $walker->() ); sub newFunc { my $s = 'a x 3'; }
    In other words, 'a' is the constant string, which seems like the right thing to me; however, 'a x 3' is a constant string. Use that instead.
      'a x 3' is a constant string. Use that instead.

      You are aware that the result of the expression 'a' x 3 is 'aaa'?


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

      The start of some sanity?