Forum: Ruby Unification of variables and methods

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
B55aa8835b13b2cb20220aa357ede4b1?d=identicon&s=25 Charles L. (aquasync)
on 2007-02-17 06:16
The one thing that bothers me about ruby is the (as i see it?) separate
namespaces for locals and functions.

Variables take precedence, but you can override and get the functional
form in 2 ways:

  def x; 1; end
  x = 2
  x        # => 2
  x()      # => 1
  self.x   # => 1

1. It seems somewhat messy, and prohibits using () as a message (eg,
sending :call)

  x = proc { 1 }
  x()      # NoMethodError...
  x[]      # => 1

2a. It also leads to a more complex language to parse, and to those
interesting issues like:

  def x; 1; end
  x       # => 1
  x = 2 if false
  x       # => nil

2b. And other confusion as `*', '&' and '/' being mistaken at times,
with certain whitespace dependencies:

  def foo1; end
  foo2 = ''

  foo1 / 1  # this / is division
  foo1 /1   # this / starts an (as-yet unterminated) regexp.
  foo2 / 1  # this / is division also
  foo2 /1   # this / is also division! yet actually IRB trips up, looks
            # for the rest of /, then gives a SyntaxError on
compilation.

  a = [1, 2]
  foo1 * a  # * means splat
  foo2 * b  # * means multiply


I don't understand why they both just can't get along? :)
(ie at least in the same namespace, optionally with parsing not
dependent on the guessed type).
0ec4920185b657a03edf01fff96b4e9b?d=identicon&s=25 Yukihiro Matsumoto (Guest)
on 2007-02-17 07:02
(Received via mailing list)
Hi,

In message "Re: Unification of variables and methods"
    on Sat, 17 Feb 2007 14:16:24 +0900, Charles Lowe
<aquasync@gmail.com> writes:

|The one thing that bothers me about ruby is the (as i see it?) separate
|namespaces for locals and functions.

I think unification makes

  obj.foo

to retrieve foo method object a la Python, which I believe is not the
best way for programmers.  In short, I took CommonLisp way over
Scheme way.

Some points you have pointed are negotiable.

              matz.
B55aa8835b13b2cb20220aa357ede4b1?d=identicon&s=25 Charles L. (aquasync)
on 2007-02-23 07:41
Yukihiro Matsumoto wrote:
> Hi,
>
> In message "Re: Unification of variables and methods"
>     on Sat, 17 Feb 2007 14:16:24 +0900, Charles Lowe
> <aquasync@gmail.com> writes:
>
> |The one thing that bothers me about ruby is the (as i see it?) separate
> |namespaces for locals and functions.
>
> I think unification makes
>
>   obj.foo
>
> to retrieve foo method object a la Python, which I believe is not the
> best way for programmers.  In short, I took CommonLisp way over
> Scheme way.
>
> Some points you have pointed are negotiable.
>
>               matz.

Thanks for the response. In some ways i suppose, I've always found
scheme somehow more elegant that commonlisp, so perhaps we are looking
for different things...

I think though, that unification of vars/methods, and whether a bare
method name should auto-apply (as it were) are orthogonal? And I
certainly don't advocate the removal of the latter (ie obj.foo returning
a method object). That is part of what gives ruby its beauty IMO.
A unified namespace does pave the way for () to map to #call (although
such semantics aren't required), and it doesn't preclude the use of
plain methods.
Rather consider something like this:

  def foo
    ...
  end

  bar = proc { ... }

  foo   # calls a method
  foo() # also calls a method
  method(:foo) # gets method object (proc)
  bar   # gets a proc
  bar() # calls that proc

Its merely a syntactic sugar i guess, but in a way, you then have the
option of doing things python style, which is not my intention, and
possibly undesirable.

I think that the semantics are neater in the before mentioned case of
collisions:

  def x; 1; end
  x = 2
  x        # => 2
  x()      # => 1

If that final one were to either try to #call the x variable, or throw a
runtime error, or something, it would be (IMO of course) better.

In order to try to fake it for local variables, i tried this hack
once-upon-a-time:

  def method_missing(sym, *args, &block)
    sym = sym.to_s
    error = NameError.new "undefined local variable or method `#{sym}'"
    Binding.of_caller do |binding|
      raise error unless eval('local_variables', binding).include?
sym.to_s
      func = eval(sym, binding)
      raise error unless func.respond_to? :call
      func.call(*args, &block)
    end
  end

At any rate, just glad you've considered it - Ruby is great, so I trust
your judgement :)
This topic is locked and can not be replied to.