[#99002] [Ruby master Feature#17004] Provide a way for methods to omit their return value — shyouhei@...

Issue #17004 has been reported by shyouhei (Shyouhei Urabe).

21 messages 2020/07/01

[#99044] [Ruby master Bug#17007] SystemStackError when using super inside Module included and lexically inside refinement — eregontp@...

Issue #17007 has been reported by Eregon (Benoit Daloze).

7 messages 2020/07/03

[#99078] [Ruby master Feature#17016] Enumerable#scan_left — finch.parker@...

Issue #17016 has been reported by parker (Parker Finch).

42 messages 2020/07/07

[#99079] [Ruby master Bug#17017] Range#max & Range#minmax incorrectly use Float end as max — bosticko@...

Issue #17017 has been reported by sambostock (Sam Bostock).

25 messages 2020/07/07

[#99097] [Ruby master Bug#17021] "arm64" and "arm" are mixed in RbConfig on Apple silicon — watson1978@...

Issue #17021 has been reported by watson1978 (Shizuo Fujita).

9 messages 2020/07/09

[#99115] [Ruby master Bug#17023] How to prevent String memory to be relocated in ruby-ffi — larskanis@...

Issue #17023 has been reported by larskanis (Lars Kanis).

22 messages 2020/07/10

[#99156] [Ruby master Bug#17030] Enumerable#grep{_v} should be optimized for Regexp — marcandre-ruby-core@...

Issue #17030 has been reported by marcandre (Marc-Andre Lafortune).

25 messages 2020/07/13

[#99257] [Ruby master Misc#17041] DevelopersMeeting20200826Japan — mame@...

Issue #17041 has been reported by mame (Yusuke Endoh).

18 messages 2020/07/22

[#99308] [Ruby master Feature#17047] Support parameters for MAIL FROM and RCPT TO — bugs.ruby-lang.org@...

Issue #17047 has been reported by c960657 (Christian Schmidt).

11 messages 2020/07/23

[#99311] [Ruby master Bug#17048] Calling initialize_copy on live modules leads to crashes — XrXr@...

Issue #17048 has been reported by alanwu (Alan Wu).

17 messages 2020/07/24

[#99351] [Ruby master Bug#17052] Ruby with LTO enabled on {aarch64, ppc64le} architectures. — v.ondruch@...

Issue #17052 has been reported by vo.x (Vit Ondruch).

35 messages 2020/07/27

[#99375] [Ruby master Feature#17055] Allow suppressing uninitialized instance variable and method redefined verbose mode warnings — merch-redmine@...

Issue #17055 has been reported by jeremyevans0 (Jeremy Evans).

29 messages 2020/07/28

[#99391] [Ruby master Feature#17059] epoll as IO.select — dsh0416@...

Issue #17059 has been reported by dsh0416 (Delton Ding).

18 messages 2020/07/29

[#99418] [Ruby master Feature#17097] `map_min`, `map_max` — sawadatsuyoshi@...

Issue #17097 has been reported by sawa (Tsuyoshi Sawada).

11 messages 2020/07/31

[ruby-core:99023] [Ruby master Feature#17004] Provide a way for methods to omit their return value

From: merch-redmine@...
Date: 2020-07-02 01:01:20 UTC
List: ruby-core #99023
Issue #17004 has been updated by jeremyevans0 (Jeremy Evans).


duerst (Martin Dst) wrote in #note-12:
> - Where there are performance implications, couldn't that be solved by an
>   additional parameter to the methods in question? Or by a better design
>   of interfaces (e.g. different methods for cases where an expensive
>   return value isn't needed)? (@jeremyevans0)

Yes, it could definitely be solved by additional method arguments (or keyword arguments).  However, that can complicate implementation or may not be possible depending on the method's API (consider a method that already accepts arbitrary arguments and arbitrary keywords).

One specific use case I see for this is `Sequel::Dataset#insert` (http://sequel.jeremyevans.net/rdoc/classes/Sequel/Dataset.html#method-i-insert).  The return value of this method is generally the primary key value of the last inserted row.  On some databases, getting that value is expensive, potentially doubling the execution time of the method when using a remote database.  If the return value is not needed, the INSERT query could still be performed, but it would not be necessary to issue another query to SELECT the return value.

Due to `Sequel::Dataset#insert`'s flexible API, it would be hard to support this as a method argument.  I could add a different method to support it, but then I need to add a separate internal method (more indirection, lower performance), or significant duplication.  Additionally, having fewer, more flexible methods can result in an API that is easier to remember and use, compared to an API that has many more methods with less flexible behavior for each (with the tradeoff that the internals become significantly more complex).

One potential advantage of the VM_FRAME_FLAG_DISCARDED flag that may not yet have been anticipated is not a performance advantage, but a usability advantage.  Consider the following code:

```ruby
  def foo(**kw)
    kw.merge(FORCE_VALUES)
    bar(**kw)
  end
```

This code has a bug I've seen new Ruby programmers make.  The bug is that `Hash#merge` returns a new hash, it doesn't modify the existing hash.  This is almost certainly a bug, because there is no reason to call `Hash#merge` without using the return value.  The programmer almost certainly wanted the behavior of `Hash#merge!`.  Basically, `Hash#merge` is a pure function.  We could add a way to mark methods as pure functions (e.g. `Module#pure_function`), and if the method is called with VM_FRAME_FLAG_DISCARDED, Ruby could warn or raise.

While I am in favor of this, I can certainly understand the potential for abuse.  However, Ruby has never been a language that avoided features simply because it is possible to abuse them.  That being said, I think it would make sense to make this strictly internal initially, and not expose it to C extensions and pure ruby code unless the internal usage demonstrates its usefulness.

----------------------------------------
Feature #17004: Provide a way for methods to omit their return value
https://bugs.ruby-lang.org/issues/17004#change-86398

* Author: shyouhei (Shyouhei Urabe)
* Status: Open
* Priority: Normal
----------------------------------------
In ruby, it often is the case for a method's return value to not be used by its caller.  Even when a method returns something meaningful, its caller is free to ignore it.

Why not provide a way for a method to know if its return value is needed or not?  That adds a room for methods to be optimized, by for instance skipping creation of complex return values.

The following pull request implements `RubyVM.return_value_is_used?` method, which does that: https://github.com/ruby/ruby/pull/3271



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>

In This Thread