Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #93972 > unrolled thread

Proposed keyword to transfer control to another function

Started byChris Angelico <rosuav@gmail.com>
First post2015-07-17 09:46 +1000
Last post2015-07-22 03:38 +1000
Articles 12 — 7 participants

Back to article view | Back to comp.lang.python


Contents

  Proposed keyword to transfer control to another function Chris Angelico <rosuav@gmail.com> - 2015-07-17 09:46 +1000
    Re: Proposed keyword to transfer control to another function Paul Rubin <no.email@nospam.invalid> - 2015-07-17 20:16 -0700
    Re: Proposed keyword to transfer control to another function Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2015-07-19 11:32 +1200
      Re: Proposed keyword to transfer control to another function Chris Angelico <rosuav@gmail.com> - 2015-07-19 10:21 +1000
      Re: Proposed keyword to transfer control to another function Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2015-07-19 12:05 -0400
      Re: Proposed keyword to transfer control to another function Chris Angelico <rosuav@gmail.com> - 2015-07-20 02:13 +1000
      Re: Proposed keyword to transfer control to another function MRAB <python@mrabarnett.plus.com> - 2015-07-19 17:24 +0100
      Re: Proposed keyword to transfer control to another function Chris Angelico <rosuav@gmail.com> - 2015-07-20 02:32 +1000
      Re: Proposed keyword to transfer control to another function Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-07-19 17:41 +0100
      Re: Proposed keyword to transfer control to another function Chris Angelico <rosuav@gmail.com> - 2015-07-20 02:50 +1000
      Re: Proposed keyword to transfer control to another function Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2015-07-21 19:33 +0200
      Re: Proposed keyword to transfer control to another function Chris Angelico <rosuav@gmail.com> - 2015-07-22 03:38 +1000

#93972 — Proposed keyword to transfer control to another function

FromChris Angelico <rosuav@gmail.com>
Date2015-07-17 09:46 +1000
SubjectProposed keyword to transfer control to another function
Message-ID<mailman.617.1437090408.3674.python-list@python.org>
Out of the lengthy thread on tail call optimization has come one broad
theory that might be of interest, so I'm spinning it off into its own
thread.

The concept is like the Unix exec[vlpe] family of functions: replace
the current stack frame with a new one. This can be used for explicit
tail recursion without repeated stack frames, or for a pre-check that
then disappears out of the stack. Like any other feature, it can be
misused to make debugging difficult, but among consenting adults,
hopefully it can be used sensibly.

Examples:

# derived from Paul Rubin's example
def quicksort(array, start, end):
     midp = partition(array, start, end)
     if midp <= (start+end)//2:
        quicksort(array, start, midp)
        transfer quicksort(array, midp+1, end)
     else:
        quicksort(array, midp+1, end)
        transfer quicksort(array, start, midp)

def count_usage(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        wrapper.usage += 1
        transfer func(*args, **kwargs)
    wrapper.usage = 0
    return wrapper

Semantics:
* Evaluate the function and all its arguments, exactly as per a
current function call.
* Leaving them on the stack, remove the current call frame and dispose
of all its objects.
* Finally, construct a new stack frame for the target function and
transfer control to it.

In effect, "transfer f()" is equivalent to "return f()", except that
the current function finishes before the target is entered.

Note that this is incompatible with 'try' and 'with' blocks, and is
disallowed inside them. It may be safe to use 'transfer' from a
'finally' block, and possibly from an 'except' block that isn't
followed by a 'finally', but otherwise, there's code to be executed
after the target returns, ergo it can't be done with a direct
transfer.

Open for bikeshedding: What should the keyword be? We can't use
"exec", which would match Unix and shell usage, because it's already
used in a rather different sense in Python. Current candidates:
"transfer", "goto", "recurse", and anything else you suggest.

Possible alternate syntax:

transfer func[, (arg1, arg2, arg3)[, {'kw1': val1, 'kw2': val2}]]

This makes it very clear that this is NOT accepting an arbitrary
expression, but MUST be used with a single function and its arguments.
Downside: It doesn't look like a function call any more. Upside: It's
easy to parse. Also, if the argument sequence is mandatory instead of
optional, this doesn't conflict with the simpler syntax (which
wouldn't be allowed to have a comma after it), so one can be added now
and another added later, if necessary.

Is there anything that I've missed out in speccing this up? I've a
suspicion that this might turn out to be as complicated as 'yield
from' in all its handling of edge cases.

ChrisA

[toc] | [next] | [standalone]


#94048

FromPaul Rubin <no.email@nospam.invalid>
Date2015-07-17 20:16 -0700
Message-ID<87lheeyx2q.fsf@jester.gateway.sonic.net>
In reply to#93972
Chris Angelico <rosuav@gmail.com> writes:
> # derived from Paul Rubin's example
> def quicksort(array, start, end):
>      midp = partition(array, start, end)

Heh, forgot to include the base case, as someone pointed out.  Oh well,
it's pseudocode, or something.

>         transfer quicksort(array, midp+1, end)

Overall I like the idea but though it doesn't seem terribly important in
the scheme of things.  

I think the syntax has converged to "return from" which seems good to me.

> Note that this is incompatible with 'try' and 'with' blocks, and is

Maybe something can be done about that.

> Is there anything that I've missed out in speccing this up? I've a
> suspicion that this might turn out to be as complicated as 'yield
> from' in all its handling of edge cases.

Seems worthy of more thought.

[toc] | [prev] | [next] | [standalone]


#94069

FromGregory Ewing <greg.ewing@canterbury.ac.nz>
Date2015-07-19 11:32 +1200
Message-ID<d1060jF9h2gU1@mid.individual.net>
In reply to#93972
Chris Angelico wrote:
> Possible alternate syntax:
> 
> transfer func[, (arg1, arg2, arg3)[, {'kw1': val1, 'kw2': val2}]]
> 
> This makes it very clear that this is NOT accepting an arbitrary
> expression, but MUST be used with a single function and its arguments.
> Downside: It doesn't look like a function call any more. Upside: It's
> easy to parse.

Personally I'd be fine with your initial syntax, but
something else might be needed to get it past Guido.
He didn't like my 'cocall f()' construct in PEP 3152,
which is syntactically isomorphic to 'transfer f()'.

> Is there anything that I've missed out in speccing this up? I've a
> suspicion that this might turn out to be as complicated as 'yield
> from' in all its handling of edge cases.

Presumably it would only work on functions implemented
in Python? It's no use discarding the Python stack frame
unless the C recursion in the ceval loop can be avoided
as well.

> Current candidates:
> "transfer", "goto", "recurse", and anything else you suggest.

Another possibility is "chain", which I've seen in some
contexts for an sh exec-like operation.

-- 
Greg

[toc] | [prev] | [next] | [standalone]


#94076

FromChris Angelico <rosuav@gmail.com>
Date2015-07-19 10:21 +1000
Message-ID<mailman.690.1437265299.3674.python-list@python.org>
In reply to#94069
On Sun, Jul 19, 2015 at 9:32 AM, Gregory Ewing
<greg.ewing@canterbury.ac.nz> wrote:
> Chris Angelico wrote:
>>
>> Possible alternate syntax:
>>
>> transfer func[, (arg1, arg2, arg3)[, {'kw1': val1, 'kw2': val2}]]
>>
>> This makes it very clear that this is NOT accepting an arbitrary
>> expression, but MUST be used with a single function and its arguments.
>> Downside: It doesn't look like a function call any more. Upside: It's
>> easy to parse.
>
>
> Personally I'd be fine with your initial syntax, but
> something else might be needed to get it past Guido.
> He didn't like my 'cocall f()' construct in PEP 3152,
> which is syntactically isomorphic to 'transfer f()'.

Maybe it should get written up and rejected, then, to be something to
point to any time anyone advocates TCO.

>> Is there anything that I've missed out in speccing this up? I've a
>> suspicion that this might turn out to be as complicated as 'yield
>> from' in all its handling of edge cases.
>
>
> Presumably it would only work on functions implemented
> in Python? It's no use discarding the Python stack frame
> unless the C recursion in the ceval loop can be avoided
> as well.

Hmm. Conceptually, I'd like it to work like this:

def f(x):
    return from g(x+1)

x = f(3)
# absolutely identical to
x = g(4)

Is it possible to strip away the current Python stack frame and
replace it with a C stack frame? That would be the most logical, if
it's viable. It'd also mean that other Python implementations are all
looking at things on the same footing. Obviously 'return from' (or
whatever keyword is used) would be valid only from a Python function,
but ideally it could chain to a function written in any form.

>> Current candidates:
>> "transfer", "goto", "recurse", and anything else you suggest.
>
>
> Another possibility is "chain", which I've seen in some
> contexts for an sh exec-like operation.

Hah, that brings me back! "Chaining was attempted from a REXX batch
file". I never understood why typing the name of a batch file would do
a one-way chain/exec rather than a more logical call. Unix has that
much better.

Downside: The name "chain" is highly likely to exist in people's code.
I'm liking "return from", as it's currently illegal, uses existing
keywords, and parallels with "yield from". But as a term for
describing what happens, "chain" works well.

ChrisA

[toc] | [prev] | [next] | [standalone]


#94125

FromDennis Lee Bieber <wlfraed@ix.netcom.com>
Date2015-07-19 12:05 -0400
Message-ID<mailman.720.1437321936.3674.python-list@python.org>
In reply to#94069
On Sun, 19 Jul 2015 11:32:35 +1200, Gregory Ewing
<greg.ewing@canterbury.ac.nz> declaimed the following:

>
>Another possibility is "chain", which I've seen in some
>contexts for an sh exec-like operation.

	Think I've only seen CHAIN used in some BASICs to load another program
overtop the running one. Used it on my college data structures course --
assignment was a hashed-head multiple-linked list, and we were told we
could implement it in "any language <the instructor> understood" (he never
made that mistake again: he got BASIC, FORTRAN-IV, COBOL, and Sigma-6
assembly; only APL and SNOBOL weren't accepted). The BASIC only allowed for
4 open files in a program, and it was easier to invoke separate programs
for the phases of the assignment (a phone-book, hashed on names).

	I've only seen one other application using HHMLL -- and that was the
Amiga file system.
-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
    wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

[toc] | [prev] | [next] | [standalone]


#94127

FromChris Angelico <rosuav@gmail.com>
Date2015-07-20 02:13 +1000
Message-ID<mailman.721.1437322446.3674.python-list@python.org>
In reply to#94069
On Mon, Jul 20, 2015 at 2:05 AM, Dennis Lee Bieber
<wlfraed@ix.netcom.com> wrote:
>         I've only seen one other application using HHMLL -- and that was the
> Amiga file system.

Okay, I'll bite. What does HHMLL stand for? Google didn't answer my
question instantly with the first result, like it usually does. I even
got desperate [1] but no luck.

ChrisA

[1] https://xkcd.com/1334/

[toc] | [prev] | [next] | [standalone]


#94128

FromMRAB <python@mrabarnett.plus.com>
Date2015-07-19 17:24 +0100
Message-ID<mailman.722.1437323277.3674.python-list@python.org>
In reply to#94069
On 2015-07-19 17:13, Chris Angelico wrote:
> On Mon, Jul 20, 2015 at 2:05 AM, Dennis Lee Bieber
> <wlfraed@ix.netcom.com> wrote:
>>         I've only seen one other application using HHMLL -- and that was the
>> Amiga file system.
>
> Okay, I'll bite. What does HHMLL stand for? Google didn't answer my
> question instantly with the first result, like it usually does. I even
> got desperate [1] but no luck.
>
HHMLL stands for "hashed-head multiple-linked list", a phrase from a little
earlier in the post.

[toc] | [prev] | [next] | [standalone]


#94129

FromChris Angelico <rosuav@gmail.com>
Date2015-07-20 02:32 +1000
Message-ID<mailman.723.1437323537.3674.python-list@python.org>
In reply to#94069
On Mon, Jul 20, 2015 at 2:24 AM, MRAB <python@mrabarnett.plus.com> wrote:
> On 2015-07-19 17:13, Chris Angelico wrote:
>>
>> On Mon, Jul 20, 2015 at 2:05 AM, Dennis Lee Bieber
>> <wlfraed@ix.netcom.com> wrote:
>>>
>>>         I've only seen one other application using HHMLL -- and that was
>>> the
>>> Amiga file system.
>>
>>
>> Okay, I'll bite. What does HHMLL stand for? Google didn't answer my
>> question instantly with the first result, like it usually does. I even
>> got desperate [1] but no luck.
>>
> HHMLL stands for "hashed-head multiple-linked list", a phrase from a little
> earlier in the post.

D'oh. I skimmed the post, looking for expressions matching that, and
somehow missed it. Of course, it's right there when I go back and
check again. I'm pretty sure the universe is out to gaslight me some
days, particularly the days when my proposals end up indecisive. Which
one of them is, today. This does not bode well.

ChrisA

[toc] | [prev] | [next] | [standalone]


#94132

FromMark Lawrence <breamoreboy@yahoo.co.uk>
Date2015-07-19 17:41 +0100
Message-ID<mailman.726.1437324305.3674.python-list@python.org>
In reply to#94069
On 19/07/2015 17:24, MRAB wrote:
> On 2015-07-19 17:13, Chris Angelico wrote:
>> On Mon, Jul 20, 2015 at 2:05 AM, Dennis Lee Bieber
>> <wlfraed@ix.netcom.com> wrote:
>>>         I've only seen one other application using HHMLL -- and that
>>> was the
>>> Amiga file system.
>>
>> Okay, I'll bite. What does HHMLL stand for? Google didn't answer my
>> question instantly with the first result, like it usually does. I even
>> got desperate [1] but no luck.
>>
> HHMLL stands for "hashed-head multiple-linked list", a phrase from a little
> earlier in the post.
>

I want one in the stdlib on the grounds that I like the name :)

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence

[toc] | [prev] | [next] | [standalone]


#94133

FromChris Angelico <rosuav@gmail.com>
Date2015-07-20 02:50 +1000
Message-ID<mailman.727.1437324630.3674.python-list@python.org>
In reply to#94069
On Mon, Jul 20, 2015 at 2:41 AM, Mark Lawrence <breamoreboy@yahoo.co.uk> wrote:
> On 19/07/2015 17:24, MRAB wrote:
>>
>> On 2015-07-19 17:13, Chris Angelico wrote:
>>>
>>> On Mon, Jul 20, 2015 at 2:05 AM, Dennis Lee Bieber
>>> <wlfraed@ix.netcom.com> wrote:
>>>>
>>>>         I've only seen one other application using HHMLL -- and that
>>>> was the
>>>> Amiga file system.
>>>
>>>
>>> Okay, I'll bite. What does HHMLL stand for? Google didn't answer my
>>> question instantly with the first result, like it usually does. I even
>>> got desperate [1] but no luck.
>>>
>> HHMLL stands for "hashed-head multiple-linked list", a phrase from a
>> little
>> earlier in the post.
>>
>
> I want one in the stdlib on the grounds that I like the name :)

I like the name Rachel, too, but I don't want her in the stdlib :)

ChrisA

[toc] | [prev] | [next] | [standalone]


#94303

FromAntoon Pardon <antoon.pardon@rece.vub.ac.be>
Date2015-07-21 19:33 +0200
Message-ID<mailman.825.1437499992.3674.python-list@python.org>
In reply to#94069
On 07/19/2015 02:21 AM, Chris Angelico wrote:
> On Sun, Jul 19, 2015 at 9:32 AM, Gregory Ewing
> <greg.ewing@canterbury.ac.nz> wrote:

>> Personally I'd be fine with your initial syntax, but
>> something else might be needed to get it past Guido.
>> He didn't like my 'cocall f()' construct in PEP 3152,
>> which is syntactically isomorphic to 'transfer f()'.
> 
> Maybe it should get written up and rejected, then, to be something to
> point to any time anyone advocates TCO.

Those who remember the history of pep 308 will not find
that a strong deterrent.

[toc] | [prev] | [next] | [standalone]


#94305

FromChris Angelico <rosuav@gmail.com>
Date2015-07-22 03:38 +1000
Message-ID<mailman.826.1437500296.3674.python-list@python.org>
In reply to#94069
On Wed, Jul 22, 2015 at 3:33 AM, Antoon Pardon
<antoon.pardon@rece.vub.ac.be> wrote:
> On 07/19/2015 02:21 AM, Chris Angelico wrote:
>> On Sun, Jul 19, 2015 at 9:32 AM, Gregory Ewing
>> <greg.ewing@canterbury.ac.nz> wrote:
>
>>> Personally I'd be fine with your initial syntax, but
>>> something else might be needed to get it past Guido.
>>> He didn't like my 'cocall f()' construct in PEP 3152,
>>> which is syntactically isomorphic to 'transfer f()'.
>>
>> Maybe it should get written up and rejected, then, to be something to
>> point to any time anyone advocates TCO.
>
> Those who remember the history of pep 308 will not find
> that a strong deterrent.

It doesn't have to be a deterrent. It just has to say "Here's all the
arguments we came up with in 2015, so find answers to those if you
want to reopen the debate". It's effectively a way of rapidly
onboarding the conclusions from a lengthy discussion, much more easily
than pointing someone to the archive and expecting him/her to read
through it all.

ChrisA

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web