Statalist The Stata Listserver


[Date Prev][Date Next][Thread Prev][Thread Next][Date index][Thread index]

Re: st: Help needed to understand behavior of Mata's increment/decrement


From   wgould@stata.com (William Gould, Stata)
To   statalist@hsphsun2.harvard.edu
Subject   Re: st: Help needed to understand behavior of Mata's increment/decrement
Date   Mon, 15 May 2006 08:44:47 -0500

Joseph Coveney <jcoveney@bigplanet.com> came up with a cute Mata expression, 

	(i, ++i, i, i++, i)

I'm recommend against ever coding anything like that, but Joseph explains 
that he concocted it just to explore the operators' behavior, and he's 
puzzled by the result.  Joseph writes, 

> Mata's documentation (in "[M-2] op_increment -- Increment and decrement
> operators") says that increment and decrement operators are performed in
> relation to the "entire expression."  I don't understand why the first and
> second elements of -myrowvector = (i, i, ++i, i, i++, i)- don't come out the
> same as the first element of -myrowvector = (i, ++i, i, i++, i)-.

Just so you can see what Joseph is talking about, here's the output:

	: i = 1
 
        : (i, ++i, i, i++, i)
               1   2   3   4   5
            +---------------------+
          1 |  2   2   2   2   2  |
            +---------------------+

        : i
          3

The operator worked as advertized.  The expression is (i, ++i, i, i++, i), 
which is to say, the entire thing.  Before the expression, Mata executed 
++i, and i went from being 1 to 2.  After the expression, Mata incremented 
i again, and i went from being 2 to 3.  During the expression, i remained 
constant.

Joesph's confusion is because he is thinking of (i, ++i, i, i++, i) as 
being a list of expressions, the list separated by commas.  Not true.
Comma is an operator; (a,b,c) is a single expression just as is (a+b+c).

Actually, the example Joesph gave was 

	myrowvector = (i, i, ++i, i, i++, i)

and given what I just said, Joseph now probably thinks of this as being 
two expressions, -myrowvector- on the left, and -(i, i, ++i, i, i++, i)- 
on the right.  Not true.  Equal is an operator, and the above 
is one expression (a=b=c is a single expression just as is a+b+c).  In Mata,
you can code things like

	x = y = z[i=(i++)+1]

In his posting, Joesph said

> The op_increment documentation does admonish, "and many programmers
> feel that i++ or ++i should never be coded in a line that has a second
> reference to i, before or after."  

Thus, the following is bad style, 

		y[i] = x[i++] 

because i and i++ are being used in the SAME EXPRESSION.
Forget the rule and think about,

		y[i] = x[++i]

What would you expect to happen?  Are you sure?

The manual says "many programmers feel".  In most languages that allow ++ and
--, the admonishment is stronger, warning that the result is undefined.  What
they mean is that they won't tell you what it does, because it is too
complicated, and anyway, they want the freedom to change what it does.  We
should have done the same thing.  We were too proud about how nicely we had
isolated the ++ and -- operators.

If you repeat Joseph's experiment with structure elements (e.g., p.i and
p.i++), you will obtain different results!  It turned out that, with ++p.i
and p.i++, we could not be fast and move the reference all the way to the
front or end of the expression, so the incrementation moves just a little,
far enough to do the right thing if you follow the admonishment, which now 
needs to be stronger.

-- Bill
wgould@stata.com
*
*   For searches and help try:
*   http://www.stata.com/support/faqs/res/findit.html
*   http://www.stata.com/support/statalist/faq
*   http://www.ats.ucla.edu/stat/stata/



© Copyright 1996–2014 StataCorp LP   |   Terms of use   |   Privacy   |   Contact us   |   What's new   |   Site index