Goto (Posting On Python-List Prohibited)

bartc bc at freeuk.com
Sun Dec 31 14:29:03 EST 2017


On 31/12/2017 17:06, Chris Angelico wrote:
> On Mon, Jan 1, 2018 at 3:55 AM, bartc <bc at freeuk.com> wrote:
>>> The suggestion was to use them to avoid gotos.  If duplicating is a good
>>> idea (and it's a hard line to draw) then we are not talking about the
>>> same cases.  Given the choice of "dragging in named functions" and
>>> dragging in named blocks and gotos, I would choose the functions every
>>> time.
>>
>>
>> The blocks don't need to be dragged; they are already in place!
>>
>> It's funny because in c.l.c you're always advocating keep declarations as
>> close to the point of use as possible. Here you appear to be saying the
>> opposite: taking code away from the primary point of use.
> 
> I don't understand the issue here. All you need to do is add a "def"
> statement header in front of the block of code. And maybe indent it
> further, although if you're unifying "if/elif" subtrees, that'll
> cancel out the indentation level change. The block of code stays at or
> near its first use.

You'll need to give an example I think. Suppose I start with this:

def fn(a):
     if a==1:
         print ("One")
         print ("Two")
         print ("Three")
     elif a==2:
         print ("Four")
     else:
         print ("Other")
         print ("One")
         print ("Two")
         print ("Three")

I want to share the lines that print One Two Three, so I create an 
inline function, defined as close as possible to the original code:

def fn2(a):
     if a==1:
         def F123():
             print ("One")
             print ("Two")
             print ("Three")
         F123()
     elif a==2:
         print ("Four")
     else:
         print ("Other")
         F123()

However, if I call this with fn2(3), it says that variable F123 has not 
been assigned.

(I'm not sure what overheads are associated with nested functions. 
Presumably its byte-code is done once, but is there any other setup of 
F123 associated with each call of fn2()? Even when a==2 so that F123() 
is not called?

A brief test [not using print()] showed it was a little slower having 
F123 inside fn2() - and outside the if-statement to make it work - than 
having F123 outside. And having to call F123() anyway instead of just 
having the inline code makes it a little slower too.

Although this would need to be balanced by the cost of the alternative, 
whether a goto or whatever.)

Note also that a goto, and a function call, don't do the same thing. The 
function will return, the goto won't. In my example all paths will 
return, in others this will have to be taken care of.

-- 
bartc












  Don't forget that after turning a block into a def-function in-place, 
it will need to be followed by a call to it:

   if X:
      A
      B
      C
   elif ...
   else:
      A
      B
      C

This becomes:

    if X:
       def F():
          A
          B
          C
       F()
    elif...
    else
       F()

(Is the def statement executed once during byte-code compilation? Or can 
it give different result each time depending on what globals are visible 
within F? Will there at least be a set-up overhead for F each time


Note that calling a local function is not quite a drop-in replacement for


> Once again, Bart, you're scorning something that you don't have much
> (any?) experience with. Look at how the feature is used before you
> hate on it.
> 
> ChrisA
> 




More information about the Python-list mailing list