develooper Front page | perl.perl5.porters | Postings from January 2018

Future::AsyncAwait and sub signatures

Thread Next
From:
Paul "LeoNerd" Evans
Date:
January 18, 2018 02:06
Subject:
Future::AsyncAwait and sub signatures
Message ID:
20180118020642.196dd937@shy.leonerd.org.uk
TL;DR: A suggestion on how to let `async sub`s use perl's normal
       signatures


Now that I've got a basic implementation of async/await working nicely
on 5.24+ and also recently (via a large amount of #ifdefs) back as far
as 5.18+, I'm now starting to think about what to do next.

One obvious missing feature right now that would be nice to add, would
be to allow `async sub` on 5.{whatever recent} to use the same
signature syntax that regular subs can use on that same version. Right
now that doesn't happen.

For example, this won't compile even on 5.24:

  async sub usd_from_btc($btc) {
    my $rate = await lookup_exchange_rate("BTC:USD");
    return $btc * $rate;
  }

The reason for this is that I can't just call into the parser to let it
parse the entire `sub NAME SIGNATURE BLOCK` syntax, because of one
small but crucial bit: I need access to the optree *before* the
{threader checker thingy whose name I currently forget} has got to it. I
have to reshape it a little, in the code around

  https://metacpan.org/source/PEVANS/Future-AsyncAwait-0.12/lib/Future/AsyncAwait.xs#L1127

Because of this, it means I don't currently recognise any attributes or
signatures.

Attributes I'm slightly less concerned about currently, as they only
really have nicely-defined properties on named subs, and a lot of
`async sub`s tend to be anonymous ones anyway. Also such attributes as
`:lvalue` really don't make sense on Future-returning async subs.

However, signature support is something I'm keen not to lose here. I
know I could reimplement some signature-like code myself, but I don't
want to do that when it's not the "core reason" for my module. I want
to get perl's regular parser to do that for me. Doing that though needs
some more work.

My original thought was that I'd need some hooks into the parser to ask
it to parse and generate the optree fragment related to the signature
for me. However, I'd then just have to build up a longer call sequence
into doing that anyway, and it starts to look like I just implement
ever more of the parser myself.

I wonder if a different approach might work, of giving core a new hook
variable that it can pass the entire sub's optree into after it has
parsed the topmost block of it but before it passes that into
newATTRSUB() to actually build the real CV out of it. Such a hook would
probably be called by core in some fashion like

  optree = (*PL_sub_body_hook)(aTHX_ optree);

A default implementation of this hook would just be the identity
function on the optree, and callers could (temporarily) hook into this
in the usual way by chaining prior callers.

This would give me an easy way to adjust the optree to my own needs,
while still invoking the regular parser in the regular way so that
attributes and signatures work as expected for the perl version.


Does that sound like something p5p could support?

Alternatively, if it sounds too powerful or invasive, would anyone be
able to suggest a different method I can let my users have `async sub`s
with signatures?

Thanks,

-- 
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk      |  https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/  |  https://www.tindie.com/stores/leonerd/

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About