in reply to Re^10: chopping a string into slices - is there a more elegant way to do it?
in thread chopping a string into slices - is there a more elegant way to do it?

it's alway the same "="

No, there are two different "=" operators, the scalar assignment operator (sassign) and the list assignment operator (aassign)

>perl -MO=Concise -e"$a=1" 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[IV 1] s ->4 - <1> ex-rv2sv sKRM*/1 ->5 4 <#> gvsv[*a] s ->5 -e syntax OK >perl -MO=Concise -e"($a)=1" 8 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v ->3 7 <2> aassign[t2] vKS ->8 <-- - <1> ex-list lK ->5 3 <0> pushmark s ->4 4 <$> const[IV 1] s ->5 - <1> ex-list lK ->7 5 <0> pushmark s ->6 - <1> ex-rv2sv sKPRM*/1 ->- 6 <#> gvsv[*a] s ->7 -e syntax OK

ssassign evaluates its RHS in scalar context, then evaluates its LHS in scalar context, then performs the assignment, then returns the value returned by the RHS.

asassign evaluates its RHS in list context, then evaluates its LHS in list context, then performs the assignment, then returns either the value returned by the RHS (in list context) or the number of scalars returned by the RHS (in scalar context).

>perl -le"print( scalar( $a=5 ) );" 5 >perl -le"print( scalar( ($a)=5 ) );" 1

If not please show me code that showes that ($a) is not a list.

I didn't say it wasn't. The list assignment operator forces its arguments to be lists. For example, there are two lists in @a = 4.

>perl -MO=Concise -e"@a=4" 9 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v ->3 8 <2> aassign[t3] vKS ->9 - <1> ex-list lK ->5 <--- 3 <0> pushmark s ->4 4 <$> const[IV 4] s ->5 - <1> ex-list lK ->8 <--- 5 <0> pushmark s ->6 7 <1> rv2av[t2] lKRM*/1 ->8 6 <#> gv[*a] s ->7 -e syntax OK

Notice how the LHS is a list even though there's no parens? You're confusing cause and effect.
"($a)" is a list because "=" is a list assignment operator.
"=" being a list assignment operator isn't caused by "($a)" being a list.

The parens only *indirectly* causes the change in context.

Replies are listed 'Best First'.
Re^12: chopping a string into slices - is there a more elegant way to do it?
by LanX (Saint) on Dec 01, 2008 at 12:27 UTC
    Notice how the LHS is a list even though there's no parens? You're confusing cause and effect. "($a)" is a list because "=" is a list assignment operator. "=" being a list assignment operator isn't caused by "($a)" being a list.

    I have no doubt that the implementation on the opcode-level is differently done, BUT I'm arguing you can tell on the perl-level!

    Do you know any perlcode, where () and (1,2) reacts as a list and (1) does not???

    My thesis is that the implemantation is transparent in this aspect and one can easily say ($a) is a one element list to a "normal" perl programmer! Can you find any contradictory perl code? I can't!

    Like in physics the easiest model is always preferable as long as you can't get to the extreme borders.

    For instance as long as Bohr's Model predicts all experiments in your laboratory it's a sufficient model, no matter how complicated the underlying Quantum Mechanics are.

    In other words: Normal Perl programmers don't need to see the matrix, Neo! 8 ) Or do you know an example where the matrix effects normal live??? I'm really eager to know ...

    Cheers Rolf

      Do you know any perlcode, where () and (1,2) reacts as a list and (1) does not???

      My point is that parens have nothing to do with it, so I'm not sure what you are trying to prove.

      Do you know any perlcode where 1,2 reacts as a list and 1 does not?

        > so I'm not sure what you are trying to prove.

        I'm trying to find a resonable simple model to understand perl's syntax!

        Thumbrules which are alway true!

        Kind of "Ducktyping" where the opcode details do not matter!

        With other words: Do you really want to tell a beginner that parens on LHS make "=" act like aassign instead of sassign???

        do you understand me now?

        Cheers Rolf

Re^12: chopping a string into slices - is there a more elegant way to do it?
by gwadej (Chaplain) on Dec 01, 2008 at 02:31 UTC

    This is great. Okay, I believe I see your point more clearly.

    You're basically saying that the list assignment is chosen because at compile-time the LHS is recognized as a list. Context is a run-time issue, so that is a completely separate thing and can't influence which assignment we pick.

    Am I understanding this correctly?

    Wow. You'd think an old Forth programmer like me would have caught the compile-time vs. run-time thing a bit faster.

    Thanks for explaining this.

    G. Wade

      ( I didn't mean to post Re^13: chopping a string into slices - is there a more elegant way to do it?. I meant to start fresh and post the following instead. )

      You're basically saying that [...]

      My point is simply parens don't create lists except when empty. That's it.

      LanX is contradicting that, saying that parens can sometimes create a list. My rebuttal is:

      1. There are important differences between scalar and list assignment operators,
      2. Parens on the LHS of an assignment can force the selection of one operator over the other, and
      3. It's not because parens magically create lists some of the time.

      perl as I understand it:

      1. Parens on the LHS of an assignment operator force the selection of the list assignment operator.
      2. The list assignment operator creates a list of both its operands.

      The abstraction pushed by LanX, if I understand him correctly:

      1. Parens on the LHS of an assignment operator force the creation of a list.
      2. A list on the LHS of an assignment operator forces the RHS operand of the assignment operator to be treated as a list.

      He hasn't had a chance to explain how that accounts for the difference in the output of scalar(($a)=5) and scalar($a=5)

      Context is a run-time issue, so that is a completely separate thing and can't influence which assignment we pick.

      Sometimes context is known at run-time, but not always.

      >perl -MO=Concise -e"f()" 2>&1 | find "entersub" 5 <1> entersub[t2] vKS/TARG,1 ->6 ^ | void >perl -MO=Concise -e"0+f()" 2>&1 | find "entersub" 6 <1> entersub[t2] sKS/TARG,1 ->7 ^ | scalar >perl -MO=Concise -e"print f()" 2>&1 | find "entersub" 6 <1> entersub[t2] lKS/TARG,1 ->7 ^ | list >perl -MO=Concise -e"return f()" 2>&1 | find "entersub" 6 <1> entersub[t2] KS/TARG,1 ->7 ^ | unknown at compile-time

      It's used by the optimizer.

      >perl -MO=Concise -e"'foo'" 3 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v ->3 - <0> ex-const v ->3 <-- The constant in void -e syntax OK context was removed from the execution path.
        > He hasn't had a chance to explain how that accounts for the difference in the output of scalar(($a)=5) and scalar($a=5)

        OK, my interpretation: the outer parens enclose to the params passed to scalar(). Both lines evaluate the result of the assignment in scalar context.

        DB<36> print scalar (($a)=5) 1 # Number of elements in list DB<37> print scalar ($a=5) 5 # value of $a
        as you can see there is no measurable difference between (),(2),(1,2)
        DB<41> print scalar (@a=(5,6)) 2 DB<42> print scalar (@a=(6)) 1 DB<43> print scalar (@a=()) 0
        whats notable is that ($a) is evaluated like a literal array!
        DB<49> print scalar ( ($a)=(5,6,7) ) 3 DB<50> print scalar ( ($a,$b)=(5,6,7) ) 3 DB<51> print scalar ( ()=(5,6,7) ) 3
        AFAIR what one expect as "the scalar of a list" should be the last element and only the scalar of an array is the number of elements.

        So the results prooves once again how problematic it is in perl5 to see the difference between arrays and lists!

        Maybe as a rule of thumb: Lists are immutable, so what looks like "a list at the LHS" has to be an array !

        Cheers Rolf

      List assignment is chosen because "()" on the LHS of "=" is special-cased to become a list assignment in that situation. The list is formed as a result of the list assignment being chosen, and gets created even if no parens are present.

        Exactly. But, the choice of list assignment is happening at compile time and therefore is independent of context.

        You have been saying this without my understanding because I was missing when the list assignment was chosen instead of scalar assignment.

        Like most important points, yours is immediately obvious once I understood my invalid assumption.

        As I said, this has been a most enlightening discussion. Thank you.

        G. Wade