Click here to get back home

FAQ 4.47 How do I handle circular lists?

 HomeNewsGroups | Search | About
 comp.lang.perl.misc    Post an article   get this group's latest topics as an RSS feed add this group's latest topics to your My MSN content add this group's latest topics to your My Yahoo content
Subject Author Date
FAQ 4.47 How do I handle circular lists? PerlFAQ Server 05-12-2008
Posted by Dr.Ruud on May 18, 2008, 11:15 am
Please log in for more thread options
sheinrich@my-deja.com schreef:

> From what the doc says it is quite understandable why the given
> examples
> $i = $i ++;
> print ++ $i + $i ++;
> should be avoided.
> However, it is not so clear and at least can be subject of debate, if
> the outcome of
> $index = ++$index % $asize;
> is also indeterminate.

No, the issue is clear, so there is no use debating that:
"modifying a variable twice in the same statement will lead to undefined
behaviour".
Take care: "undefined behaviour" and "indeterminate" don't mean the
same.

The example
$i = $i ++;
looks very similar to
$index = ++$index % $asize;
so I can not fathom how that can confuse you.

All these examples don't matter when you have read and understood this:
"modifying a variable twice in the same statement will lead to undefined
behaviour".
This "undefined" includes that it can behave differently on different
platforms.

--
Affijn, Ruud

"Gewoon is een tijger."


Posted by Peter J. Holzer on May 18, 2008, 1:02 pm
Please log in for more thread options
> sheinrich@my-deja.com schreef:
>
>> From what the doc says it is quite understandable why the given
>> examples
>> $i = $i ++;
>> print ++ $i + $i ++;
>> should be avoided.
>> However, it is not so clear and at least can be subject of debate, if
>> the outcome of
>> $index = ++$index % $asize;
>> is also indeterminate.
>
> No, the issue is clear, so there is no use debating that:
> "modifying a variable twice in the same statement will lead to undefined
> behaviour".

That sentence is very clear when taken out of context. Unfortunately, it
is much less clear in the context of perlop. Firstly, it is in the
section "Auto-increment and Auto-decrement", not in the section
"Assignment Operators". So does it only apply to ++ and -- or is

($i = 1) + ($i = 2)

also undefined? (it is in C)

Also what is "You just know it will be done sometime before or after the
value is returned." supposed to mean? Sometime between program start and
program end? Or maybe something more specific like sometime between
start and end of the current statement. And what is the current
statement anyway, if that can contain code blocks? If you allow
out-of-order execution in a programming language you need to be very
precise about the rules. Perlop is not precise. As a specification, it
is unusable (in this respect).


> Take care: "undefined behaviour" and "indeterminate" don't mean the
> same.
>
> The example
> $i = $i ++;
> looks very similar to
> $index = ++$index % $asize;
> so I can not fathom how that can confuse you.

He already wrote (twice!) that he understood "sometime before or after"
as "sometime before for the pre operators and sometime after for the
post operators". Given this misunderstanding it quite clear why he
believed that the second is well-defined but the first is not:

In the second case, the subexpression (++$index) assigns to index. But
that assignment occurs "sometime before" the result of the subextression
is returned. Since that value is needed to compute the value of
((++$index) % $asize) there is a clear and defined order of the two
assignments and the result is well-defined.

In the first case, the assignment of ($i ++) happens "sometime after"
the value is returned (this is stupid, of course and might have given a
hint that this interpretation was not the intended one). And of course
the assignment of the value of the subexpression to $i also happens
after that value has been determined. So the order of the two
assignments is undefined.

        hp


Posted by szr on May 18, 2008, 4:06 pm
Please log in for more thread options
Peter J. Holzer wrote:
>> sheinrich@my-deja.com schreef:
[...]
> That sentence is very clear when taken out of context. Unfortunately,
> it is much less clear in the context of perlop. Firstly, it is in the
> section "Auto-increment and Auto-decrement", not in the section
> "Assignment Operators". So does it only apply to ++ and -- or is
>
> ($i = 1) + ($i = 2)
>
> also undefined? (it is in C)

This seems quite defined to me; assignments occur first, going left to
right, so $i becomes 2 (ok, it becomes 1 and then immediately becomes
2), and then you add (+), resulting in 2 + 2, which of course is 4. This
seems to hold true across the board:

$ perl5.10.0 -Mstrict -we 'my $i=5; print(($i = 1) + ($i = 2), "\n")'
4

$ perl5.8.8 -Mstrict -we 'my $i=5; print(($i = 1) + ($i = 2), "\n")'
4

$ perl5.8.2 -Mstrict -we 'my $i=5; print(($i = 1) + ($i = 2), "\n")'
4

$ perl5.8.0 -Mstrict -we 'my $i=5; print(($i = 1) + ($i = 2), "\n")'
4

$ perl5.6.1 -Mstrict -we 'my $i=5; print(($i = 1) + ($i = 2), "\n")'
4


There seems to be no reason that this would be undefined.

--
szr



Posted by Ben Morrow on May 18, 2008, 6:24 pm
Please log in for more thread options

> Peter J. Holzer wrote:
> >> sheinrich@my-deja.com schreef:
> [...]
> > That sentence is very clear when taken out of context. Unfortunately,
> > it is much less clear in the context of perlop. Firstly, it is in the
> > section "Auto-increment and Auto-decrement", not in the section
> > "Assignment Operators". So does it only apply to ++ and -- or is
> >
> > ($i = 1) + ($i = 2)
> >
> > also undefined? (it is in C)
>
> This seems quite defined to me; assignments occur first, going left to
> right, so $i becomes 2 (ok, it becomes 1 and then immediately becomes
> 2), and then you add (+), resulting in 2 + 2, which of course is 4. This
> seems to hold true across the board:

That's not the correct interpretation. Assignments happen as they are
needed, with the whole expression being evaluated in order of
precedence. What's weird is that ($i = 1) doesn't return 1, it returns
an alias to $i (presumably so expressions like

($i = "x") =~ s/x/y/;

can work correctly), which means sometimes assignments appear to
have happened earlier than they actually did. (This leads to the
bizarre fact that

($i = 1) = 2;

is valid Perl, whereas it certainly isn't valid C.)

For instance, this

~% perl -le'print +($i = 1) + ($i = 2) + ($i = 3)'
7

at first makes no sense, until you realise the order of evaluation is

1: $i = 1 # returns an alias to $i
2: $i = 2 # returns another alias to $i
3: add #1 and #2 # since $i is now 2, this returns 4
4: $i = 3 # returns another alias to $i
5: add #3 and #4 # since $i is now 3, this returns 7

It's important to realise that 'undefined' doesn't mean the same thing
in the Perl docs as it does in the C standard. In C, 'undefined'
basically means 'different implementations are allowed to do different
things'; since Perl only has one implementation, that doesn't apply. In
Perl, it means something more like 'perl's behaviour here is somewhat
subtle, and we don't promise not to change it'. Treating the perldocs as
a specification you can wave at people is rather silly: when perl's
behaviour doesn't match the docs, it's not given which will be treated
as 'correct'.

Ben

--
Every twenty-four hours about 34k children die from the effects of poverty.
Meanwhile, the latest estimate is that 2800 people died on 9/11, so it's like
that image, that ghastly, grey-billowing, double-barrelled fall, repeated
twelve times every day. Full of children. [Iain Banks] ben@morrow.me.uk

Posted by John W. Krahn on May 18, 2008, 11:19 pm
Please log in for more thread options
Ben Morrow wrote:
>> Peter J. Holzer wrote:
>>>> sheinrich@my-deja.com schreef:
>> [...]
>>> That sentence is very clear when taken out of context. Unfortunately,
>>> it is much less clear in the context of perlop. Firstly, it is in the
>>> section "Auto-increment and Auto-decrement", not in the section
>>> "Assignment Operators". So does it only apply to ++ and -- or is
>>>
>>> ($i = 1) + ($i = 2)
>>>
>>> also undefined? (it is in C)
>> This seems quite defined to me; assignments occur first, going left to
>> right, so $i becomes 2 (ok, it becomes 1 and then immediately becomes
>> 2), and then you add (+), resulting in 2 + 2, which of course is 4. This
>> seems to hold true across the board:
>
> That's not the correct interpretation. Assignments happen as they are
> needed, with the whole expression being evaluated in order of
> precedence.

I've had this discussion on c.l.p.misc before and it has been (rightly)
pointed out to me that precedence does not determine order of evaluation.



John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order. -- Larry Wall

Similar ThreadsPosted
FAQ 4.47 How do I handle circular lists? February 28, 2005, 12:03 pm
FAQ 4.47 How do I handle circular lists? May 17, 2005, 5:03 pm
FAQ 4.47 How do I handle circular lists? August 2, 2005, 4:03 pm
FAQ 4.47 How do I handle circular lists? October 5, 2005, 10:03 pm
FAQ 4.47 How do I handle circular lists? January 11, 2006, 5:03 pm
FAQ 4.47 How do I handle circular lists? April 20, 2006, 3:03 am
FAQ 4.47 How do I handle circular lists? August 2, 2006, 9:03 pm
FAQ 4.47 How do I handle circular lists? October 14, 2006, 9:03 pm
FAQ 4.47 How do I handle circular lists? December 26, 2006, 9:03 pm
FAQ 4.47 How do I handle circular lists? February 24, 2007, 9:03 pm

Our other projects:

Art Dolls, Fairies and Mermaids - Sunnyfaces.net

Roy's Linux, Programming and Search Engines messages

1-Script XML SitemapXML Sitemap