Yield does not take a block

I really like the block passing thing in ruby too. I also
think it to be one of the most distinguishing features over
many other languages. What I don't like from the method
definition perspective, is that you have no control over
whether the block is not allowed, optional, or required. I
would have liked being able to define my methods like this to
control it:

def block_prohibited(*args) ... end

def block_allowed(*args,&block=nil)
    ...
    block.call(...) if block
    ...
end

def block_required(*args,&block)
    ...
    block.call(...)
    ...
end

Of course these (at least the first and last) break
compatibility, so this ain't gonna happen. But, this would
make sense relative the way other args are defined and assigned
default values.

···

--- Jim Freeze <jim@freeze.org> wrote:

* Ryan Leavengood <mrcode@netrox.net> [2005-06-29 05:49:45
+0900]:

> I like yield as a keyword, and I think the only reason to
use &block is
> when you want to save the given block or do some other
manipulation on it
> (ask for its arity, etc.) It is a lot of extra typing to
use an &block
> parameter than just calling yield, especially if all you
want to do is
> yield a value. Conceptually I think the idea of 'yield'ing
control to a
> block is nice (though I suppose the idea of 'call'ing a
block is just as
> nice.) But I still don't think yield should be tossed (not
that matz ever
> would.)

The implicit passing of a block (that follows a method call)
and
the 'yield' keyword is one of the key signatures of Ruby and
one
that gives Ruby a great deal of power with very little
typing.

If we had the principle of absolute explicitness for
everything,
then it would be more difficult to write DSL's and we
wouldn't
have nice apps like rails. In fact, we would probably even
have
to add statement ending identifiers, like semicolons....run
away run away...

____________________________________________________
Yahoo! Sports
Rekindle the Rivalries. Sign up for Fantasy Football

Eric Mahurin wrote:

Note though that yield and &c.call work quite differently.
This has for example performance implications.

I didn't know about this advantage. From my quick benchmarks,
I found yield to take half the time as Proc#call in a loop with
the block being empty. I'd imagine the performance difference
is because yield is working with a statically typed Proc,
whereas call is using a normal dynamically typed object to
#call.

Yes. More preceisely the overhead of &b.call is in the creation of the
proc (i.e. transforming the block, storing the closure and registering the
result with GC) - with 'yield' there is no object around.

I'd imagine as ruby matures, the performance difference
between these two would become negligible or zero.

Probably but IMHO not very likely. Maybe the gap closes but my guess
would be that it remains significant.

I'd hope at
some point ruby would make optimizations when it knows the
exact class of an object - do method lookup at compile time.

IMHO this is close to impossible as knowing the class of an object tells
you nothing definite about which methods it supports and what signature
they have. (see all the discussions about static typing)

Kind regards

    robert

···

--- Robert Klemme <bob.news@gmx.net> wrote:

Eric Mahurin wrote:

Rather I have to wrap print
in a block:

    myArray.each { |elem| print elem }

Wouldn't it have been cool to just be able to write:

    myArray.each print

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

···

--- "Adam P. Jenkins" <thorin@theshire.com> wrote:

Daniel Brockman wrote:

"Adam P. Jenkins" <thorin@theshire.com> writes:

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

In article <20050628215637.45029.qmail@web41129.mail.yahoo.com>, Eric
Mahurin wrote:

What I don't like ... is that you have no control over whether the
block is not allowed, optional, or required.

What's wrong with:

  def i_hate_blocks
    raise "blocks suck" if block_given?
  end

Regards,

Jeremy Henty

Probably correct. I think there may be a little too much
flexibility in the ruby language that will prevent future
optimizations. I think the destructive modification of a class
and of an object's class (making its class a singleton) are the
main culprits. If these were non-destructive (returning a new
class or new object with a singleton class), it would have
allowed more optimization. To me, discussions about
destructive vs. non-destructive methods (reverse! vs. reverse)
are nothing compared to these.

···

--- Robert Klemme <bob.news@gmx.net> wrote:

Eric Mahurin wrote:
> --- Robert Klemme <bob.news@gmx.net> wrote:
> I'd hope at
> some point ruby would make optimizations when it knows the
> exact class of an object - do method lookup at compile
time.

IMHO this is close to impossible as knowing the class of an
object tells
you nothing definite about which methods it supports and what
signature
they have. (see all the discussions about static typing)

____________________________________________________
Yahoo! Sports
Rekindle the Rivalries. Sign up for Fantasy Football

"Adam P. Jenkins" <thorin@theshire.com> writes:

Eric Mahurin wrote:

Rather I have to wrap print in a block:

    myArray.each { |elem| print elem }

Wouldn't it have been cool to just be able to write:

    myArray.each print

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.

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

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!'.

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:

[...]

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 }
   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?

···

"Adam P. Jenkins" <thorin@theshire.com> wrote:

--
Daniel Brockman <daniel@brockman.se>

Adam P. Jenkins wrote:

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] } end
=> nil
>> h = compose({ |x| 2 * x }, { |x| x + 1 })
=> #<Proc:0x00540dbc@(irb):8>
>> h[3]
=> 8

···

--
Florian Frank

Of course. I was exaggerating when I said you have "no
control". But, that is kind-of ugly to have to do this for
every method doesn't want a block (most of them). It would be
better if the iterpreter checked this at call time just like it
handles other args (checking the arity). As it is now, you can
pass a block to just about any method that doesn't want a block
and no complaint will be given. If we didn't have
yield/block_given?, this could have been easily handled with
the &block syntax and something like arity.

I'm not suggesting to get rid of yield... I'm just ranting.

···

--- Jeremy Henty <jeremy@chaos.org.uk> wrote:

In article
<20050628215637.45029.qmail@web41129.mail.yahoo.com>, Eric
Mahurin wrote:

> What I don't like ... is that you have no control over
whether the
> block is not allowed, optional, or required.

What's wrong with:

  def i_hate_blocks
    raise "blocks suck" if block_given?
  end

__________________________________
Yahoo! Mail
Stay connected, organized, and protected. Take the tour:
http://tour.mail.yahoo.com/mailtour.html

Eric Mahurin <eric_mahurin@yahoo.com> writes:

I think the destructive modification of a class and of an object's
class (making its class a singleton) are the main culprits.

However, I ``destructively'' modify standard library classes and
modules all the time. This is a major selling point for Ruby.

If these were non-destructive (returning a new class or new object
with a singleton class), it would have allowed more optimization.

I don't see how returning a new class could be useful in any way.
For example, what should happen if you say this?

    class Numeric ; def infinite? ; false end end

···

--
Daniel Brockman <daniel@brockman.se>

Daniel Brockman wrote:

"Adam P. Jenkins" <thorin@theshire.com> writes:

Eric Mahurin wrote:

Rather I have to wrap print in a block:

   myArray.each { |elem| print elem }

Wouldn't it have been cool to just be able to write:

   myArray.each print

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:
>>> file.write
<method 'write' of 'file' objects>
>>>

# Here's a bound method
>>> sys.stdout.write
<built-in method write of file object at 0xb7fb9060>

# Here's how you can use a bound method reference
>>> w=sys.stdout.write
>>> w("Hello\n")
Hello
>>>

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.

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

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.

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?

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

···

"Adam P. Jenkins" <thorin@theshire.com> wrote:

Daniel Brockman wrote:

    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 }

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

* Florian Frank <flori@nixe.ping.de> [2005-06-30 13:31:23 +0900]:

Adam P. Jenkins wrote:

>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] } end
=> nil
>> h = compose({ |x| 2 * x }, { |x| x + 1 })
=> #<Proc:0x00540dbc@(irb):8>
>> h[3]
=> 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] }
  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.

···

--
Jim Freeze

Eric Mahurin said:

As it is now, you can
pass a block to just about any method that doesn't want a block
and no complaint will be given.

There will also be no bad side affects, besides the code in the block is
never executed. So essentially the person does not understand the
interface to the given method. I don't agree the language should enforce
this, especially given the dynamic nature of Ruby. In fact this reminds me
of all the static-typing sort of arguments we get here now and then.

I equate the above argument to someone saying this should give a warning:

false && a_very_important_method_call()

A language can only go so far in trying to stop bad programmers before it
starts hurting good programmers.

Ryan

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.

···

--- Daniel Brockman <daniel@brockman.se> wrote:

Eric Mahurin <eric_mahurin@yahoo.com> writes:

> I think the destructive modification of a class and of an
object's
> class (making its class a singleton) are the main culprits.

However, I ``destructively'' modify standard library classes
and
modules all the time. This is a major selling point for
Ruby.

____________________________________________________
Yahoo! Sports
Rekindle the Rivalries. Sign up for Fantasy Football

"Adam P. Jenkins" <thorin@theshire.com> writes:

Daniel Brockman wrote:

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:
>>> file.write
<method 'write' of 'file' objects>
>>>

In Ruby,

   IO.instance_method :write #=> #<UnboundMethod: IO#write>

# Here's a bound method
>>> sys.stdout.write
<built-in method write of file object at 0xb7fb9060>

In Ruby,

   $stdout.method :write

# Here's how you can use a bound method reference
>>> w=sys.stdout.write
>>> w("Hello\n")
Hello
>>>

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.)

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

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.

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.)

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?

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?

···

--
Daniel Brockman <daniel@brockman.se>

Zach Dennis <zdennis@mktec.com> writes:

Daniel Brockman wrote:

    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&gt;\.\)

    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 }

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?

···

--
Daniel Brockman <daniel@brockman.se>

    So really, we all have to ask ourselves:
    Am I waiting for RMS to do this? --TTN.

You could say the same thing about passing too many arguments
to a method. Why does Ruby check this case now? ... because
it is an obvious error that can easily be checked for. The
same could be done automatically for code blocks to methods -
with the right language changes. Having the yield keyword does
make it a little more difficult.

I have no idea what this has to do with static typing. I am a
very strong proponent of duck typing. We are talking about
whether a certain argument (the code block) exists in the call
not what type it is. As it stands now, this code block is
actually statically typed to Proc and not just an object that
responds to call and arity. I would prefer it to be any old
duck that can call and arity.

···

--- Ryan Leavengood <mrcode@netrox.net> wrote:

Eric Mahurin said:
>
> As it is now, you can
> pass a block to just about any method that doesn't want a
block
> and no complaint will be given.

There will also be no bad side affects, besides the code in
the block is
never executed. So essentially the person does not
understand the
interface to the given method. I don't agree the language
should enforce
this, especially given the dynamic nature of Ruby. In fact
this reminds me
of all the static-typing sort of arguments we get here now
and then.

I equate the above argument to someone saying this should
give a warning:

false && a_very_important_method_call()

A language can only go so far in trying to stop bad
programmers before it
starts hurting good programmers.

__________________________________
Discover Yahoo!
Stay in touch with email, IM, photo sharing and more. Check it out!
http://discover.yahoo.com/stayintouch.html

Eric Mahurin <eric_mahurin@yahoo.com> writes:

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:

···

I don't see how returning a new class could be useful in any way.
For example, what should happen if you say this?

   class Numeric ; def infinite? ; false end end

--
Daniel Brockman <daniel@brockman.se>

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=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.

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.

Where's David Black? He usually beats these heretical ideas down pretty fast. :slight_smile:

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