aglew@ccvaxa.UUCP (03/14/86)
Why add `and-if'? Use <shudder> gotos: if A then X; if B then Y else goto AB else goto AB AB: begin Z end. Have I shocked you all? Will I have enough flames to break up the Ottawa River early? (I'm going home this weekend, hurrah!) Are you all going to tell be the above code is wrong? Hold on: this is Donald E. Knuth's example. In the uproar that followed Dijkstra's "Goto considered dangerous" letter, Knuth came out with a bit of reason. He suggested that gotos only be used where a bit of work (X above) has made one case into another. He also suggested that it be illegal to fall through to a label - that the only way to reach a label is via a goto. Finally, something I'm not sure whether it's my idea, or Knuth's, or somebody else's, there is the concept of an ASIDE. An ASIDE is a labelled block of code that can only be entered via a goto to the label at the top of the aside (and can only be exited in one of the normal ways to exit a block). Code that would seemm to fall through to an aside branches around it. So above you really have goto END AB: begin Z; goto END end END: ... The aside has saved you a goto and a label - it makes it seem just a bit less like spaghetti. Anyway, you can obviously do if A then X if B then Y else Z else Z Although it reads more easily if you do if !A then Z else if B then Y else Z but if Z is not simply a function call then you have to make sure that two copies of code get updated. That's what macros are for if ( !A ) { #define Z zzzzzzzzzzzzzzz Z; } else { if ( B ) Y; else Z; } A big #define in line looks ugly, and is really just like an aside, except that it hides a bit of the concept of doing work to get simpler cases. Andy "Krazy" Glew. Gould CSD-Urbana. USEnet: ...!ihnp4!uiucdcs!ccvaxa!aglew ARPAnet: aglew@gswd-vms
aglew@ccvaxa.UUCP (03/27/86)
Talking about the IFs that want to merge different paths back together, g-rh@cca.UUCP writes: > I went on to outline a schematic suggestion for using flags and >Jem wasn't happy with that. Frankly, I'm not enthusiastic about flags >either. The real difficulty is that there is not good solution to the >problem which can be roughly stated as follows: Given a net of if-then-else >logic in which a functional block of code occurs more than once, how do >you structure the code? Some possible solutions are: > >(a) Duplicate the block >(b) Replace the block by a procedure >(c) Replace the block by a macro >(d) Separate the logic structure and the executable structure, > using flags to control the execution >(e) Programming tricks based on language syntax To these we can also add (f) using GOTOs if the paths of execution converge. A side comment drawn from kolstad@convex.UUCP on net.cse >Style: I graded the first two assignments and inserted style >suggestions -- the students were horrified that I would eliminate 7 >boolean variables and if statements in favor of a single >forward-escaping goto. They heard that no one did that! Oh well. >Most students used PASCAL; two or three used C. Some did get better >stylistically; some did not. GOTOs are not EVIL; they are a tool that can be used in structured programming just as any other tool. They are a tool that is frequently misused, sufficiently so that you should always think three times before using a GOTO, (just like you should always think twice before using a gun, but sometimes you may have to) but sometimes they are the best thing to do. structured programming != GOTOless programming.
g-rh@cca.UUCP (Richard Harter) (03/30/86)
In article <> aglew@ccvaxa.UUCP writes: > >Talking about the IFs that want to merge different paths back together, >g-rh@cca.UUCP writes: > >> I went on to outline a schematic suggestion for using flags and >>Jem wasn't happy with that. Frankly, I'm not enthusiastic about flags >>either. The real difficulty is that there is not good solution to the >>problem which can be roughly stated as follows: Given a net of if-then-else >>logic in which a functional block of code occurs more than once, how do >>you structure the code? Some possible solutions are: >> >>(a) Duplicate the block >>(b) Replace the block by a procedure >>(c) Replace the block by a macro >>(d) Separate the logic structure and the executable structure, >> using flags to control the execution >>(e) Programming tricks based on language syntax > >To these we can also add > (f) using GOTOs >if the paths of execution converge. > >GOTOs are not EVIL; they are a tool that can be used in structured programming >just as any other tool. They are a tool that is frequently misused, >sufficiently so that you should always think three times before using a GOTO, >(just like you should always think twice before using a gun, but sometimes >you may have to) but sometimes they are the best thing to do. > >structured programming != GOTOless programming. Au contraire, "structured programming" == GOTOless programming. Well structured programming, on the other hand ... :-). Personally, I have no objection to GOTOs -- I average about one GOTO per 10,000 lines of code in languages like C and PL/I. In general, I find that GOTOs come up as a generalized escape statement, i.e. you have a block of code that has multiple routes out of the block. The usual solution is to set up the code as a procedure and use the return statement as a generalized escape statement; however this doesn't work if there is a cleanup sequence to execute before leaving the routine. I would like to have the following structures available: BLOCK label_name { ..... } LOOP label_name { ..... } FRAGMENT label_name { ..... } A FRAGMENT is essentially an internal procedure without arguments; a BLOCK is a labelled block of code; and a LOOP is a labelled (forever) loop. The command statement that I want is: escape [(block/loop)_label_name] [via fragment_name] This statement transfers control to the next statement after the block (loop) but first executes the named fragment. If there is no block/loop label name the escape leaves the current block/loop. If there is no via clause control is transferred directly to the next statement. Every once in a while I find that I would really like to have something like this available. To return to the issue originally under discussion, I agree that GOTOs ought to be listed among the alternatives but I don't think that they are appropriate in the kind of situation originally presented. GOTOs are useful as an ultimate escape statement. In my opinion they are not advisable if you merely mean to conditionally skip blocks of code. Richard Harter, SMDS Inc.
aglew@ccvaxa.UUCP (04/02/86)
>/* Written 11:12 am Mar 25, 1986 by db@cstvax.UUCP in ccvaxa:net.lang */ >In article <6843@boring.UUCP> lambert@boring.UUCP (Lambert Meertens) writes: >>In article <800009@ccvaxa> aglew@ccvaxa.UUCP writes: >>> but if Z is not simply a function call then you have to make sure that two >>> copies of code get updated. That's what macros are for [...] >> >>Some languages have "refinements", which are somewhat like macros but they >>really are part of the language and do not get expanded by a preprocessor. > >Isn't it simpler to have a parameterless procedure with no local variables >and a compiler that recognises such things? Maybe with pragmas giving the >user control over the optimisation if you want it? True in principal, but the problems are conceptual as well as implementation. Z may depend on a lot of the environment in which it is called, so a parameterless procedure will not work unless you have dynamic binding. Dynamic binding has a whole slew of other problems, not the least of which is efficiency; however, probably the most important one is that programmers make more bugs in dynamic binding systems (no source for this statement) Properly parametrizing a Z procedure is a pain. People don't handle more than 5 independent parameters well. If you read the article about Knowledge-Based Emacs in SIGPLAN(?) a while back, you've encountered `cliches' - I think that cliches are simply (macro) procedures with an inconveniently large number of parameters. >Procedures handle sequential abstraction fine. Want you seem to be after >is greater control over the way they're implemented. You don't have to >allocate a new frame on the stack just because you call a procedure, if >there is nothing to put in it! > >Maybe I've spent too long programming in functional languages, where you >have to do things like this (and tail recursion optimisation similarly) >to get decent performance. Is my big problem with functional languages - they may be better for expressing higher-level algorithms, but what good are they if I have to tie myself in knots for what I already know how to do. > > Dave Berry. CS postgrad, Univ. of Edinburgh > ...mcvax!ukc!cstvax!db Andy "Krazy" Glew. Gould CSD-Urbana. USEnet: ...!ihnp4!uiucdcs!ccvaxa!aglew ARPAnet: aglew@gswd-vms
savage@ssc-vax.UUCP (Lowell Savage) (04/04/86)
The discussion was "structured programming" and goto's in code. Richard Harter proposed a "new" type of programming language feature to take care of the case where goto's are most commonly used in HOL's. This case is (for those who have not been following the discussion or have forgotten by now), to use a goto statement to 'escape' from several levels of nested block and control structures. > ... I would like to have the following structures available: > > BLOCK label_name { > ..... > } > > LOOP label_name { > ..... > } > > FRAGMENT label_name { > ..... > } > > A FRAGMENT is essentially an internal procedure without arguments; > a BLOCK is a labelled block of code; and a LOOP is a labelled (forever) > loop. The command statement that I want is: > > escape [(block/loop)_label_name] [via fragment_name] > > This statement transfers control to the next statement after the > block (loop) but first executes the named fragment. If there is > no block/loop label name the escape leaves the current block/loop. > If there is no via clause control is transferred directly to the > next statement. Every once in a while I find that I would really > like to have something like this available. I beleve that Ada provides such a facility (with an "exit" statement which can take arguments that are block names) only without the FRAGMENT capability. If there is some set of code that needs to be executed before the block is exited, then that code can come before the exit statement. However, Ada also provides another mechanism which I think can be used for complete purpose intended by Richard. This is the exception mechanism. The FRAGMENT is now the statements after the exception handler, and the "exit" or "escape" statement is now the Ada "RAISE" statement which raises some exception known only within that block of code. > > Richard Harter, SMDS Inc. I am not associated with Ada in any way except as a former (and not very thorough) student of it. And as a potential user of it. Ada flames will not be appreciated if they only contain the SOT (Same Old Thing). Lowell Savage, Boeing Aerospace Co. Ada is a trademark of the Joint Ada Office of the DoD (I think). My opinions will reflect those of my employer, my SA, or other entities capable of "reflecting opinions" only if such entity pays me enough to agree to release my opinions for such "reflection".
aglew@ccvaxa.UUCP (04/04/86)
> To return to the issue originally under discussion, I agree >that GOTOs ought to be listed among the alternatives but I don't >think that they are appropriate in the kind of situation originally >presented. GOTOs are useful as an ultimate escape statement. In my >opinion they are not advisable if you merely mean to conditionally >skip blocks of code. > > Richard Harter, SMDS Inc. I agree that gotos are useful as escapes. I also agree that they are not advisable for conditional _skipping_ of blocks of code. I would also add that they are useful for _merging_ of separate flows of control. Can anyone give me a reference for Knuth's article that I referred to earlier? I hate it when I know that somebody said this much better than I did somewhere else, and I can't remember where.