Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • program end leads to stata breaking?

    Hi Statalist,

    I am having difficulty fixing this particular (probably syntactic?) error and would appreciate another pair of eyes looking at it.

    I want to define a program inside a forvalues loop. I've written a simpler version of what I want here:
    Code:
    forvalues i = 1 / 12 {
        di "`i'"
    
        cap prog drop aaa
        prog def aaa
            di "hello `i'"
        end 
    }
    When I run this (STATA/MP 15.1 on windows 10), I receive the following error message:

    Code:
    --Break--
    r(1);
    
    end of do-file
    
    --Break--
    r(1);
    Oddly, the `i' that should display at the beginning of the loop never displays itself, unless I remove the end command like this:
    Code:
    forvalues i = 1 / 12 {
        di "`i'"
    
        cap prog drop aaa
        prog def aaa
            di "hello `i'"
       * end 
    }
    In this latter case, `i' displays for the first loop before I get the error message you would expect, telling me I never finished defining my program:
    Code:
    1
      1. 
    unexpected end of file
    r(612);
    
    end of do-file
    
    r(612);
    Thank you for the help!

    Julian


  • #2
    I don't know why you're having the problem, other than a sense that Stata is "fussy" about multiple -end- statements, but my idea would be that there's likely a better way to write your code than repeatedly defining a program. I'd presume in your actual application that you're slightly changing the program at successive iterations, but I'd be pretty sure there's another way to do that. I'd encourage you to give the larger context of your goal here in hopes of us figuring out a better strategy.

    Comment


    • #3
      Thanks for the comments, Mike. I agree that it would be cleaner to write the program outside the loop, but I am adapting someone else's code and trying to make it as parallel as possible to their original structure. That means keeping this program definition directly above the location where it is used, not a hundred lines earlier at the top of the loop. It would also require me to edit a few hundred uses of this program in the code that I am adapting one by one (or with clever use of a macro, which makes me nervous). I can do this if necessary but would prefer not to.

      Comment


      • #4
        I can't figure out the bug, but I did figure out a way to do what you want.

        First, store 'i' as a global `j'; then put the program in a separate file:

        program.do
        Code:
        *** contents of program.do ***
        cap prog drop aaa
            prog def aaa
                di "hello $j" 
            end
        *** end program.do ***
        Then -include- this file inside your loop:

        Code:
        forv i = 1/12 {
            di "`i'"
            global j=`i'
            include program.do
            aaa
        }
        This works, though I have no idea why. Simply storing i as a global doesn't solve the problem, nor does using -include- without the global (though it shouldn't matter).

        hth,
        Jeph

        Comment


        • #5
          This is the same problem as trying to define a Mata or Python program within a bracketed block of Stata code: the end is interpreted by Stata as a command to exit the block. I am away from Stata at the moment, but in general do not see a way of accomplishing what you want. Without knowing more about your code, it seems to me the "program" should be recast as a chunk of code that expects a collection of local macros where the program now processes the arguments.

          Comment


          • #6
            Hi William and Jeph,

            Thanks very much for the thoughts. I would not have thought of the include/macro based solution, so I appreciate it. Despite what I said above, it is probably easiest to just take Mike's advice at this point, as storing a separate file with this program will make the code less 'parallel,' as I mentioned before.

            Thanks again,

            Julian


            Thanks

            Comment


            • #7
              I agree with Mike. This is not something you want to do in Stata (and probably other software). From the information that Julian provides, I cannot fully understand the motivation to parallel code that was very likely written in a different software/language. This reminds me of trying to translate spoken languages word for word, which often results in nonsensical and/or grammatically flawed sentences.

              Best
              Daniel

              Comment


              • #8
                My strategy for a translation of someone else's code, particularly when it is difficult (a loop hundreds of lines long!), is to make the translation as literal as possible, so I have some sympathy for Julian's situation. Note, for example, that Mata has a -goto- construct for the explicit purpose of translating FORTRAN to Mata. Moving a program(s) outside the loop (e.g., all programs defined at the top of the code), though, seems pretty clear to me, as that's the style I like anyway.

                Comment

                Working...
                X