Why lambda#arity always one complements of Proc#arity?

I was reading the official docs
Class: Proc (Ruby 2.1.0). Where
`lambda#arity` calculstion made me confused. Then from
ruby - Proc.arity vs Lambda.arity - Stack Overflow I
got some clue that `lambda#arity` always one complements of `Proc#arity`
?

Code :

(arup~>~)$ pry --simple-prompt

proc { |(x, y), z=0| }.arity

=> 1

lambda { |(x, y), z=0| }.arity

=> -2

proc { |x=0, y=0| }.arity

=> 0

lambda { |x=0, y=0| }.arity

=> -1

Now my direct question is - Why lambda#arity always one complements of
Proc#arity ?

But one example again made my all assumptions are less confident about
`lambda#arity` calculation. See below :

proc {}.arity

=> 0

lambda {}.arity

=> 0

Where does here `lambda#arity` not one complements of Proc#arity ?

···

--
Posted via http://www.ruby-forum.com/\.

Here are some other examples:

  def m1(x);end
  l1 = lambda{|x|}
  p1 = proc{|x|}

  method(:m1).arity # => 1
  l1.arity # => 1
  p1.arity # => 1

When there are no optional parameters (and zero or more required
parameters), all three objects report the same arity. This is what
you'd expect in a normal situation.

  def m2(x,y=1);end
  l2 = lambda{|x,y=1|}
  p2 = proc{|x,y=1|}

  method(:m2).arity # => -2
  l2.arity # => -2
  p2.arity # => 1

With an optional/default parameter, the Proc object reports number of
"required" parameters*, while the Method and Lambda objects report the
one's complement.

  def m3(x=1,y=1,z=1);end
  l3 = lambda{|x=1,y=1,z=1|}
  p3 = proc{|x=1,y=1,z=1|}

  method(:m3).arity # => -1
  l3.arity # => -1
  p3.arity # => 0

Just to demonstrate that -N doesn't mean "up to N parameters".

I suppose the logic is:

1. if arity is positive, there are that many required parameters
2. if arity is negative,
  a. required parameters = ~arity
  b. there is some (unknown, natural) number of optional parameters

The real question is: why does Proc _not_ report the one's complement?

* note: calling them "required" parameters for a proc is a bit
misleading: proc{|x|x}[] #=> nil

···

--
Posted via http://www.ruby-forum.com/.

Matthew Kerwin wrote in post #1136252:

Here are some other examples:

With an optional/default parameter, the Proc object reports number of
"required" parameters*, while the Method and Lambda objects report the
one's complement.

Again exception -

(arup~>Ruby)$ pry --simple-prompt

p = proc { |a,*b,c| }

=> #<Proc:0x84f7704@(pry):1>

l = lambda { |a,*b,c| }

=> #<Proc:0x84bbeac@(pry):2 (lambda)>

l.arity

=> -3

p.arity

=> -3

···

--
Posted via http://www.ruby-forum.com/\.

Arup Rakshit wrote in post #1136253:

Again exception -

(arup~>Ruby)$ pry --simple-prompt

p = proc { |a,*b,c| }

=> #<Proc:0x84f7704@(pry):1>

l = lambda { |a,*b,c| }

=> #<Proc:0x84bbeac@(pry):2 (lambda)>

l.arity

=> -3

p.arity

=> -3

def m(a,*b,c);end

=> nil

method(:m).arity

=> -3

I don't know that that's an exception so much as an inconsistency in
Proc. but again, I don't know what Proc reports it arity the way it
does in the first place.

It makes sense for the Lambda, because you need to provide values for a
and c, so there are two mandatory parameters. ~2 = -3

  l = lambda{|a,*b,c| p a, b, c }
  l[1,2] #=> 1, , 2

···

--
Posted via http://www.ruby-forum.com/\.