* [ruby-core:107900] [Ruby master Bug#18633] proc { |a, **kw| a } autosplats and treats empty kwargs specially
@ 2022-03-14 17:36 Eregon (Benoit Daloze)
2022-03-14 17:41 ` [ruby-core:107903] " Eregon (Benoit Daloze)
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Eregon (Benoit Daloze) @ 2022-03-14 17:36 UTC (permalink / raw
To: ruby-core
Issue #18633 has been reported by Eregon (Benoit Daloze).
----------------------------------------
Bug #18633: proc { |a, **kw| a } autosplats and treats empty kwargs specially
https://bugs.ruby-lang.org/issues/18633
* Author: Eregon (Benoit Daloze)
* Status: Open
* Priority: Normal
* Backport: 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
```ruby
irb(main):005:0> proc { |a| a }.call([1, 2])
=> [1, 2]
irb(main):006:0> proc { |a, **kw| a }.call([1, 2])
=> 1 # should be [1, 2]
irb(main):007:0> proc { |a, kw: 42| a }.call([1, 2])
=> 1 # should be [1, 2]
```
What's the reason for `proc { |a, **kw| a }` to autosplat?
It seems inconsistent with the resolution of #16166, and it seems nobody would want that behavior (it loses arguments but the user extremely likely did not want that).
Could we change it so procs never autosplat, just like `proc { |a| a }`.
My understanding of the change in #16166 is to reflect the fact positional and kwargs are separated, and so adding `**kw` or `kw:` should never change anything if only positional arguments are passed.
This breaks in this case though.
Also I noticed:
```ruby
irb(main):010:0> proc { |a, **kw| a }.call([1, 2])
=> 1
irb(main):011:0> proc { |a, **kw| a }.call([1, 2], **{})
=> [1, 2]
```
Which is really unfortunate as it shows a difference between passing `**{}` or nothing.
AFAIK passing `**{}` or nothing should always be equivalent, but it breaks in this case.
(from https://bugs.ruby-lang.org/issues/16166#note-14)
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 5+ messages in thread
* [ruby-core:107903] [Ruby master Bug#18633] proc { |a, **kw| a } autosplats and treats empty kwargs specially
2022-03-14 17:36 [ruby-core:107900] [Ruby master Bug#18633] proc { |a, **kw| a } autosplats and treats empty kwargs specially Eregon (Benoit Daloze)
@ 2022-03-14 17:41 ` Eregon (Benoit Daloze)
2022-03-14 22:47 ` [ruby-core:107905] " jeremyevans0 (Jeremy Evans)
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Eregon (Benoit Daloze) @ 2022-03-14 17:41 UTC (permalink / raw
To: ruby-core
Issue #18633 has been updated by Eregon (Benoit Daloze).
This is the logic in TruffleRuby, basically we can see the inconsistency and the need for a hack just to support this case:
```java
private boolean shouldConsiderDestructuringArrayArg(Arity arity) {
if (arity.getRequired() == 1 && arity.getOptional() == 0 && !arity.hasRest() && arity.hasKeywordsRest()) {
// Special case for: proc { |a, **kw| a }.call([1, 2]) => 1
// Seems inconsistent: https://bugs.ruby-lang.org/issues/18633
return true;
}
if (!arity.hasRest() && arity.getRequired() + arity.getOptional() <= 1) {
// If we accept at most 0 or 1 arguments, there's never any need to destructure
return false;
} else if (arity.hasRest() && arity.getRequired() == 0) {
// If there are only a rest argument and optional arguments, there is no need to destructure.
// Because the first optional argument (or the rest if no optional) will take the whole array.
return false;
} else {
return true;
}
}
```
Whether a Proc should autosplat besides special case is otherwise not too complicated.
The only runtime checks (in addition to these static checks) are:
* a single argument is passed, and it responds to `#to_ary`.
* if kwargs are passed, no autosplatting
----------------------------------------
Bug #18633: proc { |a, **kw| a } autosplats and treats empty kwargs specially
https://bugs.ruby-lang.org/issues/18633#change-96841
* Author: Eregon (Benoit Daloze)
* Status: Open
* Priority: Normal
* Backport: 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
```ruby
irb(main):005:0> proc { |a| a }.call([1, 2])
=> [1, 2]
irb(main):006:0> proc { |a, **kw| a }.call([1, 2])
=> 1 # should be [1, 2]
irb(main):007:0> proc { |a, kw: 42| a }.call([1, 2])
=> 1 # should be [1, 2]
```
What's the reason for `proc { |a, **kw| a }` to autosplat?
It seems inconsistent with the resolution of #16166, and it seems nobody would want that behavior (it loses arguments but the user extremely likely did not want that).
Could we change it so procs never autosplat, just like `proc { |a| a }`.
My understanding of the change in #16166 is to reflect the fact positional and kwargs are separated, and so adding `**kw` or `kw:` should never change anything if only positional arguments are passed.
This breaks in this case though.
Also I noticed:
```ruby
irb(main):010:0> proc { |a, **kw| a }.call([1, 2])
=> 1
irb(main):011:0> proc { |a, **kw| a }.call([1, 2], **{})
=> [1, 2]
```
Which is really unfortunate as it shows a difference between passing `**{}` or nothing.
AFAIK passing `**{}` or nothing should always be equivalent, but it breaks in this case.
(from https://bugs.ruby-lang.org/issues/16166#note-14)
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 5+ messages in thread
* [ruby-core:107905] [Ruby master Bug#18633] proc { |a, **kw| a } autosplats and treats empty kwargs specially
2022-03-14 17:36 [ruby-core:107900] [Ruby master Bug#18633] proc { |a, **kw| a } autosplats and treats empty kwargs specially Eregon (Benoit Daloze)
2022-03-14 17:41 ` [ruby-core:107903] " Eregon (Benoit Daloze)
@ 2022-03-14 22:47 ` jeremyevans0 (Jeremy Evans)
2022-03-15 20:43 ` [ruby-core:107912] " jeremyevans0 (Jeremy Evans)
2022-03-17 8:46 ` [ruby-core:107941] " matz (Yukihiro Matsumoto)
3 siblings, 0 replies; 5+ messages in thread
From: jeremyevans0 (Jeremy Evans) @ 2022-03-14 22:47 UTC (permalink / raw
To: ruby-core
Issue #18633 has been updated by jeremyevans0 (Jeremy Evans).
Eregon (Benoit Daloze) wrote:
> ```ruby
> irb(main):005:0> proc { |a| a }.call([1, 2])
> => [1, 2]
> irb(main):006:0> proc { |a, **kw| a }.call([1, 2])
> => 1 # should be [1, 2]
> irb(main):007:0> proc { |a, kw: 42| a }.call([1, 2])
> => 1 # should be [1, 2]
> ```
>
> What's the reason for `proc { |a, **kw| a }` to autosplat?
> It seems inconsistent with the resolution of #16166, and it seems nobody would want that behavior (it loses arguments but the user extremely likely did not want that).
> Could we change it so procs never autosplat, just like `proc { |a| a }`.
I agree that there is no reason to autosplat in this case on Ruby 3 (autosplatting made sense in Ruby 2). I changed the `*a, **kw` case in #16166, because that is the case @matz indicated he wanted to change (https://bugs.ruby-lang.org/issues/16166#note-6). @matz didn't indicate he wanted the behavior of `a, **kw` or `a, kw: ` changed, so I didn't make changes to that behavior.
Like #18625, this change seems too risky to backport, and there doesn't seem to be a way to properly deprecate it. So I also recommend we make this change in 3.2 and not backport it.
> Also I noticed:
> ```ruby
> irb(main):010:0> proc { |a, **kw| a }.call([1, 2])
> => 1
> irb(main):011:0> proc { |a, **kw| a }.call([1, 2], **{})
> => [1, 2]
> ```
> Which is really unfortunate as it shows a difference between passing `**{}` or nothing.
> AFAIK passing `**{}` or nothing should always be equivalent, but it breaks in this case.
>
> (from https://bugs.ruby-lang.org/issues/16166#note-14)
At least this behavior is deliberate. We don't want `proc { |a, **kw| a }.call([1, 2], **h)` to result in `a` sometimes being `1` and other times being `[1, 2]` based on the value of `h`. Always using `[1, 2]` for `a` seems fine.
----------------------------------------
Bug #18633: proc { |a, **kw| a } autosplats and treats empty kwargs specially
https://bugs.ruby-lang.org/issues/18633#change-96843
* Author: Eregon (Benoit Daloze)
* Status: Open
* Priority: Normal
* Backport: 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
```ruby
irb(main):005:0> proc { |a| a }.call([1, 2])
=> [1, 2]
irb(main):006:0> proc { |a, **kw| a }.call([1, 2])
=> 1 # should be [1, 2]
irb(main):007:0> proc { |a, kw: 42| a }.call([1, 2])
=> 1 # should be [1, 2]
```
What's the reason for `proc { |a, **kw| a }` to autosplat?
It seems inconsistent with the resolution of #16166, and it seems nobody would want that behavior (it loses arguments but the user extremely likely did not want that).
Could we change it so procs never autosplat, just like `proc { |a| a }`.
My understanding of the change in #16166 is to reflect the fact positional and kwargs are separated, and so adding `**kw` or `kw:` should never change anything if only positional arguments are passed.
This breaks in this case though.
Also I noticed:
```ruby
irb(main):010:0> proc { |a, **kw| a }.call([1, 2])
=> 1
irb(main):011:0> proc { |a, **kw| a }.call([1, 2], **{})
=> [1, 2]
```
Which is really unfortunate as it shows a difference between passing `**{}` or nothing.
AFAIK passing `**{}` or nothing should always be equivalent, but it breaks in this case.
(from https://bugs.ruby-lang.org/issues/16166#note-14)
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 5+ messages in thread
* [ruby-core:107912] [Ruby master Bug#18633] proc { |a, **kw| a } autosplats and treats empty kwargs specially
2022-03-14 17:36 [ruby-core:107900] [Ruby master Bug#18633] proc { |a, **kw| a } autosplats and treats empty kwargs specially Eregon (Benoit Daloze)
2022-03-14 17:41 ` [ruby-core:107903] " Eregon (Benoit Daloze)
2022-03-14 22:47 ` [ruby-core:107905] " jeremyevans0 (Jeremy Evans)
@ 2022-03-15 20:43 ` jeremyevans0 (Jeremy Evans)
2022-03-17 8:46 ` [ruby-core:107941] " matz (Yukihiro Matsumoto)
3 siblings, 0 replies; 5+ messages in thread
From: jeremyevans0 (Jeremy Evans) @ 2022-03-15 20:43 UTC (permalink / raw
To: ruby-core
Issue #18633 has been updated by jeremyevans0 (Jeremy Evans).
I've submitted a pull request to remove the autosplatting: https://github.com/ruby/ruby/pull/5665
----------------------------------------
Bug #18633: proc { |a, **kw| a } autosplats and treats empty kwargs specially
https://bugs.ruby-lang.org/issues/18633#change-96848
* Author: Eregon (Benoit Daloze)
* Status: Open
* Priority: Normal
* Backport: 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
```ruby
irb(main):005:0> proc { |a| a }.call([1, 2])
=> [1, 2]
irb(main):006:0> proc { |a, **kw| a }.call([1, 2])
=> 1 # should be [1, 2]
irb(main):007:0> proc { |a, kw: 42| a }.call([1, 2])
=> 1 # should be [1, 2]
```
What's the reason for `proc { |a, **kw| a }` to autosplat?
It seems inconsistent with the resolution of #16166, and it seems nobody would want that behavior (it loses arguments but the user extremely likely did not want that).
Could we change it so procs never autosplat, just like `proc { |a| a }`.
My understanding of the change in #16166 is to reflect the fact positional and kwargs are separated, and so adding `**kw` or `kw:` should never change anything if only positional arguments are passed.
This breaks in this case though.
Also I noticed:
```ruby
irb(main):010:0> proc { |a, **kw| a }.call([1, 2])
=> 1
irb(main):011:0> proc { |a, **kw| a }.call([1, 2], **{})
=> [1, 2]
```
Which is really unfortunate as it shows a difference between passing `**{}` or nothing.
AFAIK passing `**{}` or nothing should always be equivalent, but it breaks in this case.
(from https://bugs.ruby-lang.org/issues/16166#note-14)
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 5+ messages in thread
* [ruby-core:107941] [Ruby master Bug#18633] proc { |a, **kw| a } autosplats and treats empty kwargs specially
2022-03-14 17:36 [ruby-core:107900] [Ruby master Bug#18633] proc { |a, **kw| a } autosplats and treats empty kwargs specially Eregon (Benoit Daloze)
` (2 preceding siblings ...)
2022-03-15 20:43 ` [ruby-core:107912] " jeremyevans0 (Jeremy Evans)
@ 2022-03-17 8:46 ` matz (Yukihiro Matsumoto)
3 siblings, 0 replies; 5+ messages in thread
From: matz (Yukihiro Matsumoto) @ 2022-03-17 8:46 UTC (permalink / raw
To: ruby-core
Issue #18633 has been updated by matz (Yukihiro Matsumoto).
Should be fixed. Review the patch and merge it if it's OK. @nobu please?
Matz.
----------------------------------------
Bug #18633: proc { |a, **kw| a } autosplats and treats empty kwargs specially
https://bugs.ruby-lang.org/issues/18633#change-96891
* Author: Eregon (Benoit Daloze)
* Status: Open
* Priority: Normal
* Backport: 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
```ruby
irb(main):005:0> proc { |a| a }.call([1, 2])
=> [1, 2]
irb(main):006:0> proc { |a, **kw| a }.call([1, 2])
=> 1 # should be [1, 2]
irb(main):007:0> proc { |a, kw: 42| a }.call([1, 2])
=> 1 # should be [1, 2]
```
What's the reason for `proc { |a, **kw| a }` to autosplat?
It seems inconsistent with the resolution of #16166, and it seems nobody would want that behavior (it loses arguments but the user extremely likely did not want that).
Could we change it so procs never autosplat, just like `proc { |a| a }`.
My understanding of the change in #16166 is to reflect the fact positional and kwargs are separated, and so adding `**kw` or `kw:` should never change anything if only positional arguments are passed.
This breaks in this case though.
Also I noticed:
```ruby
irb(main):010:0> proc { |a, **kw| a }.call([1, 2])
=> 1
irb(main):011:0> proc { |a, **kw| a }.call([1, 2], **{})
=> [1, 2]
```
Which is really unfortunate as it shows a difference between passing `**{}` or nothing.
AFAIK passing `**{}` or nothing should always be equivalent, but it breaks in this case.
(from https://bugs.ruby-lang.org/issues/16166#note-14)
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2022-03-17 8:46 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-03-14 17:36 [ruby-core:107900] [Ruby master Bug#18633] proc { |a, **kw| a } autosplats and treats empty kwargs specially Eregon (Benoit Daloze)
2022-03-14 17:41 ` [ruby-core:107903] " Eregon (Benoit Daloze)
2022-03-14 22:47 ` [ruby-core:107905] " jeremyevans0 (Jeremy Evans)
2022-03-15 20:43 ` [ruby-core:107912] " jeremyevans0 (Jeremy Evans)
2022-03-17 8:46 ` [ruby-core:107941] " matz (Yukihiro Matsumoto)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).