# Mixing types of arguments

**URL:** <https://rubytalk.org/t/mixing-types-of-arguments/68881>\
**Category:** ruby-talk\
**Created:** [16 December 2013 13:08 UTC](https://rubytalk.org/t/mixing-types-of-arguments/68881 "2013-12-16T13:08:08Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [16 December 2013 13:08 UTC](https://rubytalk.org/t/mixing-types-of-arguments/68881/1 "2013-12-16T13:08:08Z")

</div>

Hi,  
I was wondering why Ruby was designed so that  
&nbsp;&nbsp;def f(u, v=1, \*x)  
&nbsp;&nbsp;&nbsp;&nbsp;p u, v, x  
&nbsp;&nbsp;end  
is OK, but  
&nbsp;&nbsp;def g(u, \*v, x=1)  
&nbsp;&nbsp;&nbsp;&nbsp;p u, v, x  
&nbsp;&nbsp;end  
gives a syntax error.

I would've expected g(1) to print  
1  
[]  
1  
g(1,2) to print  
1  
[]  
2  
and g(1,2,3,4,5) to print  
1  
[2,3,4]  
5

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [16 December 2013 13:19 UTC](https://rubytalk.org/t/mixing-types-of-arguments/68881/2 "2013-12-16T13:19:49Z")

</div>

Probably because I'd have expected g(1,2) to print

> 1  
> [2]  
> 1

and g(1,2,3,4,5) to print

> **···**
>
> > 1  
> > [2,3,4,5]  
> > 1
> 
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)\
**Post date:** [16 December 2013 13:48 UTC](https://rubytalk.org/t/mixing-types-of-arguments/68881/3 "2013-12-16T13:48:55Z")

</div>

In other words: Gandalf, what you ask for is ambiguous. The parser  
cannot decide whether g(1,2) should give 1, , 2 or 1, 2, 1. There  
is no automated way to decide this unless some priorities are given  
with regard to args with \* and those with default value. If you think  
about it that can soon get messy and Matz tends to avoid pitfalls like  
these.

Note that there are other similar restrictions:

irb(main):008:0\> def h(a,\*b,c,\*d) p [a,b,c,d] end  
SyntaxError: (irb):8: syntax error, unexpected tSTAR  
def h(a,\*b,c,\*d) p [a,b,c,d] end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^  
(irb):8: syntax error, unexpected keyword\_end, expecting $end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from /usr/bin/irb:12:in `\<main\>'

Kind regards

robert

> **···**
>
> On Mon, Dec 16, 2013 at 2:19 PM, Matthew Kerwin \<lists@ruby-forum.com\> wrote:
> 
> > Probably because I'd have expected g(1,2) to print
> > 
> > > 1  
> > > [2]  
> > > 1
> > 
> > and g(1,2,3,4,5) to print
> > 
> > > 1  
> > > [2,3,4,5]  
> > > 1
> 
> --  
> remember.guy do |as, often| as.you\_can - without end  
> [http://blog.rubybestpractices.com/](http://blog.rubybestpractices.com/)

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [16 December 2013 17:16 UTC](https://rubytalk.org/t/mixing-types-of-arguments/68881/4 "2013-12-16T17:16:05Z")

</div>

Matthew Kerwin wrote in post #1130722:

> Probably because I'd have expected g(1,2) to print
> 
> > 1  
> > [2]  
> > 1
> 
> and g(1,2,3,4,5) to print
> 
> > 1  
> > [2,3,4,5]  
> > 1

This way you won't be able to assign to x (the optional parameter).

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [16 December 2013 17:58 UTC](https://rubytalk.org/t/mixing-types-of-arguments/68881/5 "2013-12-16T17:58:29Z")

</div>

Robert Klemme wrote in post #1130727:

> **···**
>
> > On Mon, Dec 16, 2013 at 2:19 PM, Matthew Kerwin \<lists@ruby-forum.com\> \> wrote:
> > 
> > > Probably because I'd have expected g(1,2) to print
> > > 
> > > > 1  
> > > > [2]  
> > > > 1
> > > 
> > > and g(1,2,3,4,5) to print
> > > 
> > > > 1  
> > > > [2,3,4,5]  
> > > > 1
> > 
> > In other words: Gandalf, what you ask for is ambiguous. The parser  
> > cannot decide whether g(1,2) should give 1, , 2 or 1, 2, 1. There  
> > is no automated way to decide this unless some priorities are given  
> > with regard to args with \* and those with default value.
> 
> There is the following sensible rule: it should always be possible to  
> assign to any parameter.  
> That's pretty natural to me, but maybe this is subjective and it would  
> make Ruby less intuitive.
> 
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Carlo\_E\_Prelz](https://avatars.discourse-cdn.com/v4/letter/c/dbc845/32.png) [@Carlo\_E\_Prelz](https://rubytalk.org/u/Carlo_E_Prelz)\
**Post date:** [16 December 2013 18:12 UTC](https://rubytalk.org/t/mixing-types-of-arguments/68881/6 "2013-12-16T18:12:54Z")

</div>

Quoting Gandalf Fladnag (lists@ruby-forum.com):

> There is the following sensible rule: it should always be possible to  
> assign to any parameter.  
> That's pretty natural to me, but maybe this is subjective and it would  
> make Ruby less intuitive.

Note that, since 2.0, Ruby allows named arguments. At the expense of  
having to type a little bit more, you are given much more flexibility  
wrt argument passing. I started using this feature a few months ago,  
and surely there are cases when it is a godsend.

There are several articles about this feature online. For example:

[http://ruby.about.com/od/beginningruby/ss/Keyword-Arguments.htm](http://ruby.about.com/od/beginningruby/ss/Keyword-Arguments.htm)

Carlo

> **···**
>
> Subject: Re: mixing types of arguments  
> &nbsp;&nbsp;Date: lun 16 dic 13 06:58:29 +0100
> 
> --  
> &nbsp;&nbsp;\* Se la Strada e la sua Virtu' non fossero state messe da parte,  
> \* K \* Carlo E. Prelz - fluido@fluido.as che bisogno ci sarebbe  
> &nbsp;&nbsp;\* di parlare tanto di amore e di rettitudine? (Chuang-Tzu)

---

<div class="post-metadata">

**Author:** ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)\
**Post date:** [16 December 2013 18:15 UTC](https://rubytalk.org/t/mixing-types-of-arguments/68881/7 "2013-12-16T18:15:00Z")

</div>

> Robert Klemme wrote in post #1130727:
> 
> > > Probably because I'd have expected g(1,2) to print
> > > 
> > > > 1  
> > > > [2]  
> > > > 1
> > > 
> > > and g(1,2,3,4,5) to print
> > > 
> > > > 1  
> > > > [2,3,4,5]  
> > > > 1
> > 
> > In other words: Gandalf, what you ask for is ambiguous. The parser  
> > cannot decide whether g(1,2) should give 1, , 2 or 1, 2, 1. There  
> > is no automated way to decide this unless some priorities are given  
> > with regard to args with \* and those with default value.
> 
> There is the following sensible rule: it should always be possible to  
> assign to any parameter.

How do you do that if there are less arguments than parameters? It's  
no use if it cannot be safely and automatically determined which  
parameters should receive which values.

> That's pretty natural to me, but maybe this is subjective and it would  
> make Ruby less intuitive.

It's more important that semantics of assignment are clear and  
unambiguous. For more complex cases use Ruby 2.0 or Hash arguments in  
older versions.

Cheers

robert

> **···**
>
> On Mon, Dec 16, 2013 at 6:58 PM, Gandalf Fladnag \<lists@ruby-forum.com\> wrote:
> 
> > > On Mon, Dec 16, 2013 at 2:19 PM, Matthew Kerwin \<lists@ruby-forum.com\> \>\> wrote:
> 
> --  
> remember.guy do |as, often| as.you\_can - without end  
> [http://blog.rubybestpractices.com/](http://blog.rubybestpractices.com/)

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [16 December 2013 20:12 UTC](https://rubytalk.org/t/mixing-types-of-arguments/68881/8 "2013-12-16T20:12:03Z")

</div>

Robert Klemme wrote in post #1130770:

> > > > > [2,3,4,5]  
> > > > > 1
> > > 
> > > In other words: Gandalf, what you ask for is ambiguous. The parser  
> > > cannot decide whether g(1,2) should give 1, , 2 or 1, 2, 1. There  
> > > is no automated way to decide this unless some priorities are given  
> > > with regard to args with \* and those with default value.
> > 
> > There is the following sensible rule: it should always be possible to  
> > assign to any parameter.
> 
> How do you do that if there are less arguments than parameters? It's  
> no use if it cannot be safely and automatically determined which  
> parameters should receive which values.

I meant something different.

Let's consider again  
&nbsp;&nbsp;def f(x,\*y,z=1)  
&nbsp;&nbsp;&nbsp;&nbsp;p x,y,z  
&nbsp;&nbsp;end  
If we decide that f(1,2,3) prints  
1  
[2,3]  
1  
then we're saying that y should capture anything starting from the  
second parameter. That makes it impossible to give a value to z and thus  
this should be avoided according to the rule I was talking about.  
Basically, if the arguments are more than one, z should always take the  
last argument.

> **···**
>
> > On Mon, Dec 16, 2013 at 6:58 PM, Gandalf Fladnag \<lists@ruby-forum.com\> \> wrote:
> 
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)\
**Post date:** [16 December 2013 21:06 UTC](https://rubytalk.org/t/mixing-types-of-arguments/68881/9 "2013-12-16T21:06:16Z")

</div>

> Robert Klemme wrote in post #1130770:
> 
> > > > > > [2,3,4,5]  
> > > > > > 1
> > > > 
> > > > In other words: Gandalf, what you ask for is ambiguous. The parser  
> > > > cannot decide whether g(1,2) should give 1, , 2 or 1, 2, 1. There  
> > > > is no automated way to decide this unless some priorities are given  
> > > > with regard to args with \* and those with default value.
> > > 
> > > There is the following sensible rule: it should always be possible to  
> > > assign to any parameter.
> > 
> > How do you do that if there are less arguments than parameters? It's  
> > no use if it cannot be safely and automatically determined which  
> > parameters should receive which values.
> 
> I meant something different.
> 
> Let's consider again  
> &nbsp;&nbsp;def f(x,\*y,z=1)  
> &nbsp;&nbsp;&nbsp;&nbsp;p x,y,z  
> &nbsp;&nbsp;end  
> If we decide that f(1,2,3) prints  
> 1  
> [2,3]  
> 1  
> then we're saying that y should capture anything starting from the  
> second parameter. That makes it impossible to give a value to z and thus  
> this should be avoided according to the rule I was talking about.

It \*is\* avoided because the syntax is illegal.

> Basically, if the arguments are more than one, z should always take the  
> last argument.

Hence you introduce priorities - as I stated above. I think that  
makes things too complicated and thus error prone. I assume that it  
has not been done exactly because of this.

Cheers

robert

> **···**
>
> On Mon, Dec 16, 2013 at 9:12 PM, Gandalf Fladnag \<lists@ruby-forum.com\> wrote:
> 
> > > On Mon, Dec 16, 2013 at 6:58 PM, Gandalf Fladnag \<lists@ruby-forum.com\> \>\> wrote:
> 
> --  
> remember.guy do |as, often| as.you\_can - without end  
> [http://blog.rubybestpractices.com/](http://blog.rubybestpractices.com/)
