From: Robert Klemme Date: 2005-05-19T06:15:14+09:00 Subject: Re: syntax sugar: treating an object like a method "Eric Mahurin" schrieb im Newsbeitrag news:20050518193919.90114.qmail@web41105.mail.yahoo.com... > --- "David A. Black" wrote: >> Hi -- >> >> On Thu, 19 May 2005, Eric Mahurin wrote: >> >> > I'm thinking of yet another RCR and would like to see if >> > anybody likes it. I think this would be a sweet feature. >> Here >> > are the basic components: >> >> I'm not sure what the canonical definition of syntactic sugar >> is, but >> I don't think that I think this is exactly that. Anyway.... > > In my book, syntactic sugar is when you have a more > concise/readable syntax that is equivalent to a more > fundamental (and longer) syntax. So by that definition, all of > the operators that equate to methods are syntactic sugar. I > think this thing I'm talking is similar to adding another > operator. I would agree the "more concise" part if you mean "shorter" but I don't follow you on the "more readable". >> Forgetting .new is a weak reason for making it optional. It >> would be >> hard to argue that calling MyClass.new to create a new >> MyClass object >> is arcane or hard to get the hang of. > > I know it is weak. But, it did seem to prod me to develop this > idea a little more - because the vast majority of time the only > thing you do with a class is call new. That might be true for you, but there's a lot of people around that do a lot more with classes than just using them as POF (plain old factory). >> += is already the real +=. It's not the C or Perl +=, but >> it's the >> real Ruby +=. > > Correct. "real" was the wrong word. How about "in-place"? A > normal += in Ruby creates a new object whereas this one > modifies an object in-place. I like the clean way Ruby does this: you define +, -, * and / and you get +=, +-, *= and /= automatically - and they all behave similarly. Introducing in place modification would greatly complicate the matter - for the ruby runtime as well as for readers of code. Once I thought, it would have been better to do it the other way round: you can define += and get + for free. But I have abandoned that thought because it does not yield seamless type conversions, i.e. if you add something to a big Fixnum you get a Bignum: >> (1<<29).class => Fixnum >> (1<<29+1).class => Bignum Although C++ folks might argue that this sacrifices performance (and they would be right) I prefer the cleaner approach of Ruby and wait for faster hardware / Ruby runtimes; apart from that I either use a C extension or another language if I am in desparate need for speed. >> To a large extent, my reaction to all of these examples comes >> down, as >> it often does, to the question: how would I explain this to >> someone to >> whom I was teaching Ruby (in person or in writing)? I think >> I would >> find it quite difficult to explain that in this: >> >> s = "hi" >> t = s >> (s) = "bye" > > I think this is a good example to show the difference. > Programmers need to understand the difference shown above. One > assigns to a variable and one assigns into an object that a > variable has. Both are normal things you would want to do and > both are assignment-like. "an object that a variable has"? Variables refer objects but they don't exactly *have* them. I have to admit that I find the third line of the example above very confusing. One of the reasons might be that there is a quite similar construct - apparently with different semantics: >> (a,b)=%w{a b} => ["a", "b"] >> a => "a" >> b => "b" >> (a,)=%w{a b} => ["a", "b"] >> a => "a" >> Similarly, obj() requires one to figure out whether or not >> there is a >> method called obj, and if there isn't to try to figure out >> what has >> been defined as () for this particular object. > > Good point. It is similar to differentiating between a local > variable and a method call. Doing the above would do the same > between a method call and calling the default method in an > object: > > xyz - could be a local variable (default) or a method call > xyz() - could be a method call (default) or a null method call > (xyz)() - definitely a null method call > >> I fear that's the >> slippery slope to what people call "write-only code". > > You could argue that. That is what Java designers said. And > that is why they didn't allow operator overloading. I think > operator is a good thing, but someone can easily abuse it and > make write-only code. I think what I'm suggesting here is like > adding more operators. IMHO Ruby has the right balance between no operator overloading at all (Java) and too much operator overloading (C++). Another note: as far as I remember there are plans to make () work for lambdas. So currently we have >> f = lambda {|x| x+x} => # >> f[10] => 20 >> f.call 10 => 20 Then we had additionally >> f(10) => 20 (Please correct me someone if I'm wrong here.) At the moment I don't fully overlook the consequences and whether there were collisions but I have the feeling that there might be - if not technical then at least in the area of understanding and clearness. That's my 0.02 EUR... Kind regards robert