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

PEVANS Grant Report January 2024

0 views
Skip to first unread message

Paul "LeoNerd" Evans

unread,
Feb 9, 2024, 1:15:05 PMFeb 9
to Perl5 Porters
It will hopefully not come as much of a surprise that I now have a TPRF
grant too for core development work. Part of the requirements for that
is posting monthly reports on progress and time being spent. So here's
what I've been working on during January (plus the end of December that
got missed off the previous report)

My first time writing one of these so hopefully this is sufficient, but
here goes...


Hours:

9 = Updates to the `meta` module, a new CPAN release, adding a ->get
method, adding experimental warnings, ->get_or_add methods
https://metacpan.org/pod/meta
https://github.com/Perl/PPCs/blob/main/ppcs/ppc0022-metaprogramming.md

3 = Initial investigation into implementing PPC0019 "Quoted template
strings"
https://github.com/Perl/PPCs/blob/main/ppcs/ppc0019-qt-string.md

7 = Getting `use VERSION` to import a feature bundle
https://github.com/Perl/perl5/pull/21850

1.5 = Adding builtin::inf and builtin::nan
https://github.com/Perl/perl5/pull/21872

5 = Improvements to PADNAMEf_TOMBSTONE handling
https://github.com/Perl/perl5/pull/21887

3 = Lexical subroutine shadow warnings
https://github.com/Perl/perl5/pull/21915

Total: 28.5 hours.

--
Paul "LeoNerd" Evans

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

Darren Duncan

unread,
Feb 15, 2024, 11:15:04 PMFeb 15
to perl5-...@perl.org
My own thoughts on what are good design...

For actual mutable objects such as these are, the writer methods should return
void, as they are statements and not expressions.

Were we talking about immutable objects such that a "setter" is actually a
shorthand for creating a new object with the same fields as the invocant but for
one field value being changed, then it should return the new object. But this
doesn't apply here.

Personally I'm a strong advocate for immutable objects where one sets all the
fields at initial construction time, and not using chained mutators.

I'm not going to argue strongly against a chained mutator design, but that's my
preference to not encourage it.

Another thing to consider though is if you want to be conservative then making
mutators void in the initial version is safest because you're providing the
simplest functionality one can rely on. You can choose to later have them
return the invocant to support chaining mutators, but you can't change chaining
to void later without breaking things.

-- Darren Duncan

On 2024-02-14 1:42 a.m., Ruud H.G. van Tol via perl5-porters wrote:
>
> On 2024-02-12 17:45, Ovid wrote:
>> [...]
>> The only caveat is I realize the team never came to an agreement about what
>> the :writer would return. Some insist upon the invocant (chaining mutators)
>> while others want void. Returning a true value or previous value were minority
>> opinions.
>>
>
> Some general remarks:
>
> Chaining is mostly only good for configuration and setup contexts.
>
> You generally start out with a copy of a default configuration, as an object,
> and then specialize it.
> Once specialized enough, you call something like $task->run, to put the
> configuration to use, to solidify it, to finish it.
>
> For returning a previous value, explicitly use a get_set method, that itself
> explicitly calls get and then set, as then both get and set can be overridden.
>
> Any writer should return some (established or promised) final state in some way,
> either inside the underlying (log-)object, or directly. Avoid global variables.
>
>
> -- Ruud
>
>
> Random chaining example:
>
> my $sql= SQL -> from(t1 => "X") -> join(t2 => "Y", -on => {"t2.[% t1.name_lc
> %]_id" => "t1.id"}) -> where(...) -> select(...) -> group_by(...) -> having(...)
> -> order_by(...);
>
> my $rv= $sql -> prepare(...);
>
> if ($rv->err) {
>     ...;
> }
> else {
>     $rv= $sql -> execute;
> }
>

Darren Duncan

unread,
Feb 16, 2024, 12:00:05 AMFeb 16
to perl5-...@perl.org
Replying to myself...

Actually, if we have constructors with named arguments, then really what is the
benefit of having chained mutators, if people desire those as an object
initialization pattern?

So I say just make auto-generated :writer mutators void, developers should use
named constructor args instead, and in what hopefully are rare cases where one
might justify chained mutators, they could just declare those as regular methods
rather than auto-generated ones.

This combined with the conservative future-proofing I mentioned before, I'm now
more strongly on the side of :writer mutators should return void.

-- Darren Duncan

Paul "LeoNerd" Evans

unread,
Feb 17, 2024, 4:45:05 AMFeb 17
to Darren Duncan, perl5-...@perl.org
On Fri, 16 Feb 2024 15:51:35 -0800
Darren Duncan <dar...@darrenduncan.net> wrote:

> The "void" talk is a colloquialism rather than being literal, it
> means in effect that :writer routines end with "return;", and are
> explicitly not returning a value at all. Meaning that it doesn't
> make sense to invoke them as an expression, just as a statement, so
> no one should be writing "return $self->set_value($x), $x" in the
> first place, so adding a return value would not break anything. Why
> would one be writing that when it doesn't return a value? -- Darren
> Duncan

I've often wanted (as I've written to p5p@ many times) a `:void`
attribute on subs, to warn of such things. Imagine

sub a {}
sub b :void {}
sub c {}

my @x = ( a, b, c );

Pointless call of &main::b in non-void context at FILE line 5.


I just haven't got around to it yet.

Darren Duncan

unread,
Feb 17, 2024, 5:00:04 AMFeb 17
to perl5-...@perl.org
On 2024-02-17 1:38 a.m., Paul "LeoNerd" Evans wrote:
> On Fri, 16 Feb 2024 15:51:35 -0800
> Darren Duncan <dar...@darrenduncan.net> wrote:
>
>> The "void" talk is a colloquialism rather than being literal, it
>> means in effect that :writer routines end with "return;", and are
>> explicitly not returning a value at all. Meaning that it doesn't
>> make sense to invoke them as an expression, just as a statement, so
>> no one should be writing "return $self->set_value($x), $x" in the
>> first place, so adding a return value would not break anything. Why
>> would one be writing that when it doesn't return a value? -- Darren
>> Duncan
>
> I've often wanted (as I've written to p5p@ many times) a `:void`
> attribute on subs, to warn of such things. Imagine
>
> sub a {}
> sub b :void {}
> sub c {}
>
> my @x = ( a, b, c );
>
> Pointless call of &main::b in non-void context at FILE line 5.
>
> I just haven't got around to it yet.

Yes, that would indeed be nice to have, I would use it if it existed, and this
is then what :writer should use.

FWIW, from a general language design perspective, I prefer those languages that
make functions and procedures very structurally different routines in how they
are declared. So functions must return a value and be invoked within
expressions, and procedures must not return a value and must be invoked as
statements. Examples of languages like this include SQL and Pascal. In that
context, there is no "void" result type, instead you have a "procedure".

-- Darren Duncan

Ruud H.G. van Tol via perl5-porters

unread,
Feb 17, 2024, 6:45:04 PMFeb 17
to perl5-...@perl.org

On 2024-02-17 10:51, Darren Duncan wrote:
> FWIW, from a general language design perspective, I prefer those
> languages that make functions and procedures very structurally
> different routines in how they are declared.  So functions must return
> a value and be invoked within expressions, and procedures must not
> return a value and must be invoked as statements. Examples of
> languages like this include SQL and Pascal.  In that context, there is
> no "void" result type, instead you have a "procedure".

A procedure-call can still end in failure,
so it further depends on the definition of "return value".

Some functions use out-of-domain values to return error status.
I don't like that, IMO return value and state must be kept separate.

As Perl subs kan return lists, one could use
the first element for the return value
and the second element for the status:

  my ($rv, $err) = mysub(....);

But then mysub() needs to use wantarray()
(which actually means wantlist())
to find out what it should return.

Procedures generally have side effects.
Procedures can be allowed to change the contents of ("output") parameters,
which is much like a return value.

Functions are cleanest if they don't have side effects.
But for example memoization already blurs that.

-- Ruud

Darren Duncan

unread,
Feb 17, 2024, 7:00:04 PMFeb 17
to perl5-...@perl.org
Yes. I kept things simpler in my statement above. But a more expanded version
is: From a general language design perspective, functions should be pure and
not have side effects, and return values are determined just by arguments.
While anything with side effects would be a procedure, and if that procedure has
outputs to the caller it can be through reference/inout parameters. As for
indicating errors, depending on what one prefers, this could be an output
parameter or a thrown exception. Typically one would expect errors/exceptions
to come from procedures and not functions, unless indicating inappropriate
arguments or divide by zero or out of memory or such. I also don't like the
idea of wantarray/etc and feel if one wants different behavior for different
calling contexts like that they should be separate routines with different
names. Anyway this thread is more of a tangent and I likely won't take the time
to discuss it further. -- Darren Duncan

Paul "LeoNerd" Evans

unread,
Feb 18, 2024, 4:30:05 AMFeb 18
to Lukas Mai, perl5-...@perl.org
On Sun, 18 Feb 2024 10:19:59 +0100
Lukas Mai <lukasmai...@gmail.com> wrote:

> > E.g. use Attribute::Handlers, implement an `apply` attribute on
> > CODE. One of the arguments passed in to the handler for it is the
> > globref for the sub having the attribute applied to it. You can
> > make a new sub and assign it into the globref.
>
> What if it's an anonymous sub?

Ah ;)

Even anonymous subs have GVs, but the way that attributes themselves
currently work means you don't get access to run any on the protosub,
only per closure that gets created.

That's part of a far wider topic of fixes that need looking into as
part of a bigger redesign of attributes in general.
0 new messages