Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Pre-RFC: A built-in ability for lexical import/export

1 view
Skip to first unread message

Paul "LeoNerd" Evans

unread,
Jun 24, 2022, 12:00:04 PM6/24/22
to Perl5 Porters
One of the offshoots from the Pre-RFC rejections of the `module` and
`UNIVERSAL::import` ideas, was the thought that perl core really needs
to provide some nicer ways to implement lexical import into the
caller's lexical namespace.

Core didn't really have any code that does lexical import of normal
symbols, so when I created the `builtin::import` function I had to
create it all specially. It's fine there but feels a bit weird not
providing that as a general mechanism for others to use.

I was thinking that maybe it should be just exposed as a builtin::
function itself, perhaps as

builtin::lexically_export $name, \&func;

Perhaps it should take a whole kv-list of name/ref pairs, so you can
export lots in one go:

builtin::lexically_export
one => \&one,
two => \&two, ...

Though maybe it would be bad to encourage that because really the
caller ought to be specifying just a few symbols they want. Hmm.

Also, while syntactically this is written out "like a normal function"
and thus could go in `builtin::`, I wonder if it's a good fit here. It
can only possibly work during BEGIN time, because it affects the
compiletime lexical environment of the code being compiled. It isn't
useful at runtime. It syntactically looks like a regular function but
it doesn't really behave like one.

We probably do want this available as a core function, but what should
it be named? Is `builtin::` still a good place to put it?

--
Paul "LeoNerd" Evans

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

Paul "LeoNerd" Evans

unread,
Jun 27, 2022, 9:45:03 AM6/27/22
to Perl5 Porters
On Fri, 24 Jun 2022 16:44:27 +0100
"Paul \"LeoNerd\" Evans" <leo...@leonerd.org.uk> wrote:

> I was thinking that maybe it should be just exposed as a builtin::
> function itself, perhaps as
>
> builtin::lexically_export $name, \&func;

I've had a bit of a go at implementing this:

https://github.com/leonerd/perl5/tree/lexically-export

> Perhaps it should take a whole kv-list of name/ref pairs, so you can
> export lots in one go:
>
> builtin::lexically_export
> one => \&one,
> two => \&two, ...

It currently doesn't do this yet, but shouldn't be hard to add.


In the process of writing it I've come up with some more questions, to
which I don't have an easy answer:

* Should it support things other than functions? Should we support

lexically_export VAR => \my $scalar;

* If so, should names be sigil-prefixed?

lexically_export '$VAR' => \my $scalar, '&func' => sub {...};

While I don't think it is common to want to export things other than
functions, it does occasionally happen (e.g. think the $LOG variable of
various logger modules, or the $METRICS of Metrics::Any). It would be
nice to support these in some way.

If we do support them, it raises the question on whether the "name"
argument to lexically_export() itself should include the sigil part of
it. In the vastly-common majority of cases, they'll all just be
functions, so it feels annoying to have to '&'-prefix them all -
especially if it would otherwise break the neat way of using
"name => \&name" notation.

On the other hand, it would lead to an awkward situation if you wanted
to export more than one item of the same basename:

lexically_export
FOO => \my $s, FOO => \my @arr, FOO => \my %hash, FOO => sub {};

This would technically be fine as it would create four separately named
items in the caller - $FOO, @FOO, %FOO and &FOO (callable as FOO()).
But it does feel strange, and breaks the otherwise neat hash-like
name/value pair structure of the arguments. I'm not sure I like it.

Instead, perhaps a compromise idea taken from the way Exporter.pm
works; which is to say that sigils would be required for
scalar/hash/array variables, but not required for regular functions.

lexically_export
name => \&function, # a regular function
'$VAR' => \my $scalar, # a scalar variable
'@VAR' => \my @arr, # an array variable
'%VAR' => \my %hash, # a hash variable

'&func' => \&func, # also permitted for symmetry, but not
# required

I.e. the model being "if no sigil is specified, presume &"; and
additionally, error if the sigil doesn't match the thing being
referenced.


I think this feels sane - does anyone disagree?

G.W. Haywood via perl5-porters

unread,
Jun 27, 2022, 11:15:04 AM6/27/22
to Perl5 Porters
Hi there,

On Mon, 27 Jun 2022, Dagfinn Ilmari Mannsåker wrote:
> "Paul \"LeoNerd\" Evans" writes:
>> On Fri, 24 Jun 2022 16:44:27 +0100 "Paul \"LeoNerd\" Evans" wrote:
>>
>> ...
>> ...
>> * Should it support things other than functions? Should we support
>>
>> lexically_export VAR => \my $scalar;
>
> Yes.

Agreed.

>> * If so, should names be sigil-prefixed?
>>
>> lexically_export '$VAR' => \my $scalar, '&func' => sub {...};
>
> Yes ...

Agreed.

--

73,
Ged.

Paul "LeoNerd" Evans

unread,
Jun 27, 2022, 11:45:03 AM6/27/22
to perl5-...@perl.org
On Mon, 27 Jun 2022 14:40:15 +0100
"Paul \"LeoNerd\" Evans" <leo...@leonerd.org.uk> wrote:

> > Perhaps it should take a whole kv-list of name/ref pairs, so you can
> > export lots in one go:
> >
> > builtin::lexically_export
> > one => \&one,
> > two => \&two, ...
>
> It currently doesn't do this yet, but shouldn't be hard to add.

Update: it now does this.
>
> In the process of writing it I've come up with some more questions, to
> which I don't have an easy answer:
>
> * Should it support things other than functions? Should we support
>
> lexically_export VAR => \my $scalar;

And this.

> * If so, should names be sigil-prefixed?
>
> lexically_export '$VAR' => \my $scalar, '&func' => sub {...};

And this.

> I.e. the model being "if no sigil is specified, presume &"; and
> additionally, error if the sigil doesn't match the thing being
> referenced.

And this.

> I think this feels sane - does anyone disagree?

Thanks all for the comments (here and IRC).

Next (meta)-question: Should this be turned into a full RFC, or is it
small and concise enough that these questions and any subsequent
discussion on a PR would be sufficient?

In the hope it's the latter, I've now opened a PR for merging it:

https://github.com/Perl/perl5/pull/19895

but if people think this should go via the full RFC process first, I
can write something up.

Martijn Lievaart

unread,
Jun 27, 2022, 2:00:03 PM6/27/22
to perl5-...@perl.org

Op 27-06-2022 om 15:40 schreef Paul "LeoNerd" Evans:
> On Fri, 24 Jun 2022 16:44:27 +0100
> "Paul \"LeoNerd\" Evans" <leo...@leonerd.org.uk> wrote:
>
>> I was thinking that maybe it should be just exposed as a builtin::
>> function itself, perhaps as
>>
>> builtin::lexically_export $name, \&func;
> I've had a bit of a go at implementing this:
>
> https://github.com/leonerd/perl5/tree/lexically-export
>
>> Perhaps it should take a whole kv-list of name/ref pairs, so you can
>> export lots in one go:
>>
>> builtin::lexically_export
>> one => \&one,
>> two => \&two, ...
> It currently doesn't do this yet, but shouldn't be hard to add.
>

What I do not understand is why one would want to use a different
external name than the internal name? Exporter doesn't work like this
and I for one, never felt the need to export under a different name.


TIA,

M4


Paul "LeoNerd" Evans

unread,
Jun 27, 2022, 4:00:03 PM6/27/22
to perl5-...@perl.org
On Mon, 27 Jun 2022 19:46:54 +0200
Martijn Lievaart <m...@rtij.nl> wrote:

> What I do not understand is why one would want to use a different
> external name than the internal name? Exporter doesn't work like this
> and I for one, never felt the need to export under a different name.

I'm not sure I follow the question...

Martijn Lievaart

unread,
Jun 27, 2022, 5:00:03 PM6/27/22
to perl5-...@perl.org
Op 27-06-2022 om 21:45 schreef Paul "LeoNerd" Evans:
> On Mon, 27 Jun 2022 19:46:54 +0200
> Martijn Lievaart <m...@rtij.nl> wrote:
>
>> What I do not understand is why one would want to use a different
>> external name than the internal name? Exporter doesn't work like this
>> and I for one, never felt the need to export under a different name.
> I'm not sure I follow the question...
>

If I understand the proposal correctly, you could do:

builtin::lexically_export two => \&one;

builtin::lexically_export three => \&two;


Why not implement:

builtin::lexically_export '\&one';

And have that export the sub one() under the name 'one'?


TIA,
M4



Paul "LeoNerd" Evans

unread,
Jun 28, 2022, 10:30:05 AM6/28/22
to perl5-...@perl.org
On Tue, 28 Jun 2022 10:29:06 +0100
Neil Bowers <ne...@neilb.org> wrote:

> > Next (meta)-question: Should this be turned into a full RFC, or is
> > it small and concise enough that these questions and any subsequent
> > discussion on a PR would be sufficient?
>
> I think this should go via an RFC. The idea is that changes to the
> language should go through the RFC process, and the process should be
> able to handle both heavy- and light-weight proposals.

Alrighty. Now written at

https://github.com/Perl/RFCs/pull/20
0 new messages