AV API thoughts: AVs as proxies for other things

[email protected] ("Paul \"LeoNerd\" Evans") Thu, 11 Jun 2026 11:31:21 +0100
Newsgroups perl.perl5.porters
Message-ID <[email protected]>
Here's a loose collection of ideas that came to mind while thinking of
how to handle the `av_splice()` API, as observed in
  https://github.com/Perl/perl5/pull/24451
There's no immediate questions to answer or action to perform, but I
wanted to write it out while it's in my head in case it struck and
bells with anyone else, and we manage to come to some eventual plan of
work that might become useful one day...


The currently-last comment in that PR I liked above, is some thinking
out loud on the complicated problem with the C-level API it proposes. 
It observes that if at the C level you call `av_splice(...)` on a given
AV that is tied, there's no guarantee that the Perl `SPLICE` method that
gets invoked returns the right number of deleted items. In particular,
it could return more, which would be too many items for the caller to
account for in the C-level array it passed in for the purpose. Much
trouble. My comment ends with the observation that perhaps a workable
API would be to have three variants of the function, which differ in
the way they pass in or out a list (sequence?) of SVs for the splice
operation. The three variants could use C-level arrays of SV pointers,
perl's AV structures, or the perl data stack.

But the more I thought on this, the more I realise this is definitely
not a design problem specific to `av_splice()`, and could apply
basically anywhere in perl APIs that wants to receive or return lists
of SVs. That's quite a lot. I don't think we'd want three copies of
every single API function that might want to take (or return) a list of
SVs. And of course it gets even worse with things like `av_splice` that
might want to take and return lists in two different forms - do we
write nine variants of that? Madness!

So to avoid all that madness I started thinking that between various
hackery on AVs (things like adjusting AvALLOC, AvMAX and AvREAL), it
would be fairly easy to make an AV that really just acts as a proxy to
a C array directly. A complex function such as `av_splice()` could use
a reduced subset of the AV API to operate on its input and output list
arguments, and not have to care if that AV is actually a proper
perl-level array data structure, or was in fact a proxy to a C array.
Or perhaps even the perl data stack directly. Thus, rather than us
having to write three functions for three variants of "values from AV,
values from C array, values from perl stack", what if everything just
took an AV, but we had a few functions to build little proxy AVs for C
arrays or the perl stack.

For example: Imagine we had an `av_push_av`, which pushes all the
values from a source AV onto the end of its destination AV.

  void av_push_av(AV *av, AV *src);

Well we wouldn't need variants to push from a C array or from the perl
stack, if instead we had some API like

  AV *newAVproxy_array(SV **svs, size_t len);
  AV *newAVproxy_from_stack(size_t count);

then we wouldn't need any other variants of `av_push_av`. We'd just be
able to pass them in a little proxy AV for one of these scenarios, and
all would work out.

  /* push from a C array */
  av_push_av(av, newAVproxy_array(more_svs, count_of_svs));

  /* push the top 5 items from the perl values stack */
  av_push_av(av, newAVproxy_from_stack(5));


There would be a few concerns here: most notably, that any of these
proxy AVs would likely only support some subset of operations. I think
we'd have to distinguish between "source-only AVs" that get looked at
as inputs but not modified; from "sink-only AVs" that accumulate
results but don't need to be read from beforehand. Additionally, there
would need to be some subtle thoughts about how to encode the required
behaviour with refcount bumping and so on. But I think that would be
easily workable within this overall shape.

As I said at the top, this isn't a fully-formed plan, or a set of
questions. I just wanted to write it out while it was in my head, for
future reference in case someone else came to similar ideas before, or
in future looking back at this.

-- 
Paul "LeoNerd" Evans

[email protected]
http://www.leonerd.org.uk/  |  https://metacpan.org/author/PEVANS