Goto in Python

by walluniton 9/21/2015, 6:57 AMwith 43 comments

by david-givenon 9/21/2015, 9:13 AM

Hey, awesome! And it produces a true goto as well, working on the bytecode level. I wonder if there's a way to remove the extra nops?

This is really, really useful for doing language-to-language translation. Without the ability to arbitrarily branch from basic block to basic block, it's possible for the basic block graph produced by a program in one language to be simply inexpressible in your target language. You end up having to fake it with a while loop and switch statement, which has horrible performance implications.

(Emscripten has some exotic algorithms to try and express the source program's basic block graph using the target language's structured programming constructs. This is vitally important to make goto-less Javascript perform well, but it can't work in all cases, and some C functions will force Emscripten to fall back to loop-and-switch. And, of course, these functions are typically the ones which have been carefully hand-optimised for speed...)

by mrsirdukeon 9/21/2015, 8:49 AM

The technique used to implement this is rather interesting, and the implementation itself[1] is very understandable.

I'm sure neither should be used in a production project.

[1]: https://github.com/snoack/python-goto/blob/master/goto.py

by simgidacavon 9/21/2015, 9:29 AM

https://www.xkcd.com/292/

Sorry, I had to.

by tveitaon 9/21/2015, 2:15 PM

This is cute but of course horribly unsafe since it doesn't respect control statements.

Some examples you'd expect to work that will crash the interpreter:

  @with_goto
  def fun1():
   while True:
    for x in [1]:
     goto .next
    label .next
  
  @with_goto
  def fun2():
   goto .next
   for x in [1]:
    label .next
  
  @with_goto
  def fun3():
   while True:
    try:
     goto .next
    finally:
     print('skipped')
    label .next

by polemicon 9/21/2015, 10:07 AM

Incidentally, from 2009: http://code.activestate.com/recipes/576944-the-goto-decorato...

And presented at KiwiPycon 2014: https://www.youtube.com/watch?v=DdU8I09BGsU

by morettion 9/21/2015, 11:48 AM

Here's another Python 3 compatible implementation: https://github.com/cdjc/goto

by ssanderson11235on 9/21/2015, 5:17 PM

If you're interested in this sort of thing, you might also check out https://github.com/llllllllll/codetransformer, which is a general-purpose library for doing these sorts of shenanigans in an almost-sane way. (Disclaimer: I'm one of the library authors).

As an example, I've got a PR open right now that lets you do things like:

    @mutable_locals
    def f():
        out = []
        x = 1
        out.append(x)
        locals().update({'x': 2, 'y': 3})
        out.append(x)
        out.append(y)
        return out

    assert f() == [1, 2, 3]
which works using a combination of ctypes hackery and replacing all LOAD_FAST instructions with appropriately-resolved LOAD_NAME instructions.

by veddoxon 9/21/2015, 9:06 AM

47 years after Dijkstra's "Go To Statement Considered Harmful"[1], the Structured Programming Wars flare up again on Hacker News :D

Neat hack, though.

[1] http://www.u.arizona.edu/~rubinson/copyright_violations/Go_T...

by Veedracon 9/21/2015, 8:45 AM

I was aware of the April Fools version.

The idea that it needs optimizing, no doubt because someone's using it in a hot code, is hilarious. That's either the best satire or the worst truth I've heard all day.

by ainiriandon 9/21/2015, 7:54 AM

WHY?! Good experiment anyway, well done.

by WalterBrighton 9/21/2015, 9:53 AM

goto is sometimes the right tool for the job.

by cslon 9/21/2015, 11:40 AM

Nice. But does it handle extended jumps?

I know this is a problem for at least the Byteplay module.