Very impressive and complete explanation, thanks!
> I'm inclined to view it as pretty good. I also think it might be seriously 
> hard to improve.

As we're looking a known "trap" could this one append of those (my favorite 
kind) leading questions "Did you mean to pass ...?"
________________________________
From: Ralph Mellor <ralphdjmel...@gmail.com>
Sent: Sunday, April 18, 2021 11:59 PM
To: Joseph Brenner <doom...@gmail.com>
Cc: perl6-users <perl6-us...@perl.org>
Subject: Re: slurpy hash signatures

CAUTION - EXTERNAL:


On Sun, Apr 18, 2021 at 8:00 PM Joseph Brenner <doom...@gmail.com> wrote:
>
> Before I get started here, a small point about defining hashes.
> There are various ways that work:
>
>    my %h1 = ( 'ha' => 1, 'ho' => 2, 'hum' => 3 );
>    my %h2 = (  ha  => 1,  ho  => 2,  hum  => 3 );
>    my %h3 =  ha => 1, ho => 2, hum => 3;
>    my %h4 = 'ha' => 1, 'ho' => 2, 'hum' => 3;

Idiomatically, %h3 is the clear favorite among those four.

The others are anti-idiomatic.

Raku is forgiving in this case, trying to ease Perl devs into
using Raku, but do not unduly take advantage of Raku's
kindness. Learn to use the right idioms as soon as possible.
Otherwise you'll get outcomes like the perspective you have
on what happens when you pass pairs as arguments.

Btw, another option that's sometimes nice is:

my %h5 = :1week, :2days, :3hours;

(Same as `my %h5 = week => 1, days => 2, hours => 3;`.)

(But generally avoid this idiom when it does not read well,
and note how subs using it will often need to double up
singular and plural versions of named arguments, in this
case week/weeks etc.)

>    say join(' ',
>             %h1{'ho'}, %h2{'ho'}, %h3{'ho'}, %h4{'ho'}
>             );
>    # Output: 2 2 2 2

Idiomatically, use `<...>` subscripts instead. Again, Raku is
forgiving, but don't take advantage of its kindness. Learn to
use the best idiom.

Maybe even `say join ' ', do .<ho> for %h1, %h2, %h3, %h4;`

> Of course, when you're accessing the hash value,
> the key *does* need to be quoted (unlike in perl),

Not at all. As you note yourself, just use `<...>` subscripts.

> And because of this, I keep thinking I need to quote keys

It's not because the key needs to be quoted when you're
accessing keys. Because they don't. You note the solution
yourself.

If you keep thinking you need to quote keys it's for some
other reason.

> I often quote keys without thinking about it

That may get you into trouble if you pass pairs in an argument
list that you intend will be received as named arguments. They
will be received as positional arguments instead.

>     genius( 'ha' => 1, 'ho' => 2, 'hum' => 3 );
>     ## Error: Too many positionals passed; expected 0 arguments but got 3

Great example.

Fortunately, the error message makes it clear you've passed
3 positional arguments when it expected none, immediately
pinpointing where the problem lies:

* If you thought you were passing 3 named arguments, you
  now know you passed 3 positional ones instead.

* If you thought you were passing 3 positional arguments, you
  now know the sub doesn't expect them.

> So: when passing pairs to a sub, quoting the key causes things to barf

No, quoting keys when passing pairs to a sub does *not* cause it to barf:

sub church(*%fried, *@frab) { say %fried, @frab }
church( 'ha' => 1, ho => 2, 'hum' => 3 );
## Output: {ho => 2}[ha => 1 hum => 3]

Works beautifully.

Larry deliberately distinguished pairs passed as arguments based
on whether their keys were or weren't quoted. If they're unquoted,
they're named arguments. If they're quoted, they're positional.

He did a similar thing for putting pairs in parens:

sub church(*@frab) { say @frab }
church( 'ha' => 1, (ho => 2, hum => 3) );
## Output: [ha => 1 ho => 2 hum => 3]

> and the messaging is seriously LTA.

Well, it's surprising to you, because you aren't familiar with
named vs positional arguments. If you were, the message
would instantly clue you into the fact your pairs have been
received as positional arguments instead of as named ones.

I'm not convinced the error message is seriously LTA. I'm
inclined to view it as pretty good. I also think it might be
seriously hard to improve. Perhaps a champion (you?)
might step up to the plate to explore how the message
might be improved, but I think it might be really hard to
improve that message alone in a meaningful way.

I can think of one way that would work and have a much
better payoff. It would still require a champion, but there's
a much greater chance of finding and motivating them.

The short version of it is the idea that error messages can
link to doc pages. So if this error message occurs, there's
a link to a doc page matching the error. That page can then
discuss things at length, covering all the various reasons
why the too many positionals or too many nameds messages
might appear, and all the ways to fix things.

> (The pair operator is being demoted to a fat comma?)

The pair syntax is allowing you to express whether you
want to pass a pair as a positional or a named argument.

Both are useful, so it's useful to be able to express both.
Which do you want?

--
raiph
CAUTION - EXTERNAL EMAIL: This email originated outside the Judiciary. Exercise 
caution when opening attachments or clicking on links.

Reply via email to