[net.lang] and if you put this in your languag

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.