Stata The Stata listserver
[Date Prev][Date Next][Thread Prev][Thread Next][Date index][Thread index]

st: Re: Double -for- loop on one line crashes Stata


From   rgutierrez@stata.com (Roberto G. Gutierrez, StataCorp.)
To   statalist@hsphsun2.harvard.edu
Subject   st: Re: Double -for- loop on one line crashes Stata
Date   Tue, 15 Oct 2002 17:34:40 -0500

Kaleb Michaud <kaleb@arthritis-research.org> asked:

> Just an FYI - seems the more I use Stata, the more I'm compressing my code.
> The following, independent of the actual command used, crashes my Stata
> every time (using Stata 7.0SE in Win2000 - causes Stata to end, no error
> message in results).
>
> Feel free to tell me why so I don't assume such things will work in the
> future, but thought I'd share.
>
> forvalues i =1/3 {forvalues j=1/3 {replace badcode = badcode + "h`i'_`j'" if
> hrec`i'_`j'chk>0 } }
>
> I do know it works for one loop on one line, and this also works fine in a
> do file written as:
>
> forvalues i =1/3 {
> 	forvalues j=1/3 {
> 		replace badcode = badcode + "h`i'_`j'" if hrec`i'_`j'chk>0
> 	}
> }

which prompted a myriad of responses to the list, summarized by the following
points.

-----------------------------------------------------------------------------
1. Placing commands after "{" on a command line, such as
	
       forvalues j = 1/3 { di `j'}
	    
   is a bad idea.

2. It is such a bad idea that, as Kaleb noticed, something like

       forvalues i = 1/3 {forvalues j=1/3 {di `i'*`j'} }

   may even cause Stata to crash.

3. The fact that this is a bad idea is tacit rather than explicit in 
   our documentation (Nick Cox's words - couldn't have said it better
   myself).

4. In the past, Stata developers have often used syntax like

       if <condition> { do something }

   in their ado code.  If that works then why don't similar things?

----------------------------------------------------------------------------

We'll address these points one at a time:

> 1. Placing commands after "{" on a command line, such as
> 	
>        forvalues j = 1/3 { di `j'}
> 	    
>    is a bad idea.

It is a bad idea because Stata must jump through hoops to try to allow such a
construct to work.  Remember that Stata normally expects each command to be on
a separate line.  The above line contains two commands, -forvalues- and -di-.

This leads to the question of why this was ever allowed.  Stata developers are
programmers at heart, and thus we tried to allow C-like constructs where
possible.  However, due to the trickery involved in making this work,
unexpected results can occur, as evidenced by the potential for a crash.

Over time, we have realized that we never should have allowed such constructs
because it is impossible to make them work in 100% of cases involving nested {
... } constructs -- Stata just does not work that way.

> 2. It is such a bad idea that, as Kaleb noticed, something like
> 
>        forvalues i = 1/3 {forvalues j=1/3 {di `i'*`j'} }
> 
>    may even cause Stata to crash.

This is not good and of course should be considered a bug.  Of course, this
brings up the issue of what Stata SHOULD do in this case.  Stata should issue
an error, but that is easier said than done.  We intend to fix this, but don't
expect to see the fix soon.

> 3. The fact that this is a bad idea is tacit rather than explicit in 
>    our documentation (Nick Cox's words - couldn't have said it better
>    myself).

Because such constructs have been allowed in the past, and because they
currently do not produce appropriate errors, our documentation does not
explicitly disallow them.  It should.

> 4. In the past, Stata developers have often used syntax like
> 
>        if <condition> { do something }
> 
>    in their ado code.  If that works then why don't similar things?

At StataCorp, we always knew that such constructs would work as long as they
were "simple", and, determining what constitutes "simple" was born more out of
experience than any definite guidelines.  When we as developers used such
syntax, it was originally with the (undocumented) knowledge that such
constructs worked, but couldn't be nested too deeply.

Stata developers and users should no longer use syntax like this.  Our intent
for the future is to disallow such syntax by issuing an error.  We also 
intend to make our documentation explicit that it is not allowed.  Of course,
when we complete the change, old code will continue to work under version
control.

We do not, however, anticipate making these changes anytime soon.

--Alan                                       --Bobby
ariley@stata.com                             rgutierrez@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