From: merch-redmine@... Date: 2020-07-02T01:01:20+00:00 Subject: [ruby-core:99023] [Ruby master Feature#17004] Provide a way for methods to omit their return value Issue #17004 has been updated by jeremyevans0 (Jeremy Evans). duerst (Martin D�rst) 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: