I'm not quite sure agree with what what you're saying.
Ruby does have references. Every variable is a reference. For example:
def foo(str)
str << " baz"
end
x = "bar"
foo x
p x # => "bar baz"
The only thing you can't do is assign back to local variables in another
scope. The only reason you can do this in C (for example) is because you're
dealing with memory explicitly, so nothing is immutable (excepting constants).
If every object in Ruby were mutable, we might not be having this discussion.
What you're really doing when you wrap something like an integer is making an
immutable object appear mutable. We already have references.
About laziness: there aren't many languages with built-in lazy evaluation.
Haskell is the only one I know of. When you do lazy evaluation where not
everything is lazy, you need to have explicit syntax both ways, like:
(let (x (delay (foo y))) ; makes x point to the delayed result of (foo y)
(bar (force x))) ; calls bar with (foo y)
Ruby even has this level of lazy evaluation with blocks (as do all langauges
with lambda expressions, although making a delay macro in Lisp is a little
more convenient).
If you want lazy initialization, you can write a proxy that behaves exactly
the same as the underlying object (after all, an object is more or less
defined by what messages it responds to, and how it does so) by simply
mirroring all methods with #method_missing.
In fact, you could use exclusively proxies, and the only thing you'd have to
change is assignment to get what you desire (I think). Like:
def assign(obja, objb)
obja.value = objb.value
end
x = Proxy(obj1)
y = Proxy(obj2)
# use x and y
assign(x, y)
# now x == y
You could have the capability to have assigning to one variable assign to
another as a side effect, but I think that would be confusing, especially
since Ruby doesn't have declared varables. For example suppose:
x = ... # is a normal variable
r = ... # is a reference to x
y = r
Now, is y a reference to variable x, or is it the object that x refers to
(apologies for the confusing language)? If it's one, how do I get the
other? If it's the former, I'd need to do r.value or something, For the latter
I'd need to use the reference notation again. So you don't gain any calrity.
It'd be no better than rolling your own.
Also, how would you assign to r without changing x, supposing you wanted to?
What if you wanted to make r refer to another variable? You can't just assign
a new reference to it, because that'd make r a reference to a reference to an
object (which might work), but it would make x a reference to that variable,
which probably wasn't intended.
Any solution would require declaration of variables, because you'd need to
specify which are regular and which are reference variables. That's something
of a disadvantage. And the benefit would be non-obvious assignment side
effects, which are of dubious value if you ask any functional purist.
One last thing and I'll wrap this up because it's getting too long. The main
use for reference variables as they're used in C/C++ is for out parameters,
because you can only return one value from a function easily (you can wrap
multiple return values in a struct and such, but that's messy). This, however,
is easily done in Ruby, since you can do multiple assignment with implicit
arrays. The only thing I can think of that's anything like out parameters
I've seen used in Ruby is with blocks, like:
callcc { |foo.vaule| # implicitly does foo.value = continuation }
However, I think that's being done away with in favor of explicit assignment:
callcc { |cc| foo.value = cc }
Anyhow, we can agree to disagree, I suppose.
The discussion is interesting
and I can see the use of having this. The only problem is that the situations
where you use it feel like (to me) "I shouldn't be doing it this way at all"
situations.
Cheers. And sorry for the long post.
- Dan