Parameters and their assignment to the argument list: logical/consistent?

I was wondering if anybody thinks there is anything illogical or
inconsistent with the following two pieces of code.

code sample 1: splitting a list into it’s head and tail.
h, *t = [1,2,3]
h ==> 1
t ==> [2,3]

···

code sample 2: passing a list to a function accepting two arguments.
def f(h, *t)
# actual result
# h ==> [1,2,3]
# t ==> []

# my expected result
# h ==> 1
# t ==> [2,3]

end

f [1,2,3]

I was expecting the assignment of parameters to arguments to work the
same way as normal assignment.

The downside to the way it works now is demonstrated by the following
quick sort code:
def qs(arr)
return [] if arr.length <= 0
x, *xs = arr
qs(xs.select{ |y| y <= x } ) + [x] + qs(xs.select{ |y| y > x } )
end

However, it could have been written more concisely as
#pseudo code
def qs(x, *xs)
return [] if x.nil?
qs(xs.select{ |y| y <= x } ) + [x] + qs(xs.select{ |y| y > x } )
end

irb(main):001:0> def f(h,*t)
irb(main):002:1> p h
irb(main):003:1> p t
irb(main):004:1> end
nil
irb(main):005:0> f *[1,2,3]
1
[2, 3]
nil

batsman@kodos:/tmp$ cat b.rb
def qs(x=nil, *xs)
return if x.nil?
qs(*xs.select{ |y| y <= x }) + + qs(*xs.select{ |y| y > x })
end

p qs *[6,2,5,1,9,4,3,7,0,8]
batsman@kodos:/tmp$ ruby b.rb
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Notice I need the ‘x=nil’ thing because otherwise we’d get the
following
b.rb:3:in `qs’: wrong # of arguments(0 for 1) (ArgumentError)
when xs.select returns an empty list (the unary * expands that to ‘no
argument’)

BTW, I have the feeling I have found something really strange about
Ruby’s semantics:
irb(main):001:0> xs = [1,2,3]
[1, 2, 3]
irb(main):002:0> xs.select { |x| x < 0 }

irb(main):003:0> (xs.select { |x| x < 0 })
SyntaxError: compile error
(irb):3: parse error
from (irb):3
irb(main):004:0> p(
(xs.select { |x| x < 0 }))
nil
irb(main):005:0> p((xs.select { |x| x < 0 })|nil)
TypeError: failed to convert nil into Array
from (irb):5:in `|’
from (irb):5
irb(main):006:0> p(
(xs.select { |x| x < 0 })||nil)
nil
irb(main):007:0> p nil
nil
nil

So *() is illegal when standing on its own (OK as *whatever is too)
and only works in a method call or assigment. Now comes the weird part:
sometimes it is expanded as nil (line 005), some others it is some unknown
true value (kinda like some ‘true void’) (l. 006).

···

On Sun, Jan 12, 2003 at 05:44:04AM +0900, MetalOne wrote:

I was wondering if anybody thinks there is anything illogical or
inconsistent with the following two pieces of code.

code sample 1: splitting a list into it’s head and tail.
h, *t = [1,2,3]
h ==> 1
t ==> [2,3]

code sample 2: passing a list to a function accepting two arguments.
def f(h, *t)
# actual result
# h ==> [1,2,3]
# t ==>

# my expected result
# h ==> 1
# t ==> [2,3]

end

f [1,2,3]

I was expecting the assignment of parameters to arguments to work the
same way as normal assignment.

The downside to the way it works now is demonstrated by the following
quick sort code:
def qs(arr)
return if arr.length <= 0
x, *xs = arr
qs(xs.select{ |y| y <= x } ) + + qs(xs.select{ |y| y > x } )
end

However, it could have been written more concisely as
#pseudo code
def qs(x, *xs)
return if x.nil?
qs(xs.select{ |y| y <= x } ) + + qs(xs.select{ |y| y > x } )
end


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

…you could spend all day customizing the title bar. Believe me. I
speak from experience.
– Matt Welsh

irb(main):005:0> p(*(xs.select { |x| x < 0 })|nil)

You have written this

                      *(xs.select { |x| x < 0 } | nil)

#select return an Array and ruby is trying

pigeon% ruby -e '[1,2]|nil'
-e:1:in `|': failed to convert nil into Array (TypeError)
        from -e:1
pigeon%

Guy Decoux

irb(main):005:0> p(*(xs.select { |x| x < 0 })|nil)

You have written this

                  *(xs.select { |x| x < 0 } | nil)

#select return an Array and ruby is trying

pigeon% ruby -e ‘[1,2]|nil’
-e:1:in `|': failed to convert nil into Array (TypeError)
from -e:1
pigeon%

I see it, but that is not my point (just a side-way test):

batsman@tux-chan:/tmp$ ruby -e "p (*() || ‘was false’) "
batsman@tux-chan:/tmp$ ruby -e "p (() || ‘was false’) "

Although *() expands to ‘void’ (not nil, nothing), it is “true”.
It feels kinda strange that “nothing” is true.

···

On Sun, Jan 12, 2003 at 10:00:05PM +0900, ts wrote:

Guy Decoux


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

ECRC hat keine lynx komp. seiten, sowas MUSS ja pleite gehen ;-)=
– Getty on #LinuxGER