order_of_evaluation 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. I wonder if this strange behaviour is known:
  2. $ perl -e'my $i = 1;
  3. my $foo = sub {
  4. $i = shift if @_
  5. };
  6. print $i,&$foo(3),$i;'
  7. 333
  8. $ perl -e'my $i = 1;
  9. my $foo = sub {
  10. $i = shift if @_
  11. };
  12. print $i; print &$foo(3),$i;'
  13. 133
  14. The first seems very wrong to me. The 2nd arg $foo, a cv - even a
  15. closure, but this is not relevant in general - must not be evaluated
  16. before the 1st arg of print.
  17. There's something wrong with the argument handling in the compiler
  18. and/or run-time, affecting side-effects only - such as the evaluation
  19. here. I'll scratching my head now how to fix this, if wanted. IMO it
  20. should be fixed. To which ops this really should be compiled to, if
  21. it can be detected on the compiler level. e.g. "not-special ops" with
  22. list args with cv's, which are not the 1st arg. Such as our print
  23. here. Or if it needs a fix in some of the LISTOP pp_ functions, like
  24. pp_print().
  25. http://groups.google.com/group/perl.perl6.language/tree/browse_frm/thread/508f65ac12195a59/0f35e622211975bd?rnum=61&_done=%2Fgroup%2Fperl.perl6.language%2Fbrowse_frm%2Fthread%2F508f65ac12195a59%3F#doc_617344f05578681a
  26. Rafael once wrote:
  27. The implicit assumption is that C<,> guarantees
  28. evaluation order. Like the comma operator in C IIRC.
  29. -- This would be nice, but is wrong.
  30. Mark Overmeer then wrote:
  31. In the C language, the comma does not define the order of evaluation,
  32. which is cause of many conversion problems.
  33. -- Well, in lisp special arrangements are made for faster register passing -
  34. a bogus argument, but I heard it for parrot - and possible parallel evaluation,
  35. so left-to-right in special functions is not always guaranteed -- Reini
  36. In Perl, the comma is strictly evaluated from left to right in scalar context (explicitly
  37. described perlop).
  38. In LIST context, the comma is not an operator at all, but an expression
  39. separator like ';' And therefore, the comma is not in for re-ordering
  40. in an argument list.
  41. -- Now this is true, but only half of the truth.
  42. And I know that Larry wrote, that perl5 is mistaken here, and perl6 should get
  43. it right. This was in 2003.
  44. But since it's quite easy to fix, it should be fixed in perl5, as everyone
  45. expects such args to be evaluated left-to-right.
  46. http://groups.google.com/groups?selm=bhok6j%2470f%241%40plover.com
  47. first, wrong:
  48. 1 <0> enter
  49. 2 <;> nextstate(main 1 -e:1) v:{
  50. 3 <$> const[IV 1] s
  51. 4 <0> padsv[$i:1,4] sRM*/LVINTRO
  52. 5 <2> sassign vKS/2
  53. 6 <;> nextstate(main 3 -e:4) v:{
  54. 7 <0> pushmark sRM
  55. 8 <$> anoncode[CV ] lRM
  56. 9 <1> refgen sK/1
  57. a <0> padsv[$foo:3,4] sRM*/LVINTRO
  58. b <2> sassign vKS/2
  59. c <;> nextstate(main 4 -e:5) v:{
  60. d <0> pushmark s
  61. e <0> padsv[$i:1,4] l
  62. f <0> pushmark s
  63. g <$> const[IV 3] sM
  64. h <0> padsv[$foo:3,4] s
  65. i <1> entersub[t4] lKS/TARG,1
  66. j <0> padsv[$i:1,4] l
  67. k <@> print vK
  68. l <@> leave[1 ref] vKP/REFC
  69. second ok:
  70. 1 <0> enter
  71. 2 <;> nextstate(main 1 -e:1) v:{
  72. 3 <$> const[IV 1] s
  73. 4 <0> padsv[$i:1,4] sRM*/LVINTRO
  74. 5 <2> sassign vKS/2
  75. 6 <;> nextstate(main 3 -e:4) v:{
  76. 7 <0> pushmark sRM
  77. 8 <$> anoncode[CV ] lRM
  78. 9 <1> refgen sK/1
  79. a <0> padsv[$foo:3,4] sRM*/LVINTRO
  80. b <2> sassign vKS/2
  81. c <;> nextstate(main 4 -e:5) v:{
  82. d <0> pushmark s
  83. e <0> padsv[$i:1,4] l
  84. f <@> print vK
  85. g <;> nextstate(main 4 -e:5) v:{
  86. h <0> pushmark s
  87. i <0> pushmark s
  88. j <$> const[IV 3] sM
  89. k <0> padsv[$foo:3,4] s
  90. l <1> entersub[t4] lKS/TARG,1
  91. m <0> padsv[$i:1,4] l
  92. n <@> print vK
  93. o <@> leave[1 ref] vKP/REFC