On Thu, 14 Dec 2006 dblack / wobblini.net wrote:

>> i think that makes good sense considering ruby's pattern of not
>> auto-magically munge aruements: we all agree that it's a good thing
>> that this does not work
>> 
>>    "40" + 2
>> 
>> the e.map(:m) is exactly the equivalent of that: it says "by the
>> way, if you pass me a symbol object i'll auto-magically convert that
>> to a method call on the object.
>
> I don't see a similarity.

in both cases the arguments types changes the semantics of the method.  in one
case a number is numged into a string.  in the other a symbol is munged into a
method/proc.  in both cases this behaviour is burried in the method and users
of the methods must know that passing certain classes of objects results in
different behaviour.  consider this pattern applied to more methods that take
blocks but currently no arguments - can we always make the meaning the same?


> It's not a conversion to a method; you couldn't replace the symbol with a
> method object.

   harp: > cat a.rb
   class String
     def up(*a) upcase end
   end

   s = 'forty-two'

   p(  [s].map(&:up)  )
   p(  [s].map(&s.method(:up))  )

   harp: > ruby19 a.rb
   ["FORTY-TWO"]
   ["FORTY-TWO"]


> It's just a decision to have the argument have that meaning.
> It may even be more circuitous, in a sense, than converting 2 to a string,
> but I don't think it's the same at all.

it's not __just__ having the argument have a meaning, it's having a particular
class of object specify block auto-creation when it was originally nil.  the
indirection isn't extensible to other methods, transparent, or orthongonal.
for instance, what does this do?

   enum.map(:upcase){|e| e.downcase} # noop

it could throw an error - but why should it?  we could simply have rule that
the two blocks, the implied and the actual, are always run in a given order,
say left to right.  once we're there, we take the step that multiple args be
given and that they too will be called left to right...

   enum.map(:upcase, :downcase){|e| e.upcase} # not noop

now, the impl of map is very useful and yet the code is more complex, next we
can tackle #each, then we can move on to each and every method that takes a
block but takes no args.  each one can have similar, or differnt behaviour
based on extra symbol args.  blocks that take multiple args will really
complicate the rules.  then we can doccument them....

yuk!  this is what's known as code acretion and it's a __bad_thing__.

__or__ we can write Symbol#to_proc __once__.  doccument it __once__, and every
single method in ruby, stdlibs, and user code can now leverage this
functionality to compactly specified a block of {|elem| elem.send :meth} as
simply &:meth.

you can't really think the former is a better course of action do you?

>> 
>> given that this will work all over the place, it's doubtfull that it
>> will be more obsure than a special case for map, since people will
>> use the idiom all over the place.
>
> Maybe that's what I'm afraid of.  I find it obscure and ugly.

well, that's hard to argue about.  ;-)  still, there are alot of ugly syntax
elements in ruby like

   class << self

and

   @@ugly

and

   *list

and

   self.a = :value

still.  we can just call these 'beauty marks' can't we?

;-)

-a
-- 
if you find yourself slandering anybody, first imagine that your mouth is
filled with excrement.  it will break you of the habit quickly enough. - the
dalai lama