Ruby Forum Ruby-core > Drop :: as a . synonym

Posted by David A. Black (Guest)
on 23.04.2008 16:22
(Received via mailing list)
Hi --

I'd like to request the deprecation/removal of :: as a synonym for the
method-calling dot. I think it's a good opportunity to take out
something that Ruby doesn't need. We've already got the dot, which
always means "send a message", and :: already means something else
(constant resolution).

My view is that if it weren't already there, it would never occur to
anyone to put it in at this point. Of course, it *is* already there,
but I think it would be well worth taking it out. In my 7.5 years of
Ruby programming I've never seen it demonstrate any usefulness at all.


David
Posted by Luis Lavena (luislavena)
on 23.04.2008 16:30
(Received via mailing list)
On Wed, Apr 23, 2008 at 11:21 AM, David A. Black <dblack@rubypal.com> 
wrote:
>  but I think it would be well worth taking it out. In my 7.5 years of
>  Ruby programming I've never seen it demonstrate any usefulness at all.
>

Even that I agree with you, I found several examples around the web
and usage of :: over . for things like Dir::tmpdir, File::open and
others.

What about a deprecation warning in 1.9 and get rid of those in 2.0?

--
Luis Lavena
Multimedia systems
-
Human beings, who are almost unique in having the ability to learn from
the experience of others, are also remarkable for their apparent
disinclination to do so.
Douglas Adams
Posted by David A. Black (Guest)
on 23.04.2008 16:46
(Received via mailing list)
Hi --

On Wed, 23 Apr 2008, Luis Lavena wrote:

>>  anyone to put it in at this point. Of course, it *is* already there,
>>  but I think it would be well worth taking it out. In my 7.5 years of
>>  Ruby programming I've never seen it demonstrate any usefulness at all.
>>
>
> Even that I agree with you, I found several examples around the web
> and usage of :: over . for things like Dir::tmpdir, File::open and
> others.
>
> What about a deprecation warning in 1.9 and get rid of those in 2.0?

That would be fine. There's definitely a lot of usage of it, so it
wouldn't really do just to drop it suddenly.


David
Posted by Charles Oliver Nutter (Guest)
on 23.04.2008 16:52
(Received via mailing list)
David A. Black wrote:
> but I think it would be well worth taking it out. In my 7.5 years of
> Ruby programming I've never seen it demonstrate any usefulness at all.

In JRuby we use it to allow a single delimiter for package elements when
referring to a Java class.

Given the Java class java.lang.System, you can access it as
"java.lang.System", in which the intermediate "java" and "javalang"
modules are accessed with dots and the "System" at the end is a method
that returns the class, or you can access it as "java::lang::System",
where the :: replaces the . for method calls and the "System" at the end
is a direct constant reference. You can't do this without :: being
available for method calls.

A more explicit example:

module A
   module B
     class C; end
   end
   def b; B; end
end
def a; A; end

class MyClass < a.b.C # error...no method C() on module B
class MyClass < a::b::C # ok

- Charlie
Posted by David A. Black (Guest)
on 23.04.2008 17:05
(Received via mailing list)
Hi --

On Wed, 23 Apr 2008, Charles Oliver Nutter wrote:

>> anyone to put it in at this point. Of course, it *is* already there,
> replaces the . for method calls and the "System" at the end is a direct 
> constant reference. You can't do this without :: being available for method 
> calls.

OK... but could you do something else? :-) I don't mean that
facetiously; I'm just not sure that having two ways to get at the Java
class is worth having all the extra ::'s throughout so much Ruby code.
But I don't know enough about the problem to know how it might have
played out if . and :: had been fully differentiated in Ruby.


David
Posted by Trans (Guest)
on 23.04.2008 18:33
(Received via mailing list)
On Apr 23, 10:52 am, Charles Oliver Nutter <charles.nut...@sun.com>
wrote:
> > anyone to put it in at this point. Of course, it *is* already there,
> where the :: replaces the . for method calls and the "System" at the end
> is a direct constant reference. You can't do this without :: being
> available for method calls.

Do you run into any namespace issues with this?

If I understand you correctly this harks back to the usage of
capitalized methods as module/class factory methods or initializers;
usecases that I find quite worthy. But since namespace resolution of
methods and constants differ their use is limited.

I agree with David. And maybe, relinquishing '::' as interchangeable
with '.' could open up it's use for "method constants", and take care
of all these usecases.

T.
Posted by ara.t.howard (Guest)
on 23.04.2008 19:39
(Received via mailing list)
On Apr 23, 2008, at 8:52 AM, Charles Oliver Nutter wrote:
> can't do this without :: being available for method calls.
bingo - i do very similar things all the time as well - thousands of
lines of code....

the fact that code can be refactored so

   foo::Bar

may be module or method call is extremely useful with legacy code that
need a bit of tweaking.

i think i've written as much, or more, that about any ruby programmer
out there and i've used this feature extensively.  in fact i recently
design and api for a client which used the feature extensively and the
client specifically commented on how 'pretty' the resulting api was.

the real question is if it causes some problem and, we know, it does
not.  confusion not counting as a problem because that would lead to
the removed of *many* great ruby features.

besides - having 'one way' to do things is the python mindset ;-)

regards.

a @ http://codeforpeople.com/
Posted by Meinrad Recheis (Guest)
on 23.04.2008 19:55
(Received via mailing list)
it is not possible to remove an established feature of a programming
language without very good reasons. hundreds of people who have been got
used to them will bring up thousands of counter arguments.

just an observation.

-- Henon
Posted by Robert Dober (Guest)
on 23.04.2008 20:08
(Received via mailing list)
On Wed, Apr 23, 2008 at 7:54 PM, Meinrad Recheis
<meinrad.recheis@gmail.com> wrote:
> it is not possible to remove an established feature of a programming
> language without very good reasons. hundreds of people who have been got
> used to them will bring up thousands of counter arguments.
>
> just an observation.
>
> -- Henon
>
I am slightly in disfavor of this CR.
Your reasoning is sound David, but as some others I feel emotionally
attached to this idiom

Class::new {
}

Cheers
Robert


--
http://ruby-smalltalk.blogspot.com/

---
Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein
Posted by David A. Black (Guest)
on 23.04.2008 20:32
(Received via mailing list)
Hi --

On Thu, 24 Apr 2008, ara.t.howard wrote:

>> replaces the . for method calls and the "System" at the end is a direct 
> may be module or method call is extremely useful with legacy code that need a 
>
> besides - having 'one way' to do things is the python mindset ;-)

Well, between Python having "one way", and Perl having "more than one
way", I prefer not to dance to either of their tunes, and just deal
with Ruby as Ruby. I'm not really talking about mindsets or
generalities, just one particular suggestion.

One of the great things about how Ruby is designed (I mean the
process, not just the results) is that it isn't based on the "Well,
we've done X, and Y is kind of like X, so we'd better do Y"
philosophy. Rather, if X is a bad idea, then X isn't done. If Y is a
good idea, then Y is done -- even if at some level of abstract
description ("confusing" being kind of an example, I guess) X and Y
resemble each other.

If separating the :: and the . is a good idea, then it's a good idea,
and *just* doing that would be good. That's what I'm trying to
explore. It would not entail removing anything else from Ruby.

Anyway -- I think your technical point is interesting, though I can't
help thinking that if :: had not been made a superset of ., it
wouldn't stop just about any code from having been written, though
perhaps in a slightly different way.


David
Posted by Charles Oliver Nutter (Guest)
on 23.04.2008 21:13
(Received via mailing list)
David A. Black wrote:
> OK... but could you do something else? :-) I don't mean that
> facetiously; I'm just not sure that having two ways to get at the Java
> class is worth having all the extra ::'s throughout so much Ruby code.
> But I don't know enough about the problem to know how it might have
> played out if . and :: had been fully differentiated in Ruby.

You can't do this with dots:

class java::lang::System
end

- Charlie
Posted by David A. Black (Guest)
on 23.04.2008 22:04
(Received via mailing list)
Hi --

On Thu, 24 Apr 2008, Charles Oliver Nutter wrote:

> end
But that's an effect, rather than the cause, of the decisions taken
about :: and .. (Hard to end a sentence with .! :-) Maybe we're in too
deep for it to change, though. It might make more sense if I knew what
Matz had in mind with it originally (i.e., why have two
message-sending operators?).


David
Posted by Gerardo Santana Gómez Garrido (Guest)
on 23.04.2008 22:04
(Received via mailing list)
And why would you want to do that with dots? Because _JRuby_ requires 
it?

I'm probably misunderstanding it (I hope), but that would mean holding
back the reference implementation evolution because another
implementation can't/doesn't want to keep up.
Posted by Eric Mahurin (Guest)
on 23.04.2008 22:29
(Received via mailing list)
On Wed, Apr 23, 2008 at 9:21 AM, David A. Black <dblack@rubypal.com> 
wrote:

> Hi --
>
> I'd like to request the deprecation/removal of :: as a synonym for the
> method-calling dot. I think it's a good opportunity to take out
> something that Ruby doesn't need. We've already got the dot, which
> always means "send a message", and :: already means something else
> (constant resolution).


I'd actually prefer to go the other way and  add  more value to both 
"::"
and ".".

a::b - gives an object named b in the scope of a
a.b - calls an object named b in the scope of a

With this, you'd have these as equivalents:

a::b <=> a.method(:b)
a.b <=> a::b.call
a.b(x, y) <=> a::b.call(x, y)

currying could also naturally come out of this:

a::b(x, y) <=> a.method(:b).curry(x, y)
a::b(x, y)[z] <=> a.method(:b).curry(x, y)[z] <=> a.b

You could think of "a" being an object or a class in the above.  What's 
in
the scope would just be different.

just my 2 cents...

Eric
Posted by Charles Oliver Nutter (Guest)
on 23.04.2008 22:38
(Received via mailing list)
Gerardo Santana Gómez Garrido wrote:
> And why would you want to do that with dots? Because _JRuby_ requires it?
> 
> I'm probably misunderstanding it (I hope), but that would mean holding
> back the reference implementation evolution because another
> implementation can't/doesn't want to keep up.

What are you talking about? I don't care either way, but being able to
do it with dots would be nice. In this case it's simply a parser
difference that disallows the target of a class opening to be anything
other than a constant or a colon2 ("::"). And you're talking nonsense
about holding up the reference implementation. :: for method invocation
is not holding anyone or anything back.

- Charlie
Posted by Thomas Enebo (Guest)
on 23.04.2008 22:39
(Received via mailing list)
David A. Black wrote:
>>
>> You can't do this with dots:
>>
>> class java::lang::System
>> end
>
> But that's an effect, rather than the cause, of the decisions taken
> about :: and .. (Hard to end a sentence with .! :-) Maybe we're in too
> deep for it to change, though. It might make more sense if I knew what
> Matz had in mind with it originally (i.e., why have two
> message-sending operators?).
Does that really matter in lieu of the fact that multiple people are
using this 'feature'?  I think most software designers are surprised how
people end up using their software.  It certainly could be done
differently, but class/modules only take colon2/3 which means we would
need to do this over multiple lines or need to expand definition of what
can go after class/module.

-Tom
Posted by Charles Oliver Nutter (Guest)
on 23.04.2008 22:39
(Received via mailing list)
Eric Mahurin wrote:
> a.b(x, y) <=> a::b.call(x, y)
> 
> currying could also naturally come out of this:
> 
> a::b(x, y) <=> a.method(:b).curry(x, y)
> a::b(x, y)[z] <=> a.method(:b).curry(x, y)[z] <=> a.b
> 
> You could think of "a" being an object or a class in the above.  What's 
> in the scope would just be different.

That's actually not bad. It would be a.method(:b) by a long shot.

- Charlie
Posted by Austin Ziegler (austin)
on 23.04.2008 22:46
(Received via mailing list)
On Wed, Apr 23, 2008 at 4:39 PM, Charles Oliver Nutter
<charles.nutter@sun.com> wrote:
> > a.b <=> a::b.call
>
>  That's actually not bad. It would be a.method(:b) by a long shot.

I like it, too. I'm not quite sure why.

-austin
Posted by Charles Oliver Nutter (Guest)
on 23.04.2008 22:46
(Received via mailing list)
Charles Oliver Nutter wrote:
>> a.b <=> a::b.call
> That's actually not bad. It would be a.method(:b) by a long shot.
It would *beat* ...

- Charlie
Posted by Jeremy Henty (Guest)
on 23.04.2008 23:33
(Received via mailing list)
On Thu, Apr 24, 2008 at 05:03:10AM +0900, David A. Black wrote:

> Maybe we're in too deep for it to change, though.

Don't forget  that ri uses ::  for class methods.   While I personally
hate  the ::  and  never  use it  in  my code,  my  fingers are  still
programmed to use it when referring to ri.  If ri starts rejecting the
::  then I'll  probably waste  time  thinking a  method doesn't  exist
because ri spat it out, when  in fact ri just rejected the syntax.

Of course,  ri could continue to accept  the ::, but then  Ruby and ri
would no longer agree about correct  syntax, which sows the seed for a
different kind of confusion.  Are you happy looking forward to a flood
of "ri says Foo::bar exists but Ruby says FAIL!!!" bug reports?

Much as I'd *love* to  rewind time and make this change retroactively,
I'm pessimistic  about the chances  of doing it  now without a  lot of
grief.

Regards,

Jeremy Henty
Posted by David Flanagan (Guest)
on 23.04.2008 23:42
(Received via mailing list)
Austin Ziegler wrote:
>>> a::b <=> a.method(:b)
>>  That's actually not bad. It would be a.method(:b) by a long shot.
> 
> I like it, too. I'm not quite sure why.
> 
> -austin

As I see it, methods in Ruby are like methods in Java: they are not
first-class functions the way procs are but there is cumbersome
reflective access to them which we assume is slow and inefficient.

This proposed extension for :: alters that radically and makes methods
into first-class functions. That's the appeal to me. I think it would
only make sense if a::b[] was almost as efficient as a.b.  Also, I think
it would make more sense if Proc and Method could be unified into a
single class.

Having said that, I suspect that there are too many use-cases like
Charlie's where there is some value in being able to use :: to simulate
a constant, and a change like this, even in Ruby 2.0, would be too
disruptive.

  David Flanagan

P.S. David Black (who started this thread) was a technical reviewer of
my book.  One of the important marks he left on it was to purge
inappropriate uses of :: for method invocation, where I slipped into
that idiom.  Thanks David!
Posted by Tanaka Akira (Guest)
on 23.04.2008 23:56
(Received via mailing list)
In article <Pine.LNX.4.64.0804231018230.3590@rubypal.com>,
  "David A. Black" <dblack@rubypal.com> writes:

> My view is that if it weren't already there, it would never occur to
> anyone to put it in at this point. Of course, it *is* already there,
> but I think it would be well worth taking it out. In my 7.5 years of
> Ruby programming I've never seen it demonstrate any usefulness at all.

There is (only) one example which I feel "::" is suitable than ".":
Net::HTTP::Proxy().
Posted by Gerardo Santana Gómez Garrido (Guest)
on 24.04.2008 00:17
(Received via mailing list)
On 4/23/08, Charles Oliver Nutter <charles.nutter@sun.com> wrote:
> other than a constant or a colon2 ("::"). And you're talking nonsense
> about holding up the reference implementation. :: for method invocation
> is not holding anyone or anything back.
>
> - Charlie

Someone forgot to take his pill today.

Of course you do care, otherwise you wouldn't be giving your opinion,
and it impacts on, guess what, your Ruby implementation.

And for the rest of your message, it doesn't deserve any answer from me.

To contribute to the discussion, I agree with the original poster.
There's no point on having an schizophrenic :: operator, where both ::
and . have clear separate meanings, if you allow me to invoke previous
usage of these operators in other relevant languages as an argument.
Posted by Eric Mahurin (Guest)
on 24.04.2008 00:52
(Received via mailing list)
On Wed, Apr 23, 2008 at 3:28 PM, Eric Mahurin <eric.mahurin@gmail.com>
wrote:

>
> a.b <=> a::b.call
> a.b(x, y) <=> a::b.call(x, y)
>

BTW, this does break compatibility since a::b where a is an object is an
alias for a.b.  But, I think the current behavior is confusing and
inconsistent.  I definitely agree that "::" shouldn't sometimes act as 
an
alias for ".".

Here's an example:

class A
  class B;end
  def self.B;"A.B";end
  def self.C;"A.C";end
  class D;end
  def e;"A#e";end
  def F;"A#F";end
end
=> nil
irb(main):002:0> A.B
=> "A.B"
irb(main):003:0> A::B
=> A::B
irb(main):004:0> A.C
=> "A.C"
irb(main):005:0> A::C
NameError: uninitialized constant A::C
        from (irb):5
        from :0
irb(main):006:0> A.D
NoMethodError: undefined method `D' for A:Class
        from (irb):6
        from :0
irb(main):007:0> A::D
=> A::D
irb(main):008:0> a = A.new
=> #<A:0xb7c55a8c>
irb(main):009:0> a.e
=> "A#e"
irb(main):010:0> a::e
=> "A#e"
irb(main):011:0> a.F
=> "A#F"
irb(main):012:0> a::F
TypeError: #<A:0xb7c55a8c> is not a class/module
        from (irb):12
        from :0

From this, it is difficult to describe "::".  It looks to be either:
- left is a class/module: scope resolution operator
- left is a non class/module and right is a uppercase name: invalid
- left is a non class/module and right is a lowercase name: method call

I think "::" should have one meaning: scope resolution for an object. 
And
"." already means calling a method.

Eric
Posted by David A. Black (Guest)
on 24.04.2008 03:50
(Received via mailing list)
Hi --

On Thu, 24 Apr 2008, Thomas Enebo wrote:

>>>> played out if . and :: had been fully differentiated in Ruby.
>> message-sending operators?).
> Does that really matter in lieu of the fact that multiple people are using 
> this 'feature'?  I think most software designers are surprised how people end 
> up using their software.  It certainly could be done differently, but 
> class/modules only take colon2/3 which means we would need to do this over 
> multiple lines or need to expand definition of what can go after 
> class/module.

I know what you're saying, but I am actually curious about the
origins. I don't know whether it really matters, in practical terms. I
guess it's always a judgment call how much the amount people use
something weighs against whether it's fundamentally something that
makes sense for the language. I can't help thinking that if :: had
been, all along, just for constant resolution, and . were the
universal way to send messages to objects, no one would be submitting
RCRs suggesting that they be semi-merged :-) Of course one can't turn
back the clock, though I don't think this change would be any more
radical than something like adding block-local variables and the
syntax changes that come with that.


David
Posted by Jeremy McAnally (Guest)
on 24.04.2008 08:21
(Received via mailing list)
Or changing #send to private...or (insert progressive but code
breaking change here)... ;)

I really resonate with your approach to thinking about language
features.  I've always thought that languages take the wrong approach
when "working towards something new, exciting, bigger, and better"
rather than "working towards what the language should have been."  The
latter results in a much cleaner language, where features become more
perfect versions of their original counterparts and features are
removed when they're identified as counter to the vision of the
language, and that approach is perhaps, as far as I can tell, closer
to the heart of what Matz intended for Ruby as opposed to the former.
I have a lot of thought on this, but that's for another thread I
guess...

So, when we look at things like the schizophrenic "::" operator (haha
I like that terminology), we have to ask: how should it have worked in
the first place? :)

--Jeremy

On Wed, Apr 23, 2008 at 9:49 PM, David A. Black <dblack@rubypal.com> 
wrote:
> > >
> > > > > But I don't know enough about the problem to know how it might have
> > > about :: and .. (Hard to end a sentence with .! :-) Maybe we're in too
> >
>  radical than something like adding block-local variables and the
>   ADVANCING WITH RAILS   June 16-19           Berlin
>   INTRO TO RAILS         June 24-27           London (Skills Matter)
>  See http://www.rubypal.com for details and updates!
>
>



--
http://jeremymcanally.com/
http://entp.com

Read my books:
Ruby in Practice (http://manning.com/mcanally/)
My free Ruby e-book (http://humblelittlerubybook.com/)

Or, my blogs:
http://mrneighborly.com
http://rubyinpractice.com
Posted by Michael Neumann (Guest)
on 24.04.2008 12:35
(Received via mailing list)
Eric Mahurin wrote:
 > On Wed, Apr 23, 2008 at 9:21 AM, David A. Black <dblack@rubypal.com
 > <mailto:dblack@rubypal.com>> wrote:
 >
 >     Hi --
 >
 >     I'd like to request the deprecation/removal of :: as a synonym
for the
 >     method-calling dot. I think it's a good opportunity to take out
 >     something that Ruby doesn't need. We've already got the dot, 
which
 >     always means "send a message", and :: already means something 
else
 >     (constant resolution).
 >
 >
 > I'd actually prefer to go the other way and  add  more value to both
 > "::" and ".".
 >
 > a::b - gives an object named b in the scope of a
 > a.b - calls an object named b in the scope of a

Nice idea, but a::b::c doesn't make any sense, right? Or is it method
"c" of the Proc object method(:b)?

And how about this inconsistency:

   a.b  <=>  a.b()

   a::b <!=> a::b()

In this respect, I like the current behaviour much more, which is less
inconsistent.

And think about this usage scenario, which is where "::" really helps to
mask dynamic class generation:

   module A
     class X
       C = 1
     end

     def self.GenClass(*args)
       Class.new(X) # do something here
     end
   end

   A::X
   A::X::C
   A::GenClass(1, 2, 3)
   A::GenClass(1, 2, 3)::C

Basically you can treat a method that returns a new class like a class,
which is beautiful.

Regards,

   Michael
Posted by Stefan Lang (Guest)
on 24.04.2008 13:29
(Received via mailing list)
On Mittwoch, 23. April 2008, Eric Mahurin wrote:
> On Wed, Apr 23, 2008 at 9:21 AM, David A. Black <dblack@rubypal.com> 
wrote:
>
> a::b - gives an object named b in the scope of a
> a.b - calls an object named b in the scope of a
>
> With this, you'd have these as equivalents:
>
> a::b <=> a.method(:b)
> a.b <=> a::b.call
> a.b(x, y) <=> a::b.call(x, y)

I don't think this is a good idea for Ruby. The implications
are too far reaching. It would turn Ruby from being message-
oriented to Python's attribute lookup + function call semantics.

First of all, if these semantics were actually adopted,
your equivalence table wouldn't work. There's an infinite
recursion in each line.

Second, not every "message send" in Ruby is equivalent
to a.method(:b).call. Think of method_missing.
Furthermore, I think most uses of a.method(:b) should
actually be replaced with lambda { a.b }, since it
respects Ruby's message passing nature (method_missing, again).

So I'd rather have a shorter way to say
lambda { |*args, &block| a.b(*args, &block) }

Stefan
Posted by David A. Black (Guest)
on 24.04.2008 14:18
(Received via mailing list)
Hi --

On Thu, 24 Apr 2008, Michael Neumann wrote:

>>     (constant resolution).
>    def self.GenClass(*args)
> which is beautiful.
But why have a second method-calling operator, if the first one will
work? (A.GenClass(1,2,3)::C). Also, all of the use-cases we've seen in
response to my RCR seem to involve some rather specialized
class/method interplay. I'm still not convinced that having :: as a
superset of . isn't a very loose fit for the language.


David
Posted by Charles Oliver Nutter (Guest)
on 24.04.2008 15:25
(Received via mailing list)
Jeremy McAnally wrote:
> So, when we look at things like the schizophrenic "::" operator (haha
> I like that terminology), we have to ask: how should it have worked in
> the first place? :)

I don't actually see it as being all that schizo:

# at toplevel
foo # a call
Foo # a constant

# within a module
Bar::foo # a call
Bar::Foo # a constant

Actually, perhaps the more reasonable change would be to eliminate .
completely for method invocation, since obviously the above syntax works
for all cases and better represents calling methods or accessing
constants under a given namespace. So in actuality, it's . that needs to 
go!

'baz'::capitalize
Object::new

Are we being silly yet? :)

- Charlie
Posted by Eric Mahurin (Guest)
on 24.04.2008 15:27
(Received via mailing list)
On 4/24/08, Michael Neumann <mneumann@ntecs.de> wrote:
> >     something that Ruby doesn't need. We've already got the dot, which
> Nice idea, but a::b::c doesn't make any sense, right? Or is it method
> "c" of the Proc object method(:b)?
>
> And how about this inconsistency:
>
>  a.b  <=>  a.b()
>
>  a::b <!=> a::b()


I'm not sure why this is a problem, but with the currying part of what I 
was
proposing, a::b and a::b() would be the same.  Currying x with no 
arguments
could be just x.

In this respect, I like the current behaviour much more, which is less
>    def self.GenClass(*args)
> which is beautiful.
Like David said, why not just A.GenClass(1, 2, 3)::C ?

I guess what I was suggesting would just compliment what David is 
asking.
David, from your initial message, I thought you wanted to drop "::"
altogether and alias its functionality with ".".  I guess I 
misinterpreted.
I think you are asking for non-overlapping functionality of "::" and 
".",
which I agree with.

Eric
Posted by David A. Black (Guest)
on 24.04.2008 15:47
(Received via mailing list)
Hi --

On Thu, 24 Apr 2008, Eric Mahurin wrote:

> I guess what I was suggesting would just compliment what David is asking.
> David, from your initial message, I thought you wanted to drop "::"
> altogether and alias its functionality with ".".  I guess I misinterpreted.
> I think you are asking for non-overlapping functionality of "::" and ".",
> which I agree with.

Right; I want :: to mean constant resolution and . to mean
message-sending. I think your idea about :: meaning, more generally,
object retrieval is interesting. I haven't plumbed its depths entirely
yet though.


David
Posted by David A. Black (Guest)
on 24.04.2008 15:50
(Received via mailing list)
Hi --

On Thu, 24 Apr 2008, Charles Oliver Nutter wrote:

>
> Object::new
>
> Are we being silly yet? :)

I do think it's -- well, maybe not silly, but loose and pointless (ha
ha, 'point'less) -- that 'baz'::capitalize is the same as
'baz'.capitalize. At the very least it's casting an awfully wide net
if the goal is actually to have some special-cased treatment of
methods that start with capital letters. But we still haven't heard
from Matz on what the goal was for having two method-senders.


David
Posted by Eric Mahurin (Guest)
on 24.04.2008 16:01
(Received via mailing list)
On 4/24/08, Michael Neumann <mneumann@ntecs.de> wrote:
>
> Eric Mahurin wrote:
> > I'd actually prefer to go the other way and  add  more value to both
> > "::" and ".".
> >
> > a::b - gives an object named b in the scope of a
> > a.b - calls an object named b in the scope of a
>
> Nice idea, but a::b::c doesn't make any sense, right? Or is it method
> "c" of the Proc object method(:b)?


Yep.  So, a::b::arity would probably be a better example.  A chain of 
these
"::" would typically have uppercase constants that could be arbitrary
objects (typically class/module) for all except the last that would 
refer to
a method.  The first in a chain might also be lowercase (or an 
expression)
if it is a class/module.

A possibly even better idea would be to have "::" as an overloadable
operator.  Then you could make objects that look like classes or modules
with a scope of "constants".  You could also make "." follow this
overloading (call the object from the "::" operator).

I know some of you might be seeing the similarity to python.  You can do
similar things with its overloadable "." operator (attribute accessor) 
and
overloable "()" operator (call).  The above would give you something 
similar
in a ruby syntax.  I still think it would be nice to have an 
overloadable
call operator like python, so you don't have to #call a Proc/Method.  Or
allow #[] to take a block like a normal method call (#[] would be just 
as
good then).
Posted by Eric Mahurin (Guest)
on 24.04.2008 16:02
(Received via mailing list)
On 4/24/08, Michael Neumann <mneumann@ntecs.de> wrote:
>
> Eric Mahurin wrote:
> > I'd actually prefer to go the other way and  add  more value to both
> > "::" and ".".
> >
> > a::b - gives an object named b in the scope of a
> > a.b - calls an object named b in the scope of a
>
> Nice idea, but a::b::c doesn't make any sense, right? Or is it method
> "c" of the Proc object method(:b)?


Yep.  So, a::b::arity would probably be a better example.  A chain of 
these
"::" would typically have uppercase constants that could be arbitrary
objects (typically class/module) for all except the last that would 
refer to
a method.  The first in a chain might also be lowercase (or an 
expression)
if it is a class/module.

A possibly even better idea would be to have "::" as an overloadable
operator.  Then you could make objects that look like classes or modules
with a scope of "constants".  You could also make "." follow this
overloading (call the object from the "::" operator).

I know some of you might be seeing the similarity to python.  You can do
similar things with its overloadable "." operator (attribute accessor) 
and
overloable "()" operator (call).  The above would give you something 
similar
in a ruby syntax.  I still think it would be nice to have an 
overloadable
call operator like python, so you don't have to #call a Proc/Method.  Or
allow #[] to take a block like a normal method call (#[] would be just 
as
good then).
Posted by Yukihiro Matsumoto (Guest)
on 24.04.2008 16:14
(Received via mailing list)
Hi,

In message "Re: [RCR] Drop :: as a . synonym"
    on Thu, 24 Apr 2008 22:48:37 +0900, "David A. Black" 
<dblack@rubypal.com> writes:

|I do think it's -- well, maybe not silly, but loose and pointless (ha
|ha, 'point'less) -- that 'baz'::capitalize is the same as
|'baz'.capitalize. At the very least it's casting an awfully wide net
|if the goal is actually to have some special-cased treatment of
|methods that start with capital letters. But we still haven't heard
|from Matz on what the goal was for having two method-senders.

The "::" for method invocation is a clue to emphasize class methods,
which are often treated specially in other programming languages.  In
Ruby, they are mere methods of mere objects.  But sometimes it might
be useful to treat class methods special to improve readability.

              matz.
Posted by Jeremy McAnally (Guest)
on 24.04.2008 18:07
(Received via mailing list)
I see your point there, but there are only two use cases I can think
of for that:

   1) Code readability
   2) Documentation

I think there are already conventions in place for both.  In the case
of code readability, it's self-defeatng because :: isn't always class
methods or constant resolution, injecting ambiguity into what would
otherwise be clear code.  In documentation, typically instance methods
are indicated using '#', so using something special for class methods
(like '::' if you have to) makes sense but that doesn't mean it has to
be part of the syntax (i.e., you don't see people calling
"thing"#downcase ;)).

I dunno.  You can see my previous post for my rationale, so I won't
cover it here.  But removing that bit of ambiguity would make things
easier to scan and understand for me.

--Jeremy

On Thu, Apr 24, 2008 at 10:13 AM, Yukihiro Matsumoto 
<matz@ruby-lang.org> wrote:
>  |methods that start with capital letters. But we still haven't heard
>  |from Matz on what the goal was for having two method-senders.
>
>  The "::" for method invocation is a clue to emphasize class methods,
>  which are often treated specially in other programming languages.  In
>  Ruby, they are mere methods of mere objects.  But sometimes it might
>  be useful to treat class methods special to improve readability.
>
>                                                         matz.
>
>



--
http://jeremymcanally.com/
http://entp.com

Read my books:
Ruby in Practice (http://manning.com/mcanally/)
My free Ruby e-book (http://humblelittlerubybook.com/)

Or, my blogs:
http://mrneighborly.com
http://rubyinpractice.com
Posted by Michael Neumann (Guest)
on 24.04.2008 20:58
(Received via mailing list)
David A. Black wrote:
>>>     I'd like to request the deprecation/removal of :: as a synonym 
>>  module A
>>  A::X::C
> superset of . isn't a very loose fit for the language.
Personally I prefer

   A::GenClass(1,2,3)::C

over

   A.GenClass(1,2,3)::C

Here "GenClass" should be seen as a "dynamic class",
something in-between a class (constant) and a method :)

Regards,

   Michael
Posted by David A. Black (Guest)
on 24.04.2008 21:49
(Received via mailing list)
Hi Matz --

On Thu, 24 Apr 2008, Yukihiro Matsumoto wrote:

> |from Matz on what the goal was for having two method-senders.
>
> The "::" for method invocation is a clue to emphasize class methods,
> which are often treated specially in other programming languages.  In
> Ruby, they are mere methods of mere objects.  But sometimes it might
> be useful to treat class methods special to improve readability.

It doesn't improve readability, though.  This is completely readable:

   File.new

If someone doesn't understand that File is an object, then obviously
they have to learn about classes being objects (if they want to
understand the language at all). Once they see that File is an object,
and that .new sends the message "new", the notation is completely
clear, and :: cannot make it more clear.

People can learn to read "File::new", and they can wonder why it
exists. If it's really because other languages treat class methods
specially, maybe they should find that out by studying those other
languages :-) I tend to feel that the "mere methods of mere objects"
principle is more central here.

I guess my view is that the unified model that Ruby represents, where
classes are objects and objects receive messages, should eliminate any
need to have a special-case notation for class methods -- and, of
course, the other issue is that :: isn't a special-case notation.


David
Posted by Paul Brannan (cout)
on 24.04.2008 22:14
(Received via mailing list)
On Thu, Apr 24, 2008 at 05:28:39AM +0900, Eric Mahurin wrote:
> a::b - gives an object named b in the scope of a
> a.b - calls an object named b in the scope of a
> 
> With this, you'd have these as equivalents:
> 
> a::b <=> a.method(:b)
> a.b <=> a::b.call
> a.b(x, y) <=> a::b.call(x, y)
> 

I REALLY like this idea, with a few exceptions:

1) You haven't specified what happens in this case:

  class A
    B = 42
    def self.B; 43; end
  end
  p A::B

(currently A::B returns the constant B in class A and A::B() is
equivalent to A.B())

2) Conceptually constants exist in the class/module while singleton
   methods exist as instance methods of the class/module's singleton
   class.  For example:

   class Foo
     SomeConstant = 42
     def self.some_method; 42; end
   end
   p Foo::SomeConstant # lookup happens in Foo
   p Foo::some_method  # lookup happens in Foo's singleton class

   Thus we have the illusion of unification of constant and method
   lookup without actually getting it.

3) This change breaks code without providing a transition path.  If the
   :: sytax were to be temporarily deprecated for methods, it would be
   years (ruby 2.0, most likely) before we would actually see this
   change.  Perhaps we could use a different operator instead?

> currying could also naturally come out of this:
> 
> a::b(x, y) <=> a.method(:b).curry(x, y)
> a::b(x, y)[z] <=> a.method(:b).curry(x, y)[z] <=> a.b

Why do you find #curry to be a more natural meaning for () than #call?

Paul
Posted by Paul Brannan (cout)
on 25.04.2008 01:10
(Received via mailing list)
On Fri, Apr 25, 2008 at 04:49:00AM +0900, David A. Black wrote:
> People can learn to read "File::new", and they can wonder why it
> exists. If it's really because other languages treat class methods
> specially, maybe they should find that out by studying those other
> languages :-) I tend to feel that the "mere methods of mere objects"
> principle is more central here.

While I certainly don't feel that Ruby should be changed in order to
suit users of other languages, I also feel it is foolish to ignore the
fact that certain syntactic elements feel more natural to certain
programmers because of their language backgrounds.  For example, the '.'
syntax for method invocation may feel natural to a programmer with a
background in a simula derivative, but is likely to feel foreign to
anyone else.

I have coworkers who use the :: syntax for singleton method invocation
because it feels natural to them.  The reason it feels natural is
because they come from a language that uses similar syntax for
invocation of static member functions.  If :: had never been used in
Ruby for method invocation, it would probably not be a stumbling block,
but removing it now is likely to cause confusion for many programmers.
On the other hand, afaik I am yet to meet someone who has been genuinely
confused by this syntax being available.

While I personally do not use :: for method invocation, I see little
benefit in removing this feature.

Paul
Posted by David A. Black (Guest)
on 25.04.2008 01:28
(Received via mailing list)
Hi --

On Fri, 25 Apr 2008, Paul Brannan wrote:

> programmers because of their language backgrounds.  For example, the '.'
> syntax for method invocation may feel natural to a programmer with a
> background in a simula derivative, but is likely to feel foreign to
> anyone else.
>
> I have coworkers who use the :: syntax for singleton method invocation
> because it feels natural to them.  The reason it feels natural is
> because they come from a language that uses similar syntax for
> invocation of static member functions.  If :: had never been used in

http://www.infoq.com/articles/coming-from-ruby :-) I figure it's best
to break the cycle and just try to feel at home in the language one is
actually using at a given time. Otherwise, it's just endlessly
deferred happiness: Ruby feels unnatural because you were used to X,
then when you start using Y, it feels unnatural because you're used to
Ruby, and so forth. Love the one you're with, I say :-)

> Ruby for method invocation, it would probably not be a stumbling block,
> but removing it now is likely to cause confusion for many programmers.
> On the other hand, afaik I am yet to meet someone who has been genuinely
> confused by this syntax being available.

I've seen some confusion, because it leads people to think that class
methods involves something other than just being methods. (This is
based on the convention that :: is used for method-calling only when
the receiver is a class or module, which I've always found puzzling,
though merciful considering the alternatives.) It's possible to
explain it, of course, but I'm still unable to explain why it's there.

It could definitely be interesting to explore further the kinds of
things Eric M. was talking about (i.e., rededicated and focusing the
:: to do something more purposeful, so to speak).


David
Posted by Trans (Guest)
on 25.04.2008 03:43
(Received via mailing list)
On Apr 24, 6:35 am, Michael Neumann <mneum...@ntecs.de> wrote:

>    A::X
>    A::X::C
>    A::GenClass(1, 2, 3)
>    A::GenClass(1, 2, 3)::C
>
> Basically you can treat a method that returns a new class like a class,
> which is beautiful.

It is beautiful but it has namespace issues:

   module A
     class X
       C = 1
     end

     def self.GenClass(*args)
       Class.new(X) # do something here
     end

     class B
       def whatever
         GenClass()  # <-- won't be found
      end
   end

So (unfortunately) lookup is not like a regular constant.

T.
Posted by Robert Dober (Guest)
on 25.04.2008 09:22
(Received via mailing list)
On Fri, Apr 25, 2008 at 1:27 AM, David A. Black <dblack@rubypal.com> 
wrote:
David

more I read about this, more I overcome my emotional issue because I
really start to see the beauty of your idea combined with the idea of
method retrieval.

A.b being a call and
A::b being A.method(:b)

BTW I still think that A::b is more readable than A.b because of the
increased distance it puts between words, that is the same optical
reason I like Smalltalk code for, the space being a better delimiter
than the ".".
Please kindly remark that in written language one puts a space after
",", ".", ";", "!" etc.  for a very good reason. However this is a
minor point and anyway sometimes I want to read "::" but am too lazy
to write "::" ;).

The above mentioned semantic would also indicate that the following
becomes illegal

class/module X
   C = 42
   def C; 42 end
end

which would be a good thing I believe.

Cheers
Robert


--
http://ruby-smalltalk.blogspot.com/

---
Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein
Posted by David A. Black (Guest)
on 25.04.2008 12:25
(Received via mailing list)
Hi --

On Fri, 25 Apr 2008, Robert Dober wrote:

> BTW I still think that A::b is more readable than A.b because of the
> increased distance it puts between words, that is the same optical
> reason I like Smalltalk code for, the space being a better delimiter
> than the ".".
> Please kindly remark that in written language one puts a space after
> ",", ".", ";", "!" etc.  for a very good reason.

My reason is that it's conventional and expected in my language :-) I
don't think the human brain is inherently incapable of understanding a
dot that's not followed by a space, given a situation in which it's
been trained to do so. Dots are very versatile, and so are brains :-)

Mind you, I should add that I've pretty much abandoned "readability"
as a useful concept, since people disagree strongly about it and
unless some percentage of them are lying, different things really are
more "readable" to different people. It would be nice if it were
otherwise, but that seems to be the way it is.

>
> which would be a good thing I believe.

I would tend to favor the constant, but that might not make sense.


David
Posted by Nikolai Weibull (Guest)
on 25.04.2008 13:34
(Received via mailing list)
On Fri, Apr 25, 2008 at 12:24 PM, David A. Black <dblack@rubypal.com> 
wrote:

>  On Fri, 25 Apr 2008, Robert Dober wrote:

> > class/module X
> >  C = 42
> >  def C; 42 end
> > end
> >
> > which would be a good thing I believe.

>  I would tend to favor the constant, but that might not make sense.

Why not abolish :: altogether and disallow methods that begin with an
uppercase letter and reserve those explicitly for constants (that
already must be initially capitalized)?

I'm not actually for this change, but I do appreciate the a::b "turn
into method" syntax proposal, and I guess that disallowing methods to
begin with an uppercase letter would solve any ambiguities.
Posted by James Gray (bbazzarrakk)
on 25.04.2008 14:31
(Received via mailing list)
On Apr 25, 2008, at 6:34 AM, Nikolai Weibull wrote:

>>> which would be a good thing I believe.
>
>> I would tend to favor the constant, but that might not make sense.
>
> Why not abolish :: altogether and disallow methods that begin with an
> uppercase letter and reserve those explicitly for constants (that
> already must be initially capitalized)?

That would knock out some darn useful methods in core Ruby, like
Array().

James Edward Gray II
Posted by Paul Brannan (cout)
on 25.04.2008 15:14
(Received via mailing list)
On Fri, Apr 25, 2008 at 08:34:20PM +0900, Nikolai Weibull wrote:
> Why not abolish :: altogether and disallow methods that begin with an
> uppercase letter and reserve those explicitly for constants (that
> already must be initially capitalized)?

I don't really like uppercase methods, but I wouldn't want to do without
Integer() and Float().

Paul
Posted by Eric Mahurin (Guest)
on 25.04.2008 18:54
(Received via mailing list)
On Fri, Apr 25, 2008 at 8:13 AM, Paul Brannan <pbrannan@atdesk.com> 
wrote:

> On Fri, Apr 25, 2008 at 08:34:20PM +0900, Nikolai Weibull wrote:
> > Why not abolish :: altogether and disallow methods that begin with an
> > uppercase letter and reserve those explicitly for constants (that
> > already must be initially capitalized)?
>
> I don't really like uppercase methods, but I wouldn't want to do without
> Integer() and Float().
>

I think that many/most cases where uppercase methods are used is when it
matches a class name and you want some Class#new type functionality.

The namespace between class/module methods and constants could be merged 
and
you still could get this behavior if we had one more thing: callable
objects.  The Integer() and Float() methods would correspond to calling 
the
Integer and Float classes.

This is an area where I think Python is a bit more elegant.  There is no
reason for separate "." and "::" operators.  "." simply does object 
lookup
within a scope.  That object could be a method which you can call with 
the
() operator.

But, I think something elegant could exist for Ruby and still use the 
same
syntax.  But, the first thing you need is to eliminate the overlap 
between
"::" and "." as David suggested.  "." could simply be treated as two
operations - "::" (lookup within scope) + "()" (call).  So, Ruby's "::"
would be equivalent to Python's ".".  Here would be a breakdown of this
proposal (replaced currying with calling):

a.b <=> a::b()
a.b x,y,z <=> a::b(x, y, z)
a.b(x,y,z) <=> a::b(x, y, z)  # parens not needed for "."
a::b <=> a.method(:b) or a.const_get(:b)  # namespaces merged for Module

So, here's a summary:
* "::" would not send, it would simply do constant/object lookup
* merge the class/module method namespace and class/module constant 
namespce
* "::" would be an overloadable operator
* "()" (calling) would also be an overloadable operator
* "." would be an alias for "::" plus "()".

This would clearly create compatibility issues, but you could create the
same type of API that can be done now (but the implementation would be
different - easier/consistent/natural in my opinion).  You could even 
use
use "::" for sending messages, but "()" would be required to invoke the 
call
operator.

Eric
Posted by Robert Dober (Guest)
on 25.04.2008 21:38
(Received via mailing list)
On Fri, Apr 25, 2008 at 6:52 PM, Eric Mahurin <eric.mahurin@gmail.com> 
wrote:
> > Integer() and Float().
> This is an area where I think Python is a bit more elegant.  There is no
> reason for separate "." and "::" operators.  "." simply does object lookup
> within a scope.  That object could be a method which you can call with the
> () operator.
>
> But, I think something elegant could exist for Ruby and still use the same
> syntax.  But, the first thing you need is to eliminate the overlap between
> "::" and "." as David suggested.  "." could simply be treated as two
> operations - "::" (lookup within scope) + "()" (call).  So, Ruby's "::"
> would be equivalent to Python's ".".  Here would be a breakdown of this
> proposal (replaced currying with calling):
I feel your initial idea is brilliant, and I did say so, but now I
feel you are overdoing it a little bit, but I am open to think about
it longer
>
> a.b <=> a::b()
a.b <=> a::b.call  would be nicer I think, but I am a notorious paren
hater ;), many others are not I admit freely.
> a.b x,y,z <=> a::b(x, y, z)
> a.b(x,y,z) <=> a::b(x, y, z)  # parens not needed for "." sure :)
> a::b <=> a.method(:b) or a.const_get(:b)  # namespaces merged for Module

but this is a small detail I would be very happy if Ruby would be
modified as you suggested above :)

Cheers
Robert



--
http://ruby-smalltalk.blogspot.com/

---
Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein