"Readability" inflation

D

Dominik Bathon

What is so bad about

ary.sort_by { | it | it.meth(foo, bar, wack!) }

Nothing, it is just more typing...
Then you can even make your sourcecode readable by putting information
into the it

playlist.sort_by { | track | track.meth(foo, bar, wack!) }
instead of
playlist.sort_by { it.meth(foo, bar, wack!) }

where it is unclear what the it is.

I know that it is not very clear, you have to get the meaning from the =20
context.
The implicit version would just be for short blocks, where the meaning is=
=20
obvious from the context.
I don't want to remove the named block parameters, just offer an =20
alternative.


Dominik
 
D

Dominik Bathon

Dominik said:
So, what we really need is the implicit block variable, because it can= =20
do
all that ;-)

ary.sort_by { it.meth }

ary.sort_by { it.meth(foo, bar, wack!) }

and even:

ary.sort_by { some_hash[it] }

Uh oh...

ary.whatever_by { |it1, it2| ... }

Now we're one step away from the from "ducking" it all:

ary.whatever_by { %1.foo ... %2.bar }

Maybe

ary.whatever_by { it[0].foo ... it[1].bar }

because block variables use multiple assignment anyway.

But I would use the implicit version only for really simple things. If =20
there are multiple block variables, then please name them.

Dominik
 
R

Ryan Leavengood

I'd like to sound a note of caution about this. I think it has the
potential to disserve Ruby's interests, by moving the language away
from the thing that has been proven to be so attractive.

I agree strongly with this, and the rest of David's comments. In fact
I'll go so far as to take the probably unpopular stance that most of
these "syntax discussions" are a big waste of time. Seriously, they
are like giant distributed committee meetings that spend days talking
and arguing and yelling to produce nothing valuable at the end. The
"named arguments" and "block syntax" related threads were just
ridiculous. There have been many others over the years.

Now matz and the other old-timers have never been ones to censure or
otherwise impede discussion on this mailing list, and I certainly
wouldn't do that either. But consider all the time people spend
writing kilobytes of text on this mailing list in fairly frivolous
discussions, and add to that all the time it takes other people to
read those kilobytes. Now what if that time were spent doing something
else? Like, say, coding new Ruby libraries! Or, even more crazy,
helping on YARV!

See, I'm a pragmatist (after all, it was "The Pragmatic Programmer"
that eventually brought me into the Ruby fray back in 2001.) I think
actions speak louder than words, and that the most useful discussions
on this mailing list involve someone posing a problem, and others
solving it in interesting and elegant ways.

So I don't see much value in these syntax discussion threads which
stretch into 100s of messages, especially when in the end, nothing
really valuable comes from them. Well, I'm probably being a little
harsh here...I imagine matz considers some of the ideas people make
and maybe those are things he hasn't thought of. But overall I think a
lot of time is wasted.

So, anyhow, before you decide that this really cool new syntax should
be put into Ruby, or before you decide to add your ever so important
opinion into these infinite threads, stop. Before posting, consider
how else your time could be spent.

Just something to thing about...

Regards,
Ryan
 
R

Ryan Leavengood

Ryan,

All work and no play? :-(

Hehehe, I'm just saying that I think these discussions get out of hand
occasionally.

I do take part in some Ruby Quizzes which I find both fun and useful.
The recent thread about finding non-unique array elements got pretty
long, but in the end we all learned quite a bit. Work and play can
sometimes be combined.

Ryan
 
R

Robert Klemme

Trans said:
Ahhhhh... but can you do:

ary.sort_by.meth(foo, bar, wack!)

I think it'd rather be

ary.sort_by:)foo, :bar, :wack!)

This is definitely superior to chaining methods. For one, because chaining
causes the wrong perception that the chain is executed once but in fact a
proxy object is created behind the scenes that applies the rest of the chain
to every instance. And also the proxy object might be slower than the
direct execution of the chain. Just because it's possible it doesn't mean
it's better or more readable. My 0.02 EUR...

Kind regards

robert
 
R

Robert Klemme

Ryan Leavengood said:
Hehehe, I'm just saying that I think these discussions get out of hand
occasionally.

I think this is nothing to worry about. After all, I'm a big fan of
democracy and still think it's better than other forms of government (please
don't take the discussion down *that* road too far). But the main point
here is that it's everybody's own decision whether he / she participates in
these threads. With a little experience you can easily detect those threads
and ignore them if you feel like it. And since you're using gmail you don't
have to worry about space and or bandwidth either, do you? :)
I do take part in some Ruby Quizzes which I find both fun and useful.
The recent thread about finding non-unique array elements got pretty
long, but in the end we all learned quite a bit. Work and play can
sometimes be combined.

Definitely.

To sum up: I'm totally with David and I think we should take his statement
for what it is: a warning notice, a reminder to maybe more often try to keep
some focus but not more - especially not any form of censorship.

Kind regards

robert
 
T

Trans

ary.sort_by:)foo, :bar, :wack!)

Oh, those weren't method calls, there were parameters to #meth --I know
Enumerable doesn't support args, but I have a module EnumerableArgs
that does (And let me tell you that was a pain --I had to essentially
rewrite Enumerable from scratch!)

T.
 
R

Robert Klemme

Trans said:
Oh, those weren't method calls, there were parameters to #meth --I

Then I guess this makes a good indication how cryptic that was... :)
know Enumerable doesn't support args, but I have a module
EnumerableArgs that does (And let me tell you that was a pain --I had
to essentially rewrite Enumerable from scratch!)

What do you mean by "Enumerable doesn't support args"? It's a module not a
method. What do you need those args for?

Cheers

robert
 
T

Trans

Robert said:
Then I guess this makes a good indication how cryptic that was... :)


What do you mean by "Enumerable doesn't support args"? It's a module not a
method. What do you need those args for?

A good exmaple is ObjectSpace:

class << ObjectSpace
include EnumerableArgs
alias :each, :each_object
end

ObjectSpace.select(Class) { |c| c.name =~ /^S/ }

You can't do this with regular Enumerable b/c you cannot pass any
arguments through the enumerable methods to the underlying #each
method.

(Sorry if there are any bugs in the code. Ruby's not installed on my
system at the moment.)

T.
 
P

Pit Capitain

Trans said:
A good exmaple is ObjectSpace:

class << ObjectSpace
include EnumerableArgs
alias :each, :each_object
end

ObjectSpace.select(Class) { |c| c.name =~ /^S/ }

You can't do this with regular Enumerable b/c you cannot pass any
arguments through the enumerable methods to the underlying #each
method.

require "enumerator"

ObjectSpace.enum_for:)each_object, Class).select { |c| c.name =~ /^S/ }

Regards,
Pit
 
T

Trans

Pit said:
require "enumerator"

ObjectSpace.enum_for:)each_object, Class).select { |c| c.name =~ /^S/ }

He he! Yep, I'd call that "inflation" alright ;). Better yet, now we've
almost come full circle since #enum_for works in essentially the same
way as #every !

Don't you just love it David!? ;)

Thanks but no thanks. I'll take an Enumerable with args and a
elementwise operator over this any day.

T.
 
R

Ryan Leavengood

}

He he! Yep, I'd call that "inflation" alright ;). Better yet, now we've
almost come full circle since #enum_for works in essentially the same
way as #every !

Don't you just love it David!? ;)

Thanks but no thanks. I'll take an Enumerable with args and a
elementwise operator over this any day.

Why? Do you have a good reason beyond the fact that you took all the
time to write your Enumerable with args? The enumerator code makes
perfect sense to me, and requires less code than your version. Plus
you are modifying a core class, which is generally looked upon as a
bad practice.

Ryan
 
T

Trans

Hi Ryan,

I didn't modify a core class. EnumerableArgs is a complete rewrite of
Enumerable and stands on it own.

The Enumerator approach lacks for a few reasons.

1. Its' longer and less readable.
2. It's creates an intermedeary object.
4. It means Enumerable remains less useful.

While Enumerator may have it's uses, I do not find it's use here
"Ruby-esque", for much the same reason David disliked #every --I have
to agree.

T.
 
R

Ryan Leavengood

Hi Ryan,

I didn't modify a core class. EnumerableArgs is a complete rewrite of
Enumerable and stands on it own.

Sorry I was ambiguous. In the ObjectSpace example you modify a core class:

class << ObjectSpace
include EnumerableArgs
alias :each, :each_object
end

ObjectSpace.select(Class) { |c| c.name =3D~ /^S/ }

Though this modification is less troublesome than other kinds of changes.
The Enumerator approach lacks for a few reasons.

1. Its' longer and less readable.

Here is the code from Pit:

require "enumerator"

ObjectSpace.enum_for:)each_object, Class).select { |c| c.name =3D~ /^S/ }

How is that longer than your example above? If the unneeded whitespace
is removed from both, your example is about 50 characters longer (this
is ignoring the needed "require" line, since your example lacks it.)

And maybe I'm "in too deep" in understanding Ruby, but I find the
above very readable (but I also find inject easy to understand now
too, so...)

And while your example is also pretty easy to read, it requires some
knowledge as to what EnumerableArgs is, since the name isn't totally
obvious.
2. It's creates an intermedeary object.

Fair enough.
4. It means Enumerable remains less useful.

What happened to number 3? ;)

I'm not arguing that the code you made doesn't have some merit, I just
don't agree that it is any better than the enumerator example.
While Enumerator may have it's uses, I do not find it's use here
"Ruby-esque", for much the same reason David disliked #every --I have
to agree.

Well it seems the perspective of something being "Ruby-esque" is quite
subjective, since I find the enumerator example quite "Ruby-esque."

Regards,
Ryan
 
D

David A. Black

Hi --

To sum up: I'm totally with David and I think we should take his statement
for what it is: a warning notice, a reminder to maybe more often try to keep
some focus but not more - especially not any form of censorship.

It definitely wasn't a post about netiquette or trying to get people
to stop posting what they want. It was chiefly an analysis of why
there are so many of these suggestions, change requests, etc. that
either add punctuation or attempt to shorten already fairly concise
idioms. I thought others who have been puzzled by the phenomenon
might find it interesting.


David
 
R

Robert Klemme

Trans said:
Hi Ryan,

I didn't modify a core class. EnumerableArgs is a complete rewrite of
Enumerable and stands on it own.

The Enumerator approach lacks for a few reasons.

1. Its' longer and less readable.

Can't see this.
2. It's creates an intermedeary object.

As all the "every" approaches that promote method chaining. Those might
even create multiple proxy objects depending on the implementation.
4. It means Enumerable remains less useful.

I cannot see this.
While Enumerator may have it's uses, I do not find it's use here
"Ruby-esque", for much the same reason David disliked #every --I have
to agree.

The big advantage of Enumerator is that it implements Enumerable thus
allowing all code created for Enumerables to work with an Enumerator
instance. The big disadvantage of your approach OTOH is that you modify an
Enumerable instance and thus shadowing methods defined in Enumerable. This
may lead to unexpected effects if people rely on the original Enumerable
methods. Also, how many classes do you know that have method #each that
accepts arguments? I'd go even further than Ryan, I think Enumerator is
better in this case than your approach.

Cheers

robert
 
T

Trans

Robert what are you talking about? "You can't see" isn't a useful
argument. And your concept of EnumerableArgs seems distorted. Its just
a Mixin. Use where you want to or don't, it doesn't effect anything
else.

T.
 
R

Robert Klemme

Trans said:
Robert what are you talking about? "You can't see" isn't a useful
argument.

I didn't want to repeat Ryan's argument and just signal my approval.
Should've been clearer.
And your concept of EnumerableArgs seems distorted. Its just
a Mixin. Use where you want to or don't, it doesn't effect anything
else.

I don't think my concept of EA is distorted: even a mixin can affect other
code. As I said, code that relies on the std Enumerable behavior might be
affected if handed an instance that mixes in EA. I don't say it will but
there's a chance because EA redefines methods from Enumerable.

The other potential issue is that EA's methods may be hidden because it's
a mixin...

What about my last question? How many classes do you know that have
method #each that accepts arguments?

Kind regards

robert
 
T

Trans

As I said, code that relies on the std Enumerable behavior
might be affected if handed an instance that mixes in EA.
I don't say it will but there's a chance because EA
redefines methods from Enumerable.

Such an argument smakes dead against the whole concept of polymorphism
and duck-typing.
What about my last question? How many classes do you
know that have method #each that accepts arguments?

That's a ridiculous question. The reason you don't have ANY #each
taking parameters is becuase it won't work with Enumerable!

This whole discussion is silly. If you really think this is "longer" or
"less readable"

ObjectSpace.select(Class) { |c| c.name =~ /^S/ }

Than this:

ObjectSpace.enum_for:)each_object, Class).select { |c| c.name =~ /^S/
}

Then by all means, type away.

T.
 

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

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top