from Hacker News

Goto in Python

by wallunit on 9/21/15, 6:57 AM with 43 comments

  • by david-given on 9/21/15, 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 mrsirduke on 9/21/15, 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 simgidacav on 9/21/15, 9:29 AM

  • by tveita on 9/21/15, 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 polemic on 9/21/15, 10:07 AM

  • by moretti on 9/21/15, 11:48 AM

    Here's another Python 3 compatible implementation: https://github.com/cdjc/goto
  • by ssanderson11235 on 9/21/15, 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 veddox on 9/21/15, 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 Veedrac on 9/21/15, 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 ainiriand on 9/21/15, 7:54 AM

    WHY?! Good experiment anyway, well done.
  • by WalterBright on 9/21/15, 9:53 AM

    goto is sometimes the right tool for the job.
  • by csl on 9/21/15, 11:40 AM

    Nice. But does it handle extended jumps?

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