yield does not take a block

E

Eric Mahurin

--- Daniel Brockman said:
=20
However, I ``destructively'' modify standard library classes
and
modules all the time. This is a major selling point for
Ruby.

I'm not going to argue that it is not useful, because it is and
I use it. I'm just saying that being able to modify a class
and the (singleton) class of an object at runtime will prohibit
some amount of optimization within ruby. If these were done at
compile/parse time or nondestructively (returning a new
class/object), it would be easier to optimize ruby, but
obviously less flexible.



=09
____________________________________________________=20
Yahoo! Sports=20
Rekindle the Rivalries. Sign up for Fantasy Football=20
http://football.fantasysports.yahoo.com
 
A

Adam P. Jenkins

Eric said:
The reason you can't is because a method name by itself calls
the method instead of returning the method object.

Ok, fair enough. I would still prefer just

myArray.each :print

or
myArray.each &print

than having to wrap it in a block.

If you had
to put () to make the call and the method name by itself
returned the method object (I would have preferred that), you
could do this:

myArray.each(&print)

but, this should work fine right now:

myArray.each(&method:)print))

Cool, I didn't know about that. Still,

myArray.each &method:)print)
myArray.each {|e| print e }

Not much advantage really.

Obviously you can do what you need to do in the current Ruby
implementation, it's just annoying and inconsistent in the same way that
it's annoying in Java that you need to box or unbox primitive types
depending on the context. Even the Java 1.5 syntactic sugar for
autoboxing doesn't completely hide the distinction. Coming from
programming in functional languages, Ruby's distinction between blocks,
closures, and methods seems similarly unnecessary at a language level,
though like Java's primitive/Object distinction, it's probably a useful
compromise for runtime efficiency.

Adam
 
D

Daniel Brockman

Adam P. Jenkins said:
In all other languages I've used that have closures, such as Scheme,
ML, Haskell, OCaml, and even Javascript, a closure is just an object
like any other object, that happens to have a special literal syntax
for creating them.
[...]

The way ruby does it with blocks/yield has several disadvantages:

1) There's an arbitrary limit of 1 on the number of blocks you can
pass to a function. If you want to pass more than 1, you need to
convert all but the last block to a proc.

The languages you mentioned above all have this ``arbitrary limit.''
Consider O'Caml. You can only give one block to the `fun' keyword.
Or JavaScript. Certainly, the `function' keyword only takes one
argument list and one code block.

In fact, these languages have the additional ``arbitrary limit'' that
code blocks cannot be passed to user-defined methods.

What I mean is that Ruby allows this,

lambda { |a, b, c| ... }

as well as this

moomin { |a, b, c| ... }

and this ---

snufkin foo, bar do |a, b, c| ... end

Heck, Ruby 1.9 even allows this shorthand for lambdas,

{ |a, b, c| ... }

but that's beside the point. The point is that JavaScript only
allows this:

function (a, b, c) { ... }

That is to say, you cannot define `moomin' in a way that makes this
valid JavaScript code:

moomin (a, b, c) { ... }

The same goes for all the other languages. (Well, except for Scheme,
which really actually lets you define arbitrary syntactic forms, but
we all know that Lisp is inherently superior to everything else, so I
will just pretend you didn't mention it.)

Clearly, when it comes to blocks, Ruby's syntax is far more general
than that of other mortal (i.e., non-Lisp) languages.

While a JavaScript programmer would go like this,

array.sort(function (a, b) { ... })

a Ruby programmer could go like this ---

array.sort &lambda { |a, b| ... }

that would be the literal translation. But Ruby takes another step;
it lets you give code blocks directly to _any_ method,

array.sort { |a, b| ... }

not just `lambda'. This is _better_ than most languages can do.
 
D

Daniel Brockman

Eric Mahurin said:
If these [modifying a class/singleton class] were done at
compile/parse time or nondestructively (returning a new
class/object), it would be easier to optimize ruby, but obviously
less flexible.

You didn't respond to my question:
 
D

Daniel Brockman

Due to the deeply object-oriented nature of Ruby, I think your
semantics (call a global method with each element as argument) are
neither very feasible nor very useful.
Ok, fair enough. I would still prefer just

myArray.each :print

Unfortunately, there is no straightforward way to redefine `each',
since every class has its own implementation. But you can define
another method for sending a message to each element in a collection.

module Enumerable
def each! message, *args, &block
each { |x| x.__send__ message, *args, &block }
end
end

I'm sorry I couldn't think of a better name than `each!'.

[...]

I just want to say that I'm really glad to be able to leave out the
parentheses. I prefer

array.compact!

over

array.compact!()

any day.
Cool, I didn't know about that. Still,

myArray.each &method:)print)
myArray.each {|e| print e }

Not much advantage really.

I have been toying with the idea of binding parameters automatically.
The general case would be to bind all parameters to, e.g., @1, @2, @3,
and so on. But the most useful case is the first parameter. What if
a single lone snail referred to the first parameter?

Then you could write the above as

myArray.each { print @ }

I know from experience that this can make people cry out ``hideous!''
and ``get away from our language, you subversive Perl advocate.''
It can also make people say ``hey, that makes a lot of sense.''

(For the record, I don't advocate Perl, per se, but I do recognize
that it was designed by a real linguist with good ideas.)

I don't think automatical currying or automatic method boxing or
anything like that makes sense in Ruby. But I do think this

ipv4s.collect! { IPv4Address[@] }
publics = ipv4s.select { @.public? }
privates = ipv4s.select { @.private? }
loopbacks = ipv4s.select { @.loopback? }

looks better than this

ipv4s.collect! { |x| IPv4Address[x] }
publics = ipv4s.select { |x| x.public? }
privates = ipv4s.select { |x| x.private? }
loopbacks = ipv4s.select { |x| x.loopback? }

looks better than this

ipv4s.collect! { |ip| IPv4Address[ip] }
publics = ipv4s.select { |ip| ip.public? }
privates = ipv4s.select { |ip| ip.private? }
loopbacks = ipv4s.select { |ip| ip.loopback? }

Those repetitive microscopically-scoped parameter names don't add any
explanatory value or increased readability --- they're just clutter.
Obviously you can do what you need to do in the current Ruby
implementation, it's just annoying and inconsistent in the same way
that it's annoying in Java that you need to box or unbox primitive
types depending on the context. Even the Java 1.5 syntactic sugar
for autoboxing doesn't completely hide the distinction. Coming from
programming in functional languages, Ruby's distinction between
blocks, closures, and methods seems similarly unnecessary at a
language level, though like Java's primitive/Object distinction,
it's probably a useful compromise for runtime efficiency.

It doesn't sound like you have anything concrete to contribute.
No, Ruby is not Haskell --- so what?
 
E

Eric Mahurin

--- Daniel Brockman said:
You didn't respond to my question:
=20

The non-destructive version of this would be (simple
inheritance):

class MyNumeric < Numeric; def infinite?;false;end;end

I know that is not what you wanted and not nearly as useful. I
was just making the point that this useful behavior (modifying
classes at run-time) does come at a cost: it ties ruby to a
very dynamic object model that makes it difficult for ruby to
do certain types of optimizations.



=09
__________________________________=20
Yahoo! Mail Mobile=20
Take Yahoo! Mail with you! Check email on your mobile phone.=20
http://mobile.yahoo.com/learn/mail=20
 
A

Adam P. Jenkins

Daniel said:
Due to the deeply object-oriented nature of Ruby, I think your
semantics (call a global method with each element as argument) are
neither very feasible nor very useful.

Not true at all. An OO language just has to support the concept of a
bound method reference. For example, in Python:

# Here's an unbound method of the "file" class:
# Here's a bound method<built-in method write of file object at 0xb7fb9060>

# Here's how you can use a bound method reference
The assignment to "w" creates a bound method reference, that not only
knows what method it refers to, but which object to send the method call
to. C# implements a similar concept, and there's no fundamental reason
that any OO language couldn't. So I don't agree at all that OO and
functional paradigms don't mix in this regard.
Unfortunately, there is no straightforward way to redefine `each',
since every class has its own implementation.

I'm just having an theoretical "could have been" discussion. I'm not
suggesting there's any practical way to change things at this point.
It doesn't sound like you have anything concrete to contribute.
No, Ruby is not Haskell --- so what?

Hey now, that's an unnecessary low blow. Or are you suggesting we
should forgo theoretical discussion, and limit ourselves to discussing
things which are actually likely to make it into the next version of Ruby?

This is a language newsgroup, and this a thread about arguably
inconsistent semantics concerning blocks and procs. I'm not suggesting
Ruby should be a certain way *because* some other language is that way,
but rather I'm critiquing a certain aspect of the Ruby language by way
of comparison to other languages.

When I first started programming in Ruby, I didn't understand why it had
separate concepts for blocks and closures, but I figured maybe it would
become apparent after using it for a while. One guess I made was that
maybe the first version of Ruby only had block/yield, and when it became
apparent that blocks were too limited, procs were added as a more
general mechanism, but block/yield had to stay for backward
compatibility. After using Ruby at work for several months now, I've
come to the conclusion that there is no good reason for the distinction
at the language level, though at an implementation level, I have seen it
mentioned that yield operates faster than Proc#call. I'd still be
interested though in hearing if there is another rationale for the
distinction.

Adam
 
A

Adam P. Jenkins

Daniel said:
In all other languages I've used that have closures, such as Scheme,
ML, Haskell, OCaml, and even Javascript, a closure is just an object
like any other object, that happens to have a special literal syntax
for creating them.

[...]


The way ruby does it with blocks/yield has several disadvantages:

1) There's an arbitrary limit of 1 on the number of blocks you can
pass to a function. If you want to pass more than 1, you need to
convert all but the last block to a proc.


The languages you mentioned above all have this ``arbitrary limit.''
Consider O'Caml. You can only give one block to the `fun' keyword.
Or JavaScript. Certainly, the `function' keyword only takes one
argument list and one code block.

The "function" keyword is not a function, it's a keyword for defining a
function, equivalent to "def" in Ruby, or "fun" in O'Caml. I'm talking
about the passing multiple closures to a function. In Ruby you need to
use a different syntax to pass more than one closure argument than if
you only want to pass one. That's what I was talking about.

obj.method_that_takes_one_block {|a,b| .... }

obj.method_that_takes_two_blocks(proc{|a| ... }) {|b| ... }

What would seem cleaner to me would be if the {|params| code } syntax
evaluated to a proc. Then you'd just say:

obj.method_that_takes_two_blocks {|a| ... }, {|b| ...}, third_arg

See, in the last (hypothetical) syntax, proc is just a kind of object
that happens to have a literal syntax for defining it, just as arrays
and hashes do, but is otherwise just like any other object, and is
passed as an argument just as anything else is passed as an argument.
That's all I'm suggesting, and wondering why it's not that way, or if it
couldn't be made that way in Ruby 1.9.
In fact, these languages have the additional ``arbitrary limit'' that
code blocks cannot be passed to user-defined methods.

What I mean is that Ruby allows this,

lambda { |a, b, c| ... }

as well as this

moomin { |a, b, c| ... }

and this ---

snufkin foo, bar do |a, b, c| ... end

Heck, Ruby 1.9 even allows this shorthand for lambdas,

{ |a, b, c| ... }

but that's beside the point. The point is that JavaScript only
allows this:

function (a, b, c) { ... }

That is to say, you cannot define `moomin' in a way that makes this
valid JavaScript code:

moomin (a, b, c) { ... }


This is just a semantic game having to do with the overloading of the
word "block" in different language definitions. In the Ruby definition
the word "block" is used to mean a type of anonymous closure, whereas in
most other languages the word "block" is usually used to refer to an
enclosed section of code, such as what would be executed inside an if or
else branch. You can do all the Ruby things you're showing above with
Javascript, it's just that the syntax is different, and what Ruby calls
a "block", Javascript calls a "closure", or "function object".

The Javascript equivalent of what Ruby calls a "block" would be this:

Ruby:
{|a, b| somecode }

Javascript:
function(a, b) { somecode }

Except that Javascript doesn't have two different types of closures, so
the Javascript closure is really closer to a "proc" in Ruby, since it
evaluates to a Function object, which can be directly assigned to a
variable, or passed as a parameter to a function.
The same goes for all the other languages. (Well, except for Scheme,
which really actually lets you define arbitrary syntactic forms, but
we all know that Lisp is inherently superior to everything else, so I
will just pretend you didn't mention it.)

Clearly, when it comes to blocks, Ruby's syntax is far more general
than that of other mortal (i.e., non-Lisp) languages.

While a JavaScript programmer would go like this,

array.sort(function (a, b) { ... })

a Ruby programmer could go like this ---

array.sort &lambda { |a, b| ... }

that would be the literal translation. But Ruby takes another step;
it lets you give code blocks directly to _any_ method,

array.sort { |a, b| ... }

not just `lambda'. This is _better_ than most languages can do.

Semantically,

array.sort {|a,b| .. }

is the same as Javascript's

array.sort(function(a,b) { ... })

so you're still just playing semantic games with Ruby's unusual use of
the word "block" to claim some fundamental advantage for Ruby.
Basically the difference just comes down to the fact that you don't have
to use the "function" keyword in Ruby. The real difference, and the one
that I'm questioning the usefulness of, is the fact that Ruby provides
several different ways to do the same thing:

def func1
yield
end

def func2(&block)
block.call
end

def func3(block)
block.call
end

blockvar = lambda { ... }

func1 { ... }
func1 &blockvar

func2 { ... }
func2 &blockvar

func3(lambda { ... })
func3 blockvar

I wouldn't see anything wrong with having all these different ways of
passing closures if I could see some different functionality being
offered by the different methods. As it is, I'm a little baffled as to
why they all couldn't be unified down to

def func(block)
block.call
end

func { ... }

And for a function that takes two blocks:

def func(block1, block2)
block1.call
block2.call
end

func { ... }, { ... }

Etc. Is it really just a matter of backward compatibility at this
point? (By "just", I don't mean to suggest this is an insignificant
concern.) Is it that people like not having to type in the extra
parameter when they're defining a function? Is it that "yield"
inherently allows for faster execution in the common 1 block case? Is
there some other advantage to "yield" that I'm missing?

Adam
 
D

Daniel Brockman

Adam P. Jenkins said:
Not true at all. An OO language just has to support the concept of
a bound method reference. For example, in Python:

# Here's an unbound method of the "file" class:

In Ruby,

IO.instance_method :write #=> # said:
# Here's a bound method
<built-in method write of file object at 0xb7fb9060>

In Ruby,

$stdout.method :write
# Here's how you can use a bound method reference

In Ruby,

w = $stdout.method :write
w["Hello\n"] # or w.call "Hello\n"
The assignment to "w" creates a bound method reference, that not
only knows what method it refers to, but which object to send the
method call to. C# implements a similar concept, and there's no
fundamental reason that any OO language couldn't.

Indeed, and Ruby does precisely this.
So I don't agree at all that OO and functional paradigms don't mix
in this regard.

I think you missed the point. You originally suggested we have this

foo.each print

be equivalent to this:

foo.each { |x| print x }

Note how print is a ``global function,'' rather than a method on x.
This is what I objected to, my point being that --- Ruby being a
deeply object-oriented language --- it would be more natural for

foo.each print

to mean

foo.each { |x| print.bind(x).call }

Of course, as I said, a more useful form would be

foo.each :print

for

foo.each { |x| x.__send__ :print }

(I believe it's more common to invoke a method on each element of a
collection than it is to give each element to a unary function.)
I'm just having an theoretical "could have been" discussion. I'm not
suggesting there's any practical way to change things at this point.

I'm also having a mostly theoretical discussion. The above statement
was not meant to criticize you. I said, ``unfortunately, you can't
redefine `each', but look, you can define your own method in the
following useful way.'' (But you cut that part out when quoting me.)
Hey now, that's an unnecessary low blow.

I apologize. I thought the above paraghaph looked like a pointless
rant about how ``it would be better if it didn't suck.'' But I think
I see where you are going with the analogy now: blocks are primitives
and procs are Objects, and we should get rid of the primitives and
stick to Objects unless it hurts performance?

Simply put, you think that the yield keyword should be abolished along
with the concept of ``block parameters'' --- right? So

foo { ... }

would be a method call with one regular parameter, and

foo { ... }, { ... }

would simply be a method call with two regular parameters. I don't
think this is an insane proposal. But what about this syntax?

foo { ... }.bar { ... }

I don't think these alternatives are very attractive:

(foo { ... }).bar { ... }

foo({ ... }).bar { ... }

Honest question: What are some use cases for multiple blocks?
(Please don't tell me you want `if' to be a method.)

[...]
When I first started programming in Ruby, I didn't understand why it
had separate concepts for blocks and closures,

Please use one of the terms `lambda', `proc', or possibly `function'
unless there is a specific reason to limit discussion to closures.

def moomin
foo = lambda { |x| x * 2 + 1 }
lambda { |x| 7 / foo.call x }
end

bar = moomin

Here, `foo' and `bar' are both lambdas, but only `bar' is a closure.
but I figured maybe it would become apparent after using it for a
while. One guess I made was that maybe the first version of Ruby
only had block/yield, and when it became apparent that blocks were
too limited, procs were added as a more general mechanism, but
block/yield had to stay for backward compatibility. After using
Ruby at work for several months now, I've come to the conclusion
that there is no good reason for the distinction at the language
level, though at an implementation level, I have seen it mentioned
that yield operates faster than Proc#call. I'd still be interested
though in hearing if there is another rationale for the distinction.

Actually, the more I think about it, the more reasonable it seems.
People, help: Why do we need blocks to be so damn special?
 
F

Florian Frank

Adam said:
obj.method_that_takes_two_blocks {|a| ... }, {|b| ...}, third_arg

See, in the last (hypothetical) syntax, proc is just a kind of object
that happens to have a literal syntax for defining it, just as arrays
and hashes do, but is otherwise just like any other object, and is
passed as an argument just as anything else is passed as an argument.
That's all I'm suggesting, and wondering why it's not that way, or if
it couldn't be made that way in Ruby 1.9.

It is made that way in current Ruby 1.9:
def compose(f, g) { |x| f[g[x]] } end => nil
h = compose({ |x| 2 * x }, { |x| x + 1 })
=> # said:
=> 8
 
D

Daniel Amelang

Well, let's look at what our code looks like now vs. how it would look:

# Current way
def meth(num)
yield(num) if block_given?
end

meth 42 { |num| puts num }


# Unified block/proc way
def meth(num, block=3Dnil)
block.call(num) if block
end

meth 42, { |num| puts num }


Nothing too strange, except for that comma in the argument list when
you call the method, since the block is now just a regular parameter.

So when you call 'inject' now, it'd look like this:

sum =3D [1,2,3].inject 0, { |s, n| s + n }

That comma does look a little funny. Not a big deal, though.

Where's David Black? He usually beats these heretical ideas down pretty fas=
t. :)

Seriously, though, getting rid of the yield keyword, block_given?, the
whole & thing for converting between blocks/procs and the concept of
blocks now being just regular parameters is a big change. The result
would border on a whole different language.

It is _conceptually_ pleasing to unify them. Does it really make our
lives easier?

Dan
 
B

Brian Candler

I'm not going to argue that it is not useful, because it is and
I use it. I'm just saying that being able to modify a class
and the (singleton) class of an object at runtime will prohibit
some amount of optimization within ruby.

But a good inline cache implementation should have pretty small overhead,
and is far easier than attempting to make inferences about the types of
objects.

Ultimately I don't see why a method call a.foo() can't be compiled into
something like this:

/* call a.foo() */

static int md1234;
static VALUE *old_class1234;
static VALUE *fn(void);

if (methods_defined != md1234 ||
(klass = CLASS_OF(a)) != old_class1234)
{
fn1234 = method_find(a, "foo");
md1234 = methods_defined;
old_class1234 = klass;
}
fn1234();

"methods_defined" is a global variable incremented every time a method is
defined, to invalidate all caches. The normal case would be just a few
compares before calling the cached function pointer.

Anyway, there are other things in Ruby which are equally big overheads, and
just as difficult to optimise out. For example,

10.times do
puts "hello"
end

generates a new String object containing "hello" each time round the loop,
which has to be garbage-collected. You can't re-use the same object unless
you can be sure that no references to it have been kept anywhere else.

There are both benefits and costs associated with a highly dynamic language
- but given that CPUs are so cheap, and programmer time is so expensive, I
think it's reasonable to go the Ruby way.

Regards,

Brian.
 
D

Daniel Brockman

Daniel Amelang said:
Well, let's look at what our code looks like now vs. how it
would look:

Good idea.
# Current way
def meth(num)
yield(num) if block_given?
end

meth 42 { |num| puts num }

Actually, that would have to be either this

meth 42 do |num| puts num end

or this,

meth(42) { |num| puts num }

since this

meth 42 { |num| puts num }

is syntactically treated as this,

meth (42 { |num| puts num })

which makes no sense. (You can argue that it does not make sense to
treat the code as nonsense on purpose, when there is really only one
reasonable interpretation. But then you have this

meth 42.factorial { |num| puts num }

which has two reasonable interpretations, and the one Ruby takes
conflicts with the one needed for the original code to make sense.)
# Unified block/proc way
def meth(num, block=nil)
block.call(num) if block
end

meth 42, { |num| puts num }

Nothing too strange, except for that comma in the argument list when
you call the method, since the block is now just a regular parameter.

This is actually an interesting comparison:

meth(42) { |num| puts num }

meth 42, { |num| puts num }

I know everyone will jump the opportunity to scream that the first one
is better in every way. But I don't think it's a clear-cut winner.
(Except when you need to chain more calls onto it --- read on.)
So when you call 'inject' now, it'd look like this:

sum = [1,2,3].inject 0, { |s, n| s + n }

That comma does look a little funny. Not a big deal, though.

How about this?

average = [1,2,3].inject(0) { |s, n| s + n }.to_f / [1,2,3].size

You'd need to write that like so,

average = [1,2,3].inject(0, { |s, n| s + n }).to_f / [1,2,3].size

unless we kept the old syntax as sugar. On the other hand, I don't
think there would be any problem in doing so. That is, this code

foo(bar) { baz }

would be syntactic sugar for passing `bar' and `{ baz }' to `foo'.

Without the sugar, chaining method calls onto method calls with long
blocks would get pretty ugly. This cutie

moomin snufkin do |a, b, c|
snork.snork.snork.snork
snork.snork.snork.snork
snork.snork.snork.snork
end.frobnicate

would turn into this

moomin(snufkin, do |a, b, c|
snork.snork.snork.snork
snork.snork.snork.snork
snork.snork.snork.snork
end).frobnicate

(I'm assuming `do |x| y end' would be the same as `{ |x| y }'.)

I personally think method calls chained onto long blocks looks bad,
and I try to avoid it myself. But there are probably people who love
doing it, and who would hate it if it started to look even worse.

Note that this would be no problem even without the sugar ---

moomin snufkin do |a, b, c|
snork.snork.snork.snork
snork.snork.snork.snork
snork.snork.snork.snork
end

it would just get an extra comma:

moomin snufkin, do |a, b, c|
snork.snork.snork.snork
snork.snork.snork.snork
snork.snork.snork.snork
end
Seriously, though, getting rid of the yield keyword, block_given?, the
whole & thing for converting between blocks/procs and the concept of
blocks now being just regular parameters is a big change. The result
would border on a whole different language.

I agree that it is a very big change, but I wouldn't go so far as to
say it would make a different language. Adam is right that Ruby has
been shifting more and more towards this, to the point where Ruby 1.9
can make you think the block syntax looks like an historic quirk.
It is _conceptually_ pleasing to unify them. Does it really make our
lives easier?

I would like to know this as well.

The best example I can think of is this,

gizmos.find({ || Gizmo.new :foo => true }) { |x| x.foo? }

which would turn into this,

gizmos.find { || Gizmo.new :foo => true }, { |x| x.foo? }

which I think is an extremely minor improvement.

And what about this syntax?

def foo *args, &block ; ... end

I guess that'd have to become something like this,

def foo *args ; block = args.pop end

which is starting to look suspiciously much like Perl.

Maybe this syntax could be adopted?

def foo a, b, *args, c, d; ... end

That is, at least four arguments, and any extra ones in the the middle
get splatted into `args'. I think it makes sense. Then we'd have

def foo *args, block ; ... end


I think this is an interesting discussion. It's definitely good food
for thought. But, of course, we're just brainstorming.
 
Z

Zach Dennis

Daniel said:
ipv4s.collect! { IPv4Address[@] }
publics = ipv4s.select { @.public? }
privates = ipv4s.select { @.private? }
loopbacks = ipv4s.select { @.loopback? }

I disagree. I think this is absolutely horrid looking.

And I think that

ipv4s.collect! { |ip| IPv4Address[x] }

is better. And even if you don't think it adds to readability for single
value blocks I like it for things like...

server.process( connection ) do |msg, msg_type, socket|
# do connection procesing here...
end

Zach
 
E

Eric Mahurin

--- Daniel Brockman said:
Maybe this syntax could be adopted?
=20
def foo a, b, *args, c, d; ... end

I want that too. It would be nice for the []=3D method where the
value is always the last argument. Or any method where you
want optional arguments first or in the middle.

In general, this:

def foo a, b, c=3Dx, d=3Dy, *other, e, f
...
end

should be equivalent to:

def foo a, b, *remaining
e,f =3D remaining.slice!(-2,2)
c =3D remaining.empty? ? x : remaining.shift
d =3D remaining.empty? ? y : remaining.shift
other =3D remaining
...
end

Want to submit an RCR for this? I've already done my fair
share.



=09
____________________________________________________=20
Yahoo! Sports=20
Rekindle the Rivalries. Sign up for Fantasy Football=20
http://football.fantasysports.yahoo.com
 
D

Daniel Brockman

Zach Dennis said:
Daniel said:
ipv4s.collect! { IPv4Address[@] }
publics = ipv4s.select { @.public? }
privates = ipv4s.select { @.private? }
loopbacks = ipv4s.select { @.loopback? }

I disagree. I think this is absolutely horrid looking.

How so? Because of the choice of character? A more mnemonic but less
compatible syntax would be to use an underscore instead of a snail.

loopbacks = ipv4s.select { _.loopback? }

This is mnemonic because `_' suggests ``fill in the blank,'' but less
compatible because it is currently a valid name. Why the lucky stiff
actually uses it, but I doubt if he ever used it inside a block.

Another notation that I like is `<>' from SRFI 26.
(See <http://srfi.schemers.org/srfi-26/srfi-26.html>.)

loopbacks = ipv4s.select { <>.loopback? }

The `<>' is pronounced ``slot''. It also happens to look like a gem.
(The semantics are not exactly those of SRFI 26, but close enough.)

I may actually prefer the underscore; I'm not really sure. I know I
prefer `<>' over `@', and maybe I shouldn't have mentioned the latter.

What do other people think?
And I think that

ipv4s.collect! { |ip| IPv4Address[x] }

is better.

No comment.
And even if you don't think it adds to readability for single value
blocks I like it for things like...

server.process( connection ) do |msg, msg_type, socket|
# do connection procesing here...
end

Allow me to raise my voice. OF COURSE IT ADDS READABILITY TO LONG
BLOCKS WITH THREE PARAMETERS. I'm only talking about short blocks
with one parameter. Did you seriously think I was suggesting we
deprecate formal parameters altogether?
 
D

Daniel Brockman

Eric Mahurin said:
Daniel Brockman said:
Maybe this syntax could be adopted?

def foo a, b, *args, c, d; ... end

I want that too. It would be nice for the []= method
where the value is always the last argument.

Yeah, that's a good example. Does anyone have another?
Or any method where you want optional arguments first or
in the middle.

In general, this:

def foo a, b, c=x, d=y, *other, e, f
...
end

should be equivalent to:

def foo a, b, *remaining
e,f = remaining.slice!(-2,2)
c = remaining.empty? ? x : remaining.shift
d = remaining.empty? ? y : remaining.shift
other = remaining
...
end

Want to submit an RCR for this? I've already done my fair share.

Fair enough. I'll wait a few days to see what happens to this thread,
and then I'll probably submit one.
 
G

googlegroups2sucks

I may actually prefer the underscore; I'm not really sure. I know I
prefer `<>' over `@', and maybe I shouldn't have mentioned the latter.

What do other people think?


alright, all you party people in the house, take note of my syntax:

when i use the underscore or "_" symbol it's in lieu of what i'd
normally UNDERLINE in a full-blown wordprocessor, because the
bare-bones nature of google's posting mini-app doesn't allow it. when
i want to emphasize the word "duh", i'll type an underscore before and
after, e.g. _duh_. when i want to interject a thought within a
sentence -- like this -- then i use the hyphen symbol.

i'm starting to see more and more so-called journalists using the
underscore instead of the hyphen symbol and thereby confusing my
carefully considered system of syntax. besides, it's driving me up the
wall and it must stop. if you refuse to stop the underscore-for-hyphen
nonsense despite my reasonable request, any goldfish you may or may not
have in your possession will be eaten alive

(p.s. i was thinking of adding a goldfish rape threat in there, but i'm
afraid senator man-on-dog will then be obsessing over man-on-sushi
sexual abnormalities for years henceforth. poor thing has enough to
worry about these days and i'm not that cruel, you know.)
 
J

Jim Freeze

* Florian Frank said:
Adam said:
obj.method_that_takes_two_blocks {|a| ... }, {|b| ...}, third_arg

It is made that way in current Ruby 1.9:
def compose(f, g) { |x| f[g[x]] } end => nil
h = compose({ |x| 2 * x }, { |x| x + 1 })
=> # said:
=> 8

Well, this does not appear to be that new. 1.8.2 does the
same, it just requires the 'lambda' keyword:

def compose(f, g)
lambda { |x| f[g[x]] }
end
h = compose(lambda { |x| 2 * x }, lambda { |x| x + 1 })
h[3] #=> 8

However, even with the removal of lambda keyword, I think that
there is a big difference between the 'attached' block and
a block that is just another argument.

meth( {...}, {...}, ...)

is very different from:

meth {...} {...} ...

As has been said before, changing to the former, to get
multiple blocks, will change the way ruby is used
and perceived by developers. And I don't think it
would be for the better.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top