Raku / problem-solving

šŸ¦‹ Problem Solving, a repo for handling problems that require review, deliberation and possibly debate
Artistic License 2.0
70 stars 16 forks source link

Using multiple named arguments gives different result than just supplying value alone; specific example of `splice`. #423

Closed jubilatious1 closed 6 months ago

jubilatious1 commented 7 months ago

Using multiple named arguments gives different result than just supplying value alone; specific example of splice.

ā€¦

In answering a StackOverflow Question, I was trying to show the reader the ease with which a Perl answer ( by \@choroba) could be translated into Raku. From there I wanted to help non-Perl people understand the answer without having to refer to the docs page. This is where things went screwy.

Sample Input:

1
2
3
banana
5
6
7
banana
9
10
11

My Raku translation of \@choroba's Perl answer is as follows ('sliding window' ...delete sentinel line and two lines before):

~$ raku -ne 'BEGIN my @lines;
               @lines.push: $_;
               @lines.splice( *-3, 3)  if /banana/;
             END .put for @lines;'   file
1
5
9
10
11

So that's all well and good, and \@choroba's Perl code gives the same answer as my Raku code. But when I try to add named arguments, I get the wrong answer back:

~$ raku -ne 'BEGIN my @lines;
               @lines.push: $_;
               @lines.splice( start => *-3,  elems => 3)  if /banana/;
             END .put for @lines;'   file
9
10
11

So...perplexing. The code becomes much more "self-documenting" if named arguments (a.k.a. "adverbs") are included. But if I include them for newbies to read, the wrong answer is returned.

(Note, I believe this is a different issue than #419 , because multiple named arguments are causing the error).

Link to StackOverflow Answer below, thanks.

https://unix.stackexchange.com/a/774599/227738

ā€¦

@pmichaud @thoughtstream @TimToady

vrurg commented 7 months ago

There is very simple answer to your question: splice takes no named arguments. Thus, both nameds are plain ignored in your second example. On top of it, despite the docs are calling the first positional $start, in Rakudo source code corresponding parameter is $offset.

In your comment to #419 there is a reference to the R language experience. But Raku is not R. And it doesn't have to be.

ab5tract commented 6 months ago

A quick way to make it more self-documenting would be to assign the parameter values to variables, either at the call-site or prior:

~$ raku -ne 'BEGIN my @lines;
               @lines.push: $_;
               @lines.splice(my $start = * - 3,  my $elems = 3)  if /banana/;
             END .put for @lines;'   file

or

~$ raku -ne 'BEGIN my @lines; my $offset = * - 3; my $elems = 3; 
               @lines.push: $_;
               @lines.splice($offset,  $elems)  if /banana/;
             END .put for @lines;'   file

@vrurg For the purposes of splice functionality, calling it offset or start can probably be considered equivalent.

vrurg commented 6 months ago

For the purposes of splice functionality, calling it offset or start can probably be considered equivalent

@ab5tract it can, for sure. But would the feature of mapping nameds into correspondingly named positionals be there then particular naming becomes important. My point was that relying on the positional names as provided in the documentation isn't the right thing to do.

Otherwise I'm closing this issue. Thanks @jubilatious1 for raising it as it may help newbies in the future to better understand these peculiarities of Raku.

jubilatious1 commented 6 months ago

@ab5tract wrote:

raku -ne 'BEGIN my @lines; my $offset = * - 3; my $elems = 3; @lines.push: $_; @lines.splice($offset, $elems) if /banana/; END .put for @lines;'

I don't believe the BEGIN block (above) works to execute all three statements. Just the first.

ab5tract commented 6 months ago

Ah, yes. It needs to become a block rather than a thunk, which is to say: curly brackets required.

Or just use two thunks, to taste.

jubilatious1 commented 6 months ago

@ab5tract wrote:

Ah, yes. It needs to become a block rather than a thunk, which is to say: curly brackets required. Or just use two thunks, to taste.

Seems to be a problem: curly braces don't seem to work:


 admin@mbp ~ % raku -ne 'BEGIN { my @lines; my $offset = * - 3; my $elems = 3 };
               @lines.push: $_;
               @lines.splice($offset,  $elems)  if /banana/;
             END .put for @lines;'  file
===SORRY!=== Error while compiling -e
Variable '@lines' is not declared.  Did you mean '&lines'?
at -e:2
------>                ā@lines.push: $_;
admin@mbp ~ % raku -ne '{ BEGIN my @lines; my $offset = * - 3; my $elems = 3 };
               @lines.push: $_;
               @lines.splice($offset,  $elems)  if /banana/;
             END .put for @lines;'  file
===SORRY!=== Error while compiling -e
Variable '@lines' is not declared.  Did you mean '&lines'?
at -e:2
------>                ā@lines.push: $_;
admin@mbp ~ % 
jubilatious1 commented 6 months ago

Could someone explain to me why this Issue was closed without a single "Language Designer" chiming in?

[ ...ot knocking anyone here, but I feel the Issue should remain Open until our "Language Designers" have had a chance to comment ].

Thanks.

@pmichaud @thoughtstream @TimToady

niner commented 6 months ago

@jubilatious1 the 3 people you keep tagging have all long been inactive in Raku (for multiple years). I would kindly ask you to stop tagging them.

The issue has been closed as one of the currently active core developers determined that the language is behaving as designed. The issue you pointed out was simply a user error - your code was plain wrong and that's why you did not get the result you expected.

The underlying language design question is again whether named and positional arguments are interchangeable. In Raku's language design the choice was to keep those separate. As this is a very fundamental choice with wide ranging consequences (e.g. they have different effects with regards to multi dispatch) this is highly unlikely to change.

Anyway it's really the same discussion as https://github.com/Raku/problem-solving/issues/419 so this can be considered a duplicate.

jubilatious1 commented 6 months ago

@niner, sorry to dispute your assertion, but \@\pmichaud has chimed-in quite recently, on another problem-solving issue. And indeed I recall some commentary from \@\thoughtstream --but possibly a few months back.

Expectations: if you're advocating respect for all users of Raku, then at a minimum I'd expect some sort of 'Design-Document' analysis (possibly from @raiph, our resident historian), to provide the correct historical context. I'd expect this sort of analysis to be done before "Closing" an issue, which seems rather drastic.

Finally, if you could help out with the BEGIN block problems I've encountered (either here or on the mailing list), I would appreciate it very much. If it's a mis-understanding on my part I'd like to know the correct path forward (I don't see a reason to open a separate Issue as of yet).

Thank you.

raiph commented 6 months ago

Hi @jubilatious1

at minimum, I'd expect this sort of analysis to be done before "Closing" an issue, which seems rather drastic.

FWIW, back when this repo was first proposed, my understanding of it was that, at minimum, that sort of analysis would be done before opening a problem solving issue. And, even more basic, my understanding was that it would be deemed rather drastic to even consider opening an issue unless there was already broad consensus that we needed such an issue to be opened.

I get that that's not where things have ended up, but please imagine that the truth might be somewhere between what I've described and where things actually are.

niner commented 6 months ago

@jubilatious1 please keep in mind that we are a community of volunteers. Nobody is obliged to do anything. Thus the burden is on the one seeking the change to show not only the benefits coming from that change but also that any downsides can be mitigated. If your arguments are so compelling that others join the effort, than that's great and even a sign that you might be onto something. But again, it is on you to convince people.

The respect argument easily goes both ways. If you respect the language designers and developers who have put in countless hours to give you this language for free, you will show that you have done the research to back your proposal, i.e. demonstrate how it fits in the design, refute previously made arguments on this topic (you will find them most probably on the mailing list and in the design documents) and show how it would work in practice even with existing code.

In general, please refer to the rules for this repository for how the problem-solving process is supposed to work.

ab5tract commented 6 months ago

@jubilatious1 wrote:

Seems to be a problem: curly braces don't seem to work:



 admin@mbp ~ % raku -ne 'BEGIN { my @lines; my $offset = * - 3; my $elems = 3 };

               @lines.push: $_;

               @lines.splice($offset,  $elems)  if /banana/;

             END .put for @lines;'  file

===SORRY!=== Error while compiling -e

Variable '@lines' is not declared.  Did you mean '&lines'?

at -e:2

------>                ā@lines.push: $_;

admin@mbp ~ % raku -ne '{ BEGIN my @lines; my $offset = * - 3; my $elems = 3 };

I actually meant the BEGIN {...} form but, as you've experienced, it won't work without pre-declaring the variables. That is, the my variables will be defined only within the scope of that {...} unless you add another line declaring them first:

BEGIN my ($offset, $elems, @lines); # only needs to be BEGIN prefixed because the code runs every line, not needed in "normal" code BEGIN { $offset = *-3; $elems = 3 }

More appropriate for your use case is probably:

BEGIN my ($offset, $elems, @lines) = (*-3, 3, []);

Note that the @lines needs to go last or else it will swallow the RHS arguments. It also doesn't need to be assigned [], but it's up to taste whether you wish to include it.

BEGIN my ($offset, $elems, @lines) = (*-3, 3);

Hope it helps!

jubilatious1 commented 6 months ago

@ab5tract thanks for the pointers!

As you note, you can't really 'pre-declare' variables before a BEGIN block when you're already sitting in the loop created by the -ne (or -pe) command line flags. I've taken to using andthen to declare variables in separate 'clauses'. Combining your suggestion with pre-existing habits I get the following:

~ % raku -ne 'BEGIN my ($offset, $elems) = (*-3, 3) andthen my @lines;
               @lines.push: $_;
               @lines.splice($offset,  $elems)  if /banana/;
             END .put for @lines;'   file
1
5
9
10
11

Again, thanks for the tips. Cheers.

niner commented 6 months ago

I think you just want no strict;

raku -ne 'no strict; ($offset, $elems) = (*-3, 3);
               @lines.push: $_;
               @lines.splice($offset,  $elems)  if /banana/;
             END .put for @lines;
jubilatious1 commented 5 months ago

@niner wrote:

I think you just want no strict;

I've strictly avoided any mention of strict in my StackExchange answers, as a matter of principle:

https://unix.stackexchange.com/search?q=user%3A227738+%22Using+Raku%22

raiph commented 5 months ago

@jubilatious1

I've strictly avoided any mention of strict in my StackExchange answers, as a matter of principle

I found that confusing at various levels. Some things I thought:


Ultimately Raku has strict on by default so there actually is no good reason to mention it. So if what you meant was that your ideal would have been not to mention it then I would understand and agree with that.

About the only time I'd ever have expected strict to be mentioned is in the form no strict;, because having Raku's strict off is ideal for almost all short programs (less than a screenful).


Note that, unlike, say, Perl's strict, Raku's strict doesn't control barewords (which aren't allowed in Raku, as if Perl's strict was always on, as it should be). Nor does it control symbolic refs (which are always even more strictly controlled in Raku than in Perl even when Perl's strict is enabled).

Raku's strict, or rather no strict;, only controls one aspect: it reduces what amounts to boilerplate required when introducing variables in very short programs. While one can always write $foo::bar = 42 without predeclaring $foo::bar, regardless of whether use strict; or no strict; is in effect (as with Perl), one can't write $bar = 42 without predeclaring $bar unless no strict; is in effect (same as in Perl, but Perl defaults to no strict; for all programs).


The original design intent was that Raku's strict would only be disabled by default for -e. But presumably no one had the time to implement it for 6.c, or to discuss it properly, or it was discussed properly but the consensus was to keep it disabled for -e for 6.c.

FWIW, unless there was a clear consensus against it, I would support a PR disabling strict for -e for 6.e.

jubilatious1 commented 5 months ago

@raiph wrote:

So then I searched your posts for "strict". And it turned out you had mentioned strict. So why did you write that you hadn't, whether or not it was about principle?

You're not serious, are you? I mentioned in a single 2021 post that strict is ON by default in Raku, which alleviates the need to write use strict in Raku scripts and one-liners. An improvement over Perl, widely agreed-upon and a settled issue:

"The -eflag tells Raku to expect a 'one-liner' program (and not, for example, the name of a script file), with strict enabled by default. The -p flag runs the code linewise autoprinting the `$` topic variable at the end of each line."_

https://unix.stackexchange.com/a/684288

Above is the sort of conversational introduction you'd give to someone unfamiliar with Raku. But that's only one answer out of about 500. So maybe 0.2% of my answers have mentioned strict in Raku, hardly anything to write home about.

(Do a search for strict and you'll only get 10 results out of ~500, including setting strict => True in the Text::CSV module).


Thanks for noting that I mistakenly posted my U & L StackExchange profile instead of my Raku posts within that profile. I've updated my earlier post accordingly.

https://unix.stackexchange.com/search?q=user%3A227738+%22Using+Raku%22

raiph commented 5 months ago

@jubilatious1

You're not serious, are you?

Yes. I didn't know you didn't mean to link your profile. I just read what you wrote and clicked on the link you provided. I thought you may have meant people to search your SO answers. So I searched your SO answers for "strict". (Isn't that a reasonable thing to have done? What would you have done?)

As you say, there were 10 results. I glanced through the results page, saw a couple of answers that discussed strict (including one from this year) and stopped looking further at that point.

(All of this took perhaps 30 seconds or so, much less time than it's taking to write any comments. I had no idea you'd written hundreds of answers until you just said so. That's a heck of a lot!)

strict is ON by default in Raku, which alleviates the need to write use strict in Raku scripts and one-liners.

You are clearly implying strict being on for one-liners is a good thing, not a problem. We disagree. Why do you say "alleviates" for one liners?

An improvement over Perl, widely agreed-upon and a settled issue

I agree that Raku being "strict by default" is a widely agreed-upon and settled issue, where by "being strict by default" is as I explained in my previous comment.

But strict specifically being OFF for one liners was definitely a widely agreed-upon and settled issue back in the day. What changed?

The -e flag tells Raku to expect a 'one-liner' program

Sure. And per Raku's design docs:

Scaling is one of those areas where [Raku] needs to be multiparadigmatic and context sensitive. Perl 5 code is not strict by default, while [Raku] code is. But it should be easy to relax with -e or the 'no strict' pragma:

perl -e '$x = 1'

and

#!/usr/bin/perl
no strict;
$x = 1;

The above is from S01 and represents some of the first few sentences Larry ever wrote about Raku.

And the design team repeated this point perhaps a decade later in S11:

In any of those cases, strictures and warnings are the default in your main program. To start it in lax mode, start it with

no strict;

(Invoking [raku] with -e has the same effect.)


I remain permanently open minded and hearted about all manner of folk and their ideas about whatever, including Raku. But we all need to connect, and make good decisions, based on maximizing understanding and respect of each others' current views and gaining clarity about what is actually true vs what is supposed or surmised and discussing what is reasonable and possible and what our options are. Ultimately we need to strive to routinely arrive at consensus without fighting.

Unless I have misunderstood something, in the last year or two, your relationship with Raku and/or with me seem to have shifted from openness and joy to increasingly closed down and fraught. Do you feel that way too? In addition, I continue to recall with warmth what I think was our original exchanges. Do you feel that way too? Regardless of feelings now, I hope at least you and I can get back on track, back to that space, even if something has indeed permanently shifted for you relative to Raku.

While writing this I decided to look back at what I thought was a relatively in-depth "meeting" I thought we had via email to see if it was as I recalled it, and see if it inspired in me some way to try reset our relationship. I realized a couple things immediately. First, I don't actually know if the person I met via email is you. The identities are different and I don't know why I thought you were the same person. Second, I found some replies I never completed/sent. They were from late April 2020. Covid crashed into my life then, reorienting my activity for the next couple years. So I'm guessing the exchange I was having fell victim to that. Anyhow, I've decided to send one of them that is coherent as it stands, albeit cut off mid-thought part way through. If you get it, then please reply and confirm the email address and the @jubilatious1 nick belong to one and the same person. And if so, hi again, and I hope my reply from 4 years ago makes sense, and that we can reconnect in the spirit we then had! šŸ˜Š

If it turns out you're not the same person, I will think of some other way to try reboot our relationship grounded in a common love for Raku šŸ¦‹, or at least grounded in love of all beings. šŸ’š

lizmat commented 5 months ago

But strict specifically being OFF for one liners was definitely a widely agreed-upon and settled issue back in the day. What changed?

That was not the final verdict in my recollection. And this was changed before Christmas.

lizmat commented 5 months ago

The commit in question: https://github.com/rakudo/rakudo/commit/6120b009e3

raiph commented 5 months ago

@lizmat

But strict specifically being OFF for one liners was definitely a widely agreed-upon and settled issue back in the day. What changed?

That was not the final verdict in my recollection. And this was changed before Christmas.

Ah. OK. All things change, so fair enough. šŸ˜Š I think I missed that happening. Thanks for the comment/link.

FCO commented 5 months ago

Could we have an different flag to imply no strict? Maybe -E?