Issue #7701 has been updated by headius (Charles Nutter).


On arity: I already feel like the numeric arity has been stretched too far. There's not really a good way to introduce another dimension of required args into that single value. Arity should reflect how many arguments are required, so I suppose if there's required kwargs they should be included...but marcandre makes a good point too (options hash passed in can fulfill the requirement in fewer args. Myself, I'd say arity should reflect the number of actual args, treating any required kwargs as a single "options" argument requirement, and people should just use parameters for any metaprogramming.

def foo(a, b:1) => arity 1
def foo(a, b:) => arity 2
def foo(a, b:1, c:, d:2, e:) => arity 2 because a single options hash could fulfill all required kwargs

Parameters in each case would be:

[[:req, :a], [:key, :b]]
[[:req, :a], [:keyreq, :b]]
[[:req, :a], [:key, :b], [:keyreq, :c], [:key, :d], [:keyreq, :e]]

ko1 doesn't like the "empty value" foo: format, but I also do not have any alternative to suggest. Syntax decisions probably end up with matz or other folks concerned about syntax. I like def foo(bar:).

My one contribution to syntax discussions would be to point out that normally, you make a position argument optional by having "=" followed by some expression. You make it non-optional by removing the "=" and the expression. In the case of kwargs, we have def foo(bar: 1) for optional kwarg, but we can only remove the expression (removing the : would make it a positional arg). The result is def foo(bar:). Perhaps if kwargs had originally been specified as def foo(bar:=1) then we could say we're following the same syntax rules as for optional args...but I think that form is pretty ugly :-)
----------------------------------------
Feature #7701: Non-optional (required) keyword args
https://bugs.ruby-lang.org/issues/7701#change-37524

Author: headius (Charles Nutter)
Status: Assigned
Priority: Normal
Assignee: nobu (Nobuyoshi Nakada)
Category: 
Target version: 


=begin
I would like to see keyword args expanded to include a non-optional form, to force callers to pass in keyword arguments.

Currently, we have required, optional, and rest positional args but only optional and rest keyword args. Consistency is one small reason to add required keyword args.

They would likely take the form of keyword with no default value:

  def foo(a:, b:)
    ...
  end

  foo(a: 1, b: 2) # ok
  foo(a: 1) # ArgumentError

Justifications:

* Consistency with positional args. A weak justification, I know.
* Avoiding a lot of boilerplate code by users wishing to enforce keywords being passed in. Example from tenderlove:

    def foo(a: raise('pass a'), b: raise('pass b'))

* Building a rich API atop keyword args would be easier (i.e. require fewer manual checks) if you could force some keywords to be passed in. Having to check everywhere when you require a keyword argument is unpleasant.
* Keyword args already enforces that no *additional* keyword args can be passed (without **), and it seems lopsided to have no way to enforce a minimum set of keyword args.
=end



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