'goto', as an indicator of good language

H. S. Teoh hsteoh at qfbox.info
Thu Sep 8 22:43:58 UTC 2022


On Thu, Sep 08, 2022 at 09:30:06PM +0000, Dukc via Digitalmars-d wrote:
> On Thursday, 8 September 2022 at 21:03:04 UTC, H. S. Teoh wrote:
> > The `goto` of today's languages is a much safer, de-fanged version
> > of the original goto. In D, for example, you cannot `goto` out of a
> > function (or into another). The compiler also doesn't let you skip
> > variable initializations / destructions. So it's subject to pretty
> > much the same constraints as "structured" constructs like if, while,
> > for, switch, etc., except it's more low-level and can do a few more
> > things that the other constructs can't do.
> 
> Well if I really wanted to I could do it in 60s style by putting
> everything inside a giant `switch(callStack.pop)` in `main()`.
> "functions" would be just `goto` labels, called like this:
> 
> ```D
> callStack.push(something);
> goto function;
> case something:
> ```
> 
> ...with a jump to the switch at end of each "function" body.

Still can't get around variable initializations / destructions. ;-)

Plus, if your code ever interacts with mine, it would not be able to
willy-nilly goto into my function, no matter what other atrocities it's
committing inside main().  In 60s style code, you'd just `lea` to get
the address of the target function, perform pointer arithmetic, and
`jmp` to the destination, whether or not the callee wants to be called
that way or not. :-D  Fortunately, such nonsense is blocked at the
language level.


> So `goto` does technically have as long fangs as always :D. Of course,
> modern languages do a good job encouraging better coding habits.

Well, that's kinda an unfair way to look at it. I mean, if I *really*
wanted to write code like the above, I don't even need `goto`; it
suffices to just write something like this:

	void main() {
		int state = 1;
		int globalVar;
		switch (state) {
			case 1:
				doSomething();
				globalVar++;
				state = 5;
				break;
			case 2:
				doSomethingElse();
				globalVar--;
				state = 3;
				break;
			case 3:
				doYetSomethingElse();
				globalVar += 2;
				state = 6;
				break;
			case 4:
				blahblahblah();
				globalVar -= 2;
				state = 1;
				break;
			case 5:
				andSoOn();
				globalVar *= 2;
				state = 2;
				break;
			case 6:
				justForKicks();
				globalVar /= 3;
				state = uniform(1, 7);
				break;
		}
	}

I mean, I could write an assembly language emulator in main(), and write
the worst possible random-jump-ridden, self-mutating virus code that
main() would execute, but that doesn't mean D is inherently bad because
it's possible to do so.


T

-- 
"Real programmers can write assembly code in any language. :-)" -- Larry Wall


More information about the Digitalmars-d mailing list