Reason for implicit block syntax?

What is the reason for the implicit block in Ruby invocations?

Is it purely syntactic sugar, to allow things to look ‘built-in’

my_func bar, baz { … block … }

Has anyone tried , or knows if it is even feasible, to have an
extensible syntax in a dynamically-typed language like Ruby? Something
where a class can define not just its method body, but also its own
combination of mix-fix invocation syntax, along the lines of:

http://www.hpl.hp.com/techreports/Compaq-DEC/SRC-RR-121.html

Still a newbie…

  http://www.hpl.hp.com/techreports/Compaq-DEC/SRC-RR-121.html

Quickly look at it, and it seems similar to hygienic macros, see

[ruby-talk:64328]

http://www.ruby-talk.org/64328

Guy Decoux

“you CAN teach an old dog …” itsme213@hotmail.com schrieb im
Newsbeitrag news:a6e48b6b.0306120851.45c29db7@posting.google.com

What is the reason for the implicit block in Ruby invocations?

What’s an “implicit block”? From the wording I’d assume you mean a block
that is not explicitely mentioned and is somehow generated. But your
example shows an explicite written block.

Is it purely syntactic sugar, to allow things to look ‘built-in’

my_func bar, baz { … block … }

Hm, what do you mean by “built in”? Do you mean that by omitting the
brackets around arguments to “my_func” it looks like a keyword?

Somehow this question reminds me on a statement that with OO languages one
can view class implementations as extensions of the language, because they
define which methods and operators one can apply to an object. I think
this is supported by the fact, that certain methods in languages like Java
and Ruby are “built in”, i.e., implemented in the interpreter.

Regards

robert

My bet is that he means
my_func bar, baz { … block … }
as opposed to
block = proc { … block …, }
my_func(bar,baz, &block) # or my_func(bar,baz,block) and having to
# explicitly use block.call instead of the
# implicit block w/ yield

IMHO it can be considered syntactic sugar used to pass an anonymous
function (lambda) to a method, but because it is so convenient it
pervades all of Ruby, first in the libs and then in my (our) code.

After having internal iterators and blocks, having to do
Enumeration e = bla.keys();
while(e.hasMoreElements) {
MyClass bla = (MyClass) e.nextElement();

}
is a PITA (for me, at least).

Syntactic sugar does make a difference in the way we use things and IMHO
this is a part of the “Ruby way”.

···

On Fri, Jun 13, 2003 at 07:31:47PM +0900, Robert Klemme wrote:

Newsbeitrag news:a6e48b6b.0306120851.45c29db7@posting.google.com

What is the reason for the implicit block in Ruby invocations?

What’s an “implicit block”? From the wording I’d assume you mean a block
that is not explicitely mentioned and is somehow generated. But your
example shows an explicite written block.

Is it purely syntactic sugar, to allow things to look ‘built-in’

my_func bar, baz { … block … }

Hm, what do you mean by “built in”? Do you mean that by omitting the
brackets around arguments to “my_func” it looks like a keyword?


_ _

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

The most important design issue… is the fact that Linux is supposed to
be fun…
– Linus Torvalds at the First Dutch International Symposium on Linux

ts decoux@moulon.inra.fr wrote

http://www.hpl.hp.com/techreports/Compaq-DEC/SRC-RR-121.html

Quickly look at it, and it seems similar to hygienic macros, see

Not quite, though they have broadly similar goals. Macros only work
for explicit macro calls with parameters, where the basic syntactic
structure of a macro call is fixed and pre-determined (e.g. Lisp,
Dylan, C). Hygienic macros happen to be careful about generating
unique variable names in the macro expansion, but still work with a
fixed pre-defined macro-call syntax).

The work I referred to permits much more flexibility in the
incremental definition of syntax, permitting something like:

join p in Persons, s in Students where equal (p.name) (s.name)

I believe such a facility would allow end-programmer to define

x foo {block} braz {other block}

as the syntax to invoke one of her methods. Perhaps the implicit block
syntax (whose rationale, I am guessing, is largely syntactic
pleasantness) might be a special case of such a more general facility.

My bet is that he means
my_func bar, baz { … block … }
as opposed to
block = proc { … block …, }

···

----- Original Message -----
From: “Mauricio Fernández” batsman.geo@yahoo.com


But since `proc’ is just a method which takes a block… aren’t these
practically identical syntax? As I see it, there’s really only one way to
make a block.

Chris

You chose the wrong line :slight_smile:
The point was that the “normal way” (with lambdas but not blocks à la
Ruby) would be
my_func(bar, baz, block)
ie. passing the lambda explicitly and having to use block.call inside
my_func, instead of having yield call the “implicit block”.

As for the creation of the block, that’s by far the most common (and
sensible) way, but what about (silly example)

irb(main):003:0> class A
irb(main):004:1> def foo(bar)
irb(main):005:2> puts “A#foo #{bar}”
irb(main):006:2> end
irb(main):007:1> end
=> nil
irb(main):008:0> block = A.instance_method(:foo).bind(A.new)
=> #<Method: A#foo>
irb(main):009:0> 2.times &block
(irb):9: warning: &' interpreted as argument prefix A#foo 0 A#foo 1 => 2 irb(main):010:0> block = A.new.method(:foo).to_proc => #<Proc:0x40189040@(irb):10> irb(main):011:0> 2.times &block (irb):11: warning: &’ interpreted as argument prefix
A#foo 0
A#foo 1
=> 2

···

On Fri, Jun 13, 2003 at 09:01:59PM +0900, Chris Pine wrote:

----- Original Message -----
From: “Mauricio Fernández” batsman.geo@yahoo.com

My bet is that he means
my_func bar, baz { … block … }
as opposed to
block = proc { … block …, }

But since `proc’ is just a method which takes a block… aren’t these
practically identical syntax? As I see it, there’s really only one way to
make a block.


_ _

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

  • JHM wonders what Joey did to earn “I’d just like to say, for the record,
    that Joey rules.”
    – Seen on #Debian

Mauricio Fernández batsman.geo@yahoo.com wrote in message

The point was that the “normal way” (with lambdas but not blocks à la
Ruby) would be
my_func(bar, baz, block)
ie. passing the lambda explicitly and having to use block.call inside
my_func, instead of having yield call the “implicit block”.

As for the creation of the block, that’s by far the most common (and
sensible) way, but what about (silly example)

irb(main):003:0> class A
irb(main):004:1> def foo(bar)
irb(main):005:2> puts “A#foo #{bar}”
irb(main):006:2> end
irb(main):007:1> end
=> nil
irb(main):008:0> block = A.instance_method(:foo).bind(A.new)
=> #<Method: A#foo>
irb(main):009:0> 2.times &block
(irb):9: warning: &' interpreted as argument prefix A#foo 0 A#foo 1 => 2 irb(main):010:0> block = A.new.method(:foo).to_proc => #<Proc:0x40189040@(irb):10> irb(main):011:0> 2.times &block (irb):11: warning: &’ interpreted as argument prefix
A#foo 0
A#foo 1
=> 2

Exactly what my question was intended to ask. So, it’s been an
interesting discussion around blocks and yield, but any answer(s) to
the question:

What is the reason for the implicit block syntax?

And, along the way, any answers to my question (on a separate thread)
about why
def … end
returns nil, instead of some kind of method object; and
class … end
returns the last expression, also instead of some kind of class
instance.

Thanks.

def … end
does not return a method object because methods are not objects in Ruby
(unless wrapped in a proc object). I don’t know Smalltalk, but I have
heard that this is one of the differences between Ruby and Smalltalk.

I am interested to know what would you want to do with a method object
that was returned after
def … end

The above is a serious question.

As to
class … end
In my irb, the above also returns nil. I don’t know the actual reason
that this design choice was made, but I assume that if the new class
needs arguments, this could be a problem and that the usual case would
be to create an object separate from the class declaration, therefore,
to turn this characteristic off would usually be required. As it is,
you can create an object of a class at any point in the program,
including immediately after the class is declared – in other words,
turn on the behavior you want. Again, I’m curious to know why you want
this (if you do).

Regards,

Mark

···

On Sunday, June 15, 2003, at 05:09 PM, you CAN teach an old dog … wrote:

[snip]

And, along the way, any answers to my question (on a separate thread)
about why
def … end
returns nil, instead of some kind of method object; and
class … end
returns the last expression, also instead of some kind of class
instance.
[snip]

Mauricio Fernández batsman.geo@yahoo.com wrote in message

The point was that the “normal way” (with lambdas but not blocks à la
Ruby) would be
my_func(bar, baz, block)
ie. passing the lambda explicitly and having to use block.call inside
my_func, instead of having yield call the “implicit block”.
Exactly what my question was intended to ask. So, it’s been an
interesting discussion around blocks and yield, but any answer(s) to
the question:

What is the reason for the implicit block syntax?

Only matz can give an authoritative answer, but here’s my guess: by
having one block passed for free (*), use of that feature is encouraged
and that affects our perception of the language (iterators & co.).

(*): there’s a small “psychological” cost in using a block, as

  • you don’t have to care about the closing ‘)’ being far away from the
    opening ‘(’
  • you don’t have to keep inventing names for the blocks as they’re
    anonymous

It’d be a real PITA to have to do
some_block = { |x| … }
bla.each(some_block)
and
bla.each({|x| …



}) #notice the ‘)’
is even worse.

That’s less of an issue on the “block receiving side”, but yield instead
of block.call is still more convenient.

And, along the way, any answers to my question (on a separate thread)
about why
def … end

There were some proposals for changes in that area for 1.8.

returns nil, instead of some kind of method object; and
class … end
returns the last expression, also instead of some kind of class
instance.

We use that to access things in that scope, for instance
class << self; self end.instance_eval { … }
which you do sometimes need.

···

On Mon, Jun 16, 2003 at 06:09:57AM +0900, you CAN teach an old dog … wrote:

_ _

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

‘Ooohh… “FreeBSD is faster over loopback, when compared to Linux
over the wire”. Film at 11.’
– Linus Torvalds

···

On Sunday, June 15, 2003, at 05:09 PM, you CAN teach an old dog … wrote:

[snip]

And, along the way, any answers to my question (on a separate thread)
about why
def … end
returns nil, instead of some kind of method object

[snip]

For those interested in seeing this in Ruby, there is an RCR and
related discussion discussing various possible return values for def
… end besides ‘nil’. So far there are 11 votes (7 - Great idea, 2 -
Good idea, 2- Rather not).

[snip]

And, along the way, any answers to my question (on a separate thread)
about why
def … end
returns nil, instead of some kind of method object; and
class … end
returns the last expression, also instead of some kind of class
instance.
[snip]

def … end
does not return a method object because methods are not objects in Ruby
(unless wrapped in a proc object). I don’t know Smalltalk, but I have
heard that this is one of the differences between Ruby and Smalltalk.

I am interested to know what would you want to do with a method object
that was returned after
def … end

One application is sugar:

private def foo
# bla
end

The above is a serious question.

As to
class … end
In my irb, the above also returns nil. I don’t know the actual reason
that this design choice was made, but I assume that if the new class
needs arguments, this could be a problem and that the usual case would
be to create an object separate from the class declaration, therefore,
to turn this characteristic off would usually be required. As it is,
you can create an object of a class at any point in the program,
including immediately after the class is declared – in other words,
turn on the behavior you want. Again, I’m curious to know why you want
this (if you do).

If he wants class … end to return the class he can always do

class Foo
#bla
self
end

···

On Mon, Jun 16, 2003 at 06:30:25AM +0900, Mark Wilson wrote:

On Sunday, June 15, 2003, at 05:09 PM, you CAN teach an old dog … > wrote:


_ _

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

Never trust an operating system you don’t have sources for. :wink:
– Unknown source

Mauricio Fernández batsman.geo@yahoo.com wrote

def … end
does not return a method object because methods are not objects in Ruby
(unless wrapped in a proc object).

class A; def foo; end; end
p A.instance_method(:foo) ==> #<UnboundMethod: A#foo>

That’s the object def … end should return.

I am interested to know what would you want to do with a method object
that was returned after
def … end

One application is sugar:

private def foo

bla

end

Or, if I added some methods to the UnboundMethod class (or class
Class), I could start attaching all kinds of interesting meta-data to
these methods.

(def foo … end) synchronized

Yes, it’s only sugar. But then I guess you can call C#'s ‘attribute’
facility syntactic sugar as well.

The above is a serious question.

The intended use is also serious.

If he wants class … end to return the class he can always do

class Foo
#bla
self
end

True. It’s less of a dead-end than the ‘nil’ returned by def…end.

···

On Mon, Jun 16, 2003 at 06:30:25AM +0900, Mark Wilson wrote: