Home > Archive > Fortran > July 2006 > use 'go to' doing some case studies and induced problems
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
use 'go to' doing some case studies and induced problems
|
|
|
| Hi,
Let's say there will be some case studies after the main program.
Usually, I do this:
program main
go to 100 !case 1
go to 200 !case 2
go to 300 !sensitivity study..
.....
100 continue
case 1......
stop ' case 1'
......
Sometimes, these case studies are not so worthy of writing them as
subroutines. Furthermore, it takes time to find the varialbes or
modules declared or used in the subroutine . I'd like to know the
answer quickly. Hence I write a lot of go to XXX. Each of them go to
a small case study. Oh, yes. Sometimes I can jump to the case study
directly to prevent from reruning. This is the advantage. However,
there will be drawbacks. One of them is that I usually forgot if some
parameters are initilized or set.
My questions are
(1) what will you do if you want to do some case studies in the end of
main program without writing it as subroutines/functions ? Will you
use ' go to '?
(2) How to prevent from forgetting initilizations of varaibles if one
use 'go to'?
Any suggestion is appreciated.
Mike
| |
| Richard Maine 2006-07-19, 10:00 pm |
| Mike <acout@yam.com> wrote:
> (1) what will you do if you want to do some case studies in the end of
> main program without writing it as subroutines/functions ?
The only thing I can suggest is that you should use subroutines instead
of stuffing everything into the main program. You are running into the
first of many kinds of problems that result from trying to avoid
subroutines. Any advice I might give on how to continue to avoid using
subroutines would be counterproductive.
Somehow I am reminded of the old joke of a person complaining to the
doctor that it hurts when he grabs his ear and twists real hard. The
answer, of course, is "don't do that."
I am seeing here that you are havng problems that arise from avoiding
subroutines, and my answer is the same as the doctor's.
Not that subroutines will automatically make all your problems go away.
Of course, they won't. But learning how to use them well is the path to
follow, rather than working on how to avoid them.
--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
| |
| Brooks Moses 2006-07-19, 10:00 pm |
| Mike wrote:
> Hi,
>
> Let's say there will be some case studies after the main program.
> Usually, I do this:
>
> program main
> go to 100 !case 1
> go to 200 !case 2
> go to 300 !sensitivity study..
> ....
> 100 continue
> case 1......
> stop ' case 1'
> .....
>
> Sometimes, these case studies are not so worthy of writing them as
> subroutines. Furthermore, it takes time to find the varialbes or
> modules declared or used in the subroutine . I'd like to know the
> answer quickly. Hence I write a lot of go to XXX. Each of them go to
> a small case study. Oh, yes. Sometimes I can jump to the case study
> directly to prevent from reruning. This is the advantage. However,
> there will be drawbacks. One of them is that I usually forgot if some
> parameters are initilized or set.
> My questions are
> (1) what will you do if you want to do some case studies in the end of
> main program without writing it as subroutines/functions ? Will you
> use ' go to '?
You've phrased the question in a way that presumes what the answer is;
there is no way to jump to some code at the end of the main program
without either (a) using subroutines and/or functions, (b) using GOTO,
or (c) doing something completely absurd and unreadable with a huge IF
block or the like.
When I've been in situations that are similar to what I understand yours
to be, I've either put the code up in the main program where it's used,
or else used a subroutine.
> (2) How to prevent from forgetting initilizations of varaibles if one
> use 'go to'?
This is one of the main reasons I use subroutines. Although writing the
argument list is sometimes a little time-consuming, it's still one of
the easiest ways to make sure that I know, when looking at the spot
where you've written the "go to 100" statement, what variables need to
be initialized at that point.
You might look into subroutines that are included within the main
program (after a "contains" statement), which can access variables from
the main program directly as well as through the argument list. This
would allow you to only put the variables that you're worried about
having initialized in your argument list, and leave the others to get
carried over automatically.
....
In general, though, this is one of the tradeoffs in programming.
Writing things with a clear and explicit structure (such as subroutines)
instead of the quick and immediate way (such as goto statements) can
sometimes take more work at first, but that work goes directly into
things that make the program easier to read, easier to debug, and easier
to extend later, and thus in the long run it does save time -- often a
lot of it.
In my experience, this is one of the things that you only find out much
later. I have a program which started out as a fairly quick and simple
thing. It grew a little at a time as I worked on it, and each time it
grew I found it easier to just add in the code in the main program
rather than figuring out how to break some of it out into a subroutine.
Eventually it was a thousand lines long, and a real pain to work with,
and I finally had to completely rewrite all of it in a proper structured
way because there was no other way to fix it. So that was all the work
that I'd been avoiding, all to do in a lump, plus all the work of doing
it the first time.
Similarly, I remember another program which I was writing, where I just
wanted to get some results quickly. And I did, and it worked. And then
I used those quick results in some research, and a year later I wanted
to do some more analysis, and had a very hard time figuring out how I'd
gotten those results or even with what program (since it wasn't at all
obvious from the program what it did, because it wasn't written at all
clearly); it amounted to nearly as much work as redoing it all over.
The worst problem, though, is what happens when the lack of structure
means that you have a bug in your code that you never notice, because
it's written in a way (such at the gotos that you mention) that means
that it's very hard to notice improperly-initialized variables or other
problems of that sort.
Which reminds me of the very best way to make sure the variables are
initialized properly, if you are using gotos: put a test, after the "100
continue" statement, that checks to see.
- Brooks
--
The "bmoses-nospam" address is valid; no unmunging needed.
| |
| Ian Bush 2006-07-20, 8:00 am |
| Mike wrote:
> Let's say there will be some case studies after the main program.
> Usually, I do this:
>
> program main
> go to 100 !case 1
> go to 200 !case 2
> go to 300 !sensitivity study..
> ....
> 100 continue
> case 1......
> stop ' case 1'
> .....
>
> Sometimes, these case studies are not so worthy of writing them as
> subroutines. Furthermore, it takes time to find the varialbes or
> modules declared or used in the subroutine .
Lack of knowledge of the data flow in your code means you do not understand
your code. It some ways it is more important than the functional flow.
> I'd like to know the
> answer quickly. Hence I write a lot of go to XXX. Each of them go to
> a small case study. Oh, yes. Sometimes I can jump to the case study
> directly to prevent from reruning. This is the advantage. However,
> there will be drawbacks. One of them is that I usually forgot if some
> parameters are initilized or set.
> My questions are
> (1) what will you do if you want to do some case studies in the end of
> main program without writing it as subroutines/functions ? Will you
> use ' go to '?
I can not remember when I last used GOTO in any of its forms.
> (2) How to prevent from forgetting initilizations of varaibles if one
> use 'go to'?
Given my previous comment I can not answer this. However I would note that
I do try to design the code such that it is hard to avoid doing this, or
as a last resort find out what the compiler can do to help me. Defensive
programming is your friend - it may cost a little time and effort to begin
with but the investment has an excellent interest rate,
Ian
| |
| Catherine Rees Lay 2006-07-20, 8:00 am |
| Mike wrote:
> Hi,
>
> Let's say there will be some case studies after the main program.
> Usually, I do this:
>
> program main
> go to 100 !case 1
> go to 200 !case 2
> go to 300 !sensitivity study..
> ....
> 100 continue
> case 1......
> stop ' case 1'
> .....
>
> Sometimes, these case studies are not so worthy of writing them as
> subroutines. Furthermore, it takes time to find the varialbes or
> modules declared or used in the subroutine . I'd like to know the
> answer quickly. Hence I write a lot of go to XXX. Each of them go to
> a small case study. Oh, yes. Sometimes I can jump to the case study
> directly to prevent from reruning. This is the advantage. However,
> there will be drawbacks. One of them is that I usually forgot if some
> parameters are initilized or set.
> My questions are
> (1) what will you do if you want to do some case studies in the end of
> main program without writing it as subroutines/functions ? Will you
> use ' go to '?
> (2) How to prevent from forgetting initilizations of varaibles if one
> use 'go to'?
> Any suggestion is appreciated.
>
> Mike
>
1) If for some reason I really didn't want a separate routine with an
argument list, I'd use an internal subroutine. I've done this where I've
been splitting up old code that had
if (case1) then
<lots of lines>
elseif (case2) then
<lots of lines>
elseif...
It's very rare that I use it on new code.
These days I almost never use goto, and certainly not in the case you
describe. Anything so short that it's not worth making a subroutine for
(say, less than 10 lines), I'd put inline in the code. If it's worth
splitting out, then why not use the facilities the language has for that
- i.e. subroutines?
2) A compiler which tells you at run-time if an uninitialised variable
is used is a huge timesaver.
You really have to think about your comment "Furthermore, it takes time
to find the varialbes or modules declared or used in the subroutine .
I'd like to know the answer quickly."
I'd have to say, this sounds like it could easily lead to GIGO (garbage
in, garbage out) when you miss something in the logic. If you're lucky,
your answer will be wildly wrong and you'll notice. If you're unlucky,
it'll be plausible but wrong. Any method will only work correctly if you
also make sure the values in the variables are correct. Writing
subroutines makes you think about the logic. The extra time is worth it.
Catherine.
| |
| Paul Van Delst 2006-07-20, 7:00 pm |
| Mike wrote:
> Hi,
>
> Let's say there will be some case studies after the main program.
> Usually, I do this:
>
> program main
> go to 100 !case 1
> go to 200 !case 2
> go to 300 !sensitivity study..
> ....
> 100 continue
> case 1......
> stop ' case 1'
> .....
>
> Sometimes, these case studies are not so worthy of writing them as
> subroutines. Furthermore, it takes time to find the varialbes or
> modules declared or used in the subroutine . I'd like to know the
> answer quickly. Hence I write a lot of go to XXX. Each of them go to
> a small case study. Oh, yes. Sometimes I can jump to the case study
> directly to prevent from reruning. This is the advantage. However,
> there will be drawbacks. One of them is that I usually forgot if some
> parameters are initilized or set.
> My questions are
> (1) what will you do if you want to do some case studies in the end of
> main program without writing it as subroutines/functions ? Will you
> use ' go to '?
> (2) How to prevent from forgetting initilizations of varaibles if one
> use 'go to'?
> Any suggestion is appreciated.
Others have commented on the subroutine vs goto issue. What about something like:
PROGRAM mycases
... put *all* your declarations here....
CALL Init() ! Initialise all the stuff for your case studies
! Process all cases
Case_Loop: DO icase = 1, ncases
SELECT CASE (icase)
CASE(1)
CALL Case1()
CASE(2)
CALL Case2()
CASE(3)
CALL Case3()
CASE(4)
CALL Case4()
....
CASE DEFAULT
CALL DummyTest()
END SELECT
END DO Case_Loop ! If DO used
CONTAINS
SUBROUTINE Init()
....no arg list.. just init stuff
END SUBROUTINE Init
SUBROUTINE Case1()
....no arg list.. just run case1
END SUBROUTINE Case1
....etc....
END PROGRAM mycases
You don't need argument lists if you don't want them -- but I would use them just in case
(no pun) a test case modifies something used by a later-called test case. If you're
supa-careful maybe you'll be alright. You could always call the Init() every time for each
case.
You can add extra cases as required in the SELECT CASE. If you want to quit after any
particular case, just add an "EXIT Case_Loop" after the test case call to quit the DO loop.
I don't know what you mean by "test case", but have you looked at Bil Kleb's fUnit utility
for testing Fortran code? It'll be a bit more work setting it up, but you'll have a much
better framework for testing code. See http://funit.rubyforge.org for all the fruit.
cheers,
paulv
--
Paul van Delst Ride lots.
CIMSS @ NOAA/NCEP/EMC Eddy Merckx
Ph: (301)763-8000 x7748
Fax:(301)763-8545
| |
| John Harper 2006-07-20, 7:00 pm |
| In article <1153362148.122922.208210@b28g2000cwb.googlegroups.com>,
Mike <acout@yam.com> wrote:
>Hi,
>
>Let's say there will be some case studies after the main program.
>Usually, I do this:
>
>program main
>go to 100 !case 1
>go to 200 !case 2
>go to 300 !sensitivity study..
>....
>100 continue
> case 1......
>stop ' case 1'
>.....
>
In what follows I am following Mike's example of avoiding
subroutines, though that may well not be the best way to go.
I suspect from his description he would comment out two of those
go to statements. If so, how about
program main
integer which
print *,'Enter 1,2, or 3 for case 1, case 2, sensitivity study'
read *, which
go to (100,200,300) which
...
if using f66 or old-fashioned f77? (Metcalf and Reid "Effective Fortran
77" (1990) p160, which predated f90, already recommended replacing a
computed GO TO by a block IF. Of course the CASE construct is even
better but wasn't in f77.)
In f95 that code would still work but give an obsolescence warning.
One way to avoid that is to replace the last line by
select case(which)
case(1)
go to 100
case(2)
go to 200
case(3)
go to 300
case default
print *,'If you know what that means, implement it!'
stop
end select
which also deals with the possibility of the user entering a number
other than 1,2 or 3.
I would also replace "go to 100" by whatever Mike had between
"100 continue" and "stop 'case 1'" if brief, but it would be hard
to read the entire case construct if it was, say, 500 lines. If it
is, then subroutines really do help a lot. My own guide is that if
a program unit is too long for one screen it ought to be split up,
unless it's a module or main program in which what's before CONTAINS
is short enough, and so is each subprogram between CONTAINS and
either END PROGRAM or END MODULE. I just hope nobody with access to
my disk space is reading this and finding counter-examples :-)
-- John Harper, School of Mathematics, Statistics and Computer Science,
Victoria University, PO Box 600, Wellington 6140, New Zealand
e-mail john.harper@vuw.ac.nz phone (+64)(4)463 5341 fax (+64)(4)463 5045
|
|
|
|
|