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:
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.
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:
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?
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.
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.
You chose the wrong line
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)
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.
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)
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.
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]
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:
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).
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: