Shortcut for add unless nil?

>
> IDK how well this would work or its potential ramifications, but i
> think it fits into the 'flavor' of ruby to be able to do such things
> (i mean, you can define/change damn near *everything else* in the
> language, why not operators?)

Because that would completely break parsing. Whenever an operator
definition would be seen the whole source would need reparsing - or at
least part of it. It would be tricky to determine which part.

I'm not so sure about that. If it were just possible to specify that a
method need not be connected to its object with the "dot", it would give
the appearance of an infix operator for those who really want it, but
would only conform to the standard rules for method calls.

That's a different story because that is a fixed syntax for method
calls and *not* introducing arbitrary new operators. Introducing new
operators ad hoc changes the syntax hence you need to reparse or do
parsing completely different as I have laid out.

The parser
would just have to maintain a last-object context of one to determine
whether what follows is a method to which the last object responds.

It wouldn't work though because of ambiguity. You cannot change "a.b
c" to "a b c" which has a valid interpretation already today:

$ ruby19 -e 'def a(*x)printf("a:%p\n",x)end;def
b(*x)printf("b:%p\n",x)end;def c(*x)printf("c:%p\n",x)end;a b c'
c:
b:[nil]

$ ruby19 -e 'def a(*x)printf("a:%p\n",x)end;def
b(*x)printf("b:%p\n",x)end;def c(*x)printf("c:%p\n",x)end;a.b c'
a:
c:
-e:1:in `<main>': private method `b' called for nil:NilClass (NoMethodError)

Even simpler "a.b" means "evaluate a and invoke b on the result" while
"a b" means "evaluate b and use it as argument when calling method a".

Of course, I'm not sure that would be so great a task to dump on the
interpreter, but I don't think it would necessarily be as dire as you
describe, as long as we're willing to recognize that infix arithmetic,
comparison, and assignment operators are actually methods.

Many operators are actually methods already. (And 1.9 has expanded on
this IIRC.) But that is not the problem here, the problem lies with
the syntax. What makes operators special is not the fact that they
use a specific subset of ASCII but rather the role they play in the
syntax of the language.

Frankly, I'd be happy without infix operator syntax (with its precedence
rules) at all. 2.plus(3) is conceptually simpler than 2 + 3 in the
context of code; so is something like (+ 2 3), add(2,3,), or sum 2 3.

2.plus 3 looks pretty "infix"y to me anyway, but it's still a method call
with obvious meaning and precedence.

Yes, but the downside is that there is only one level of precedence.
The good thing about using operators in syntax is that you can have
precedence without explicit bracketing thus repeating something that
most people know from mathematics. Everybody with basic math
knowledge knows what "a + b * c" means and in what order it is
evaluated. For methods you need to do "a.plus(b.mult c)". ("times"
was already taken.) Of course we could have Ruby with the same
functionality as today without *any* operators without restriction in
functionality. But then code becomes more verbose and less elegant
and concise which is one of the strengths of the language. I am not
sure that you would be really that happy with the result - certainly I
wouldn't. :slight_smile:

Kind regards

robert

···

On Sat, Mar 26, 2011 at 4:57 PM, Chad Perrin <code@apotheon.net> wrote:

On Sat, Mar 26, 2011 at 07:21:25PM +0900, Robert Klemme wrote:

a:[nil]

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

I've found that whenever I have a variable that may be nil, doing
.to_i or .to_s or .to_a or something similar (so long as the NilClass
supports the type conversion I need) can come in handy.

So for something like:

big_array = array_or_nil_var1 + array_or_nil_var2 + array_or_nil_var3

I would just do:

big_array = array_or_nil_var1.to_a + array_or_nil_var2.to_a +
array_or_nil_var3.to_a

Aaron out.

>
> The parser would just have to maintain a last-object context of one
> to determine whether what follows is a method to which the last
> object responds.

It wouldn't work though because of ambiguity. You cannot change "a.b
c" to "a b c" which has a valid interpretation already today:

$ ruby19 -e 'def a(*x)printf("a:%p\n",x)end;def
b(*x)printf("b:%p\n",x)end;def c(*x)printf("c:%p\n",x)end;a b c'
c:
b:[nil]
a:[nil]

$ ruby19 -e 'def a(*x)printf("a:%p\n",x)end;def
b(*x)printf("b:%p\n",x)end;def c(*x)printf("c:%p\n",x)end;a.b c'
a:
c:
-e:1:in `<main>': private method `b' called for nil:NilClass (NoMethodError)

Even simpler "a.b" means "evaluate a and invoke b on the result" while
"a b" means "evaluate b and use it as argument when calling method a".

Yes, that's a good point -- and it's why I did not actually suggest Ruby
should adopt that kind of approach. The existing syntax rules of the
language make such changes difficult, to say the least.

>
> Frankly, I'd be happy without infix operator syntax (with its
> precedence rules) at all. 2.plus(3) is conceptually simpler than 2 +
> 3 in the context of code; so is something like (+ 2 3), add(2,3,), or
> sum 2 3.
>
> 2.plus 3 looks pretty "infix"y to me anyway, but it's still a method
> call with obvious meaning and precedence.

Yes, but the downside is that there is only one level of precedence.

If I don't misunderstand what you mean by that, I'm not sure that's a
problem.

The good thing about using operators in syntax is that you can have
precedence without explicit bracketing thus repeating something that
most people know from mathematics. Everybody with basic math knowledge
knows what "a + b * c" means and in what order it is evaluated. For
methods you need to do "a.plus(b.mult c)". ("times" was already taken.)

Actually, bracketing characters are not always necessary. UCBLogo uses
an interesting approach where bracketing characters are optional when
using default numbers of arguments (since some arguments can take
arbitrary numbers of arguments). For instance:

    sum 2 quotient 9 3

With some optional bracketing syntax:

    sum 2 (quotient 9 3)

For more than two arguments to sum, you would need bracketing characters:

    (sum 2 3 4)

Of course we could have Ruby with the same functionality as today
without *any* operators without restriction in functionality. But then
code becomes more verbose and less elegant and concise which is one of
the strengths of the language. I am not sure that you would be really
that happy with the result - certainly I wouldn't. :slight_smile:

One reason I might be happy with it is the fact that I guess I'd disagree
with your implied definition of elegance. I think that complex
precedence hierarchies for buckets full of operators are not as "elegant"
as a single precedence rule for operator-style methods. In fact, I
generally find it somewhat easier, in complex arithmetic operations, to
follow a chain of methods than a glut of (+-)*/% symbols with numbers
scattered amongst them, at first glance.

Obviously, your mileage may vary, depending on your experience.

Actually, one reason I would prefer the more universal syntactic style of
the language (in this case method call syntax) over special operators is
the fact that it does not require as much experience for precedence rules
to make intuitive sense, resulting in quicker uptake of the rules of the
language, thanks to the fact that the number of rules pertaining to
arithmetic and comparison is greatly reduced.

I guess I like consistency over convention, in such a case. On the other
hand, I understand the importance of convention for things like popular
adoption. If Ruby didn't have the standard set of C-style infix
operators, it probably would not have been so widely adopted, and I may
never have encountered it in the first place. That would have been
something of a tragedy, considering how much I like Ruby.

···

On Sun, Mar 27, 2011 at 03:09:05AM +0900, Robert Klemme wrote:

On Sat, Mar 26, 2011 at 4:57 PM, Chad Perrin <code@apotheon.net> wrote:

--
Chad Perrin [ original content licensed OWL: http://owl.apotheon.org ]

Nice tip, thanks!

Regards,
Iain

···

On 26 Mar 2011, at 12:41, Aaron D. Gifford wrote:

I've found that whenever I have a variable that may be nil, doing
.to_i or .to_s or .to_a or something similar (so long as the NilClass
supports the type conversion I need) can come in handy.

So for something like:

big_array = array_or_nil_var1 + array_or_nil_var2 + array_or_nil_var3

I would just do:

big_array = array_or_nil_var1.to_a + array_or_nil_var2.to_a +
array_or_nil_var3.to_a

Aaron out.