-
Notifications
You must be signed in to change notification settings - Fork 171
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Discussion: Goby's parameter syntax in method definitions #751
Comments
@hachi8833 I'm just replying some of the suggestion at a time
I think this is worth trying, can't come up with any drawback at this point. Removing it does reduce some edge cases and can simplify our argument checking logic.
I don't agree with this so much. I think more times we use pVA is because we want to pass arguments more dynamically, making users pass an array to keyword argument doesn't seem to be a solid solution. (I can't think about any specific example right now, will update this comment if I got any). Also, this is a very common syntax among most of the popular languages. The new way might not be that straightforward for new users.
This is interesting and makes sense. I'd love to try this. Anyway, we'll need to first decide if we're going to keep pND. And then we need to fix #497 before we move forward. Also, I'm very appreciated for your help on this 😄 |
Thank you for the reply! I notice that pVA in Goby is always follows other parameters and this syntax looks sufficient. I'm OK to preserve pVA 😃 . |
FYI: The following behavior has been prohibited in Ruby 2.6: def foo(h = {}, key: :default)
p [h, key]
end
foo(:key => 1, "str" => 2)
#=> [{"str"=>2}, 1] in 2.5
#=> non-symbol key in keyword arguments: "str" (ArgumentError) in 2.6 |
@hachi8833 can you help me open a PR and add some tests for testing removing |
I'd try this |
Just wait for the tests for removing FYI: https://bugs.ruby-lang.org/issues/14183 (still under discussion) Ruby committers are trying to change the behaviors around this like that: def foo(**kw); p kw; end
def bar(kw = {}); p kw; end
h = {:k => 1}
# base (non-braced) hash arguments passed as keywords
foo(k: 1) #=> {:k=>1} in 2.X and 3.0
foo(:k => 1) #=> {:k=>1} in 2.X and 3.0
foo(**h) #=> {:k=>1} in 2.X and 3.0
bar(k: 1) #=> {:k=>1} in 2.X, ArgumentError in 3.0
bar(:k => 1) #=> {:k=>1} in 2.X, ArgumentError in 3.0
bar(**h) #=> {:k=>1} in 2.X, ArgumentError in 3.0
# braced hash arguments are passed as a last argument
foo({ k: 1 }) #=> {:k=>1} in 2.X, ArgumentError in 3.0
foo({ :k => 1 }) #=> {:k=>1} in 2.X, ArgumentError in 3.0
foo(h) #=> {:k=>1} in 2.X, ArgumentError in 3.0
bar({ k: 1 }) #=> {:k=>1} in 2.X and 3.0
bar({ :k => 1 }) #=> {:k=>1} in 2.X and 3.0
bar(h) #=> {:k=>1} in 2.X and 3.0 |
@hachi8833 I'll probably go for Ruby 3.0's definition except |
FYI: Ruby finally chose to separate keyword args from positional args: |
The following is the latest and the most comprehensive document for breaking changes in Ruby 2.7~: |
TL;DR: I think we can simplify Goby's parameter syntax in method definition.
Of course the final decision should be @st0012's.
Terms
Before proceeding, let me define the followings to clarify the issues and to be concise:
Name as the following on Goby's current method parameters:
def foo(a)
def foo(a=1)
def foo(key:)
def foo(key: "value")
def foo(*array)
*
for indicating pVA[]
will be passed when omitted)In Goby, the order of parameters are restricted as
Note that the order of arguments for pK can be shuffled as far as they are grouped:
This is the same for pKD:
Ruby's parameters
In addition, Ruby has the following parameters:
def foo(**hash)
**
for indicating pVH{}
will be passed when omitted)def foo(&block)
&
for indicating pVHProc
object will be takenRuby's current issues on method parameters/arguments
1. Ruby's keyword parameters/arguments are still not well-integrated
option={}
is now obsolete and should be avoidedSee the recent Rubocop rules that indicates keyword parameters with default values are preferable over parameters with default values with
=
:2. Splat
*
or double-splat**
on calling methods are often puzzlingJust to pass a variable that holds an array or a hash, we still need to add splats to the variables. I think this is also redundant.
Just using pKD is sufficient:
3. Ruby is trying to handle keyword parameters as hash key-values, but sometimes fails:
This is one of the critical issues in current Ruby.
Ref: https://hackmd.io/8EMYfZ8KQwCbYrNogtIDIg
Ruby comitters are trying to resolve the issue, but they recognizes that some breaking-changes are required.
4. Ruby's pVH with
**
is in fact restricting the type (only hash can be taken)(This is just what I discovered and perhaps not an issue :-)
Propositions to improve Goby's parameters
Considering above, Goby is evolving in good way, so I'd propose the followings:
1. Remove pND from Goby
As described above, pND, optional parameters with default value with
=
, is redundant and can be removed from Goby.Removing pND, we can still provide optional keyword parameters pKD in Goby (and Ruby as well).
2. Remove pVA
*
from GobyI think pVA, variable-length array parameters with splat
*
can be removed as well.Removing pVA, we can still provide variable-length arguments with array literal
[]
or hash literal{}
as well as the ones in variables:This makes any splat operators unnecessary.
Final parameter syntax
So Goby's parameter syntax can be simple and concise:
Of course the order of pNs/pKs/pKDs should be kept.
Advantages
*
and**
are unnecessary1, 2, 3...
orhash1: "value1", hash2:, "value2:...
This makes us avoid confusions when adding parameters in the future.
new Sample
In other words, you should always use pK or pKD to pass variable-length arguments. I hope this does not annoy developers so much.
3. Experimental: type-checking with
[]
or{}
This is just an experimental idea. If
[]
or{}
are specified with pKD, the type (Array
orHash
) will be restricted as that.I believe this does not break duck-typings.
I look forward to your comments.
The text was updated successfully, but these errors were encountered: