Ruby parens-free function calls [was Re: Accessing parent objects]

Rick Johnson rantingrickjohnson at gmail.com
Sun Mar 25 13:33:49 EDT 2018


On Sunday, March 25, 2018 at 9:11:35 AM UTC-5, Steven D'Aprano wrote:
> On Sun, 25 Mar 2018 04:49:21 -0700, Rick Johnson wrote:
[...]
> I never said anything about not allowing it. But since
> you've gone on the defence about parens-free function
> calls, how is this for "consistency" in Ruby?
>
> [steve at ando ruby]$ ruby ws-example.rb
> a + b => 7
> a+b   => 7
> a+ b  => 7
> a +b  => 3
>
> Here's the source code:
>
> # --- cut ---
> def a(x=4)
>     x+2
> end
>
> b = 1
> print "a + b => ", (a + b), "\n"
> print "a+b   => ", (a+b), "\n"
> print "a+ b  => ", (a+ b), "\n"
> print "a +b  => ", (a +b), "\n"
> # --- cut ---


Short of demonstrating that you have knack for writing
obfuscated code :-), i don't see the point here. One could
easily induce the same level of obfuscation by redefining
numeric operators in an unintuitive manner. But, if your
point is that Ruby's "parens-free function calls" can be
confusing in some highly contrived cases in which the
programmer can't be bothered to write code in a manner that
is intuitive, well then, all we have to do is add the
parens, and poof!, we're back in the land of sanity again.

Here, i took the liberty of un-obfuscating your code by
doing the kind of back-breaking manual labor known only to
the unfortunate inhabitants of Soviet-era gulags, and i did
it by mererly adding the empty parens to each of your method
calls. Here goes:

UGGGGH!

    > print "a() + b => ", (a + b), "\n"

ARRRRG!

    > print "a()+b   => ", (a+b), "\n"

OOOOOO!

    > print "a()+ b  => ", (a+ b), "\n"

EEEEEE!

    > print "a() +b  => ", (a +b), "\n"

(wipes-sweat-from-brow) Oh boy. That was tough.


> No, its weird because in *both cases* there are no
> arguments given, but in one case there are no arguments
> passed, but in the other case, some unknown number of
> invisible arguments are passed.
>
> Consider a bunch of Ruby function calls:
>
>     f()      # calls f with no arguments
>     f        # calls f with no arguments
>     foo()    # calls foo with no arguments
>     foo      # calls foo with no arguments
>     bar()    # calls bar with no arguments
>     bar      # calls bar with no arguments
>     super()  # calls the superclass method with no arguments
>     super    # MAGIC HAPPENS! calls the superclass method with
>                some unknown number of arguments!


The "unknown number of arguments" is equivalent to whatever
is defined by the method. In this form, Ruby's "arg-less-
super" is saving you the trouble of repeating code in a
confined space (aka: method body). Because hey, misspellings
can and do happen ya know. And if the intent of a method is
merely to pass along the arguments _verbatim_ -- which is a
common pattern utilized by OO programmers -- then why bother
with all the superfluous typing and risk the spelling
errors? Besides, Ruby does not abide by the Pythonic concept
of "explicit is better than implicit"; and there is nothing
wrong with that.

Futhermore, since when did you assume that Ruby's super was
a standard func/meth call? Because, it isn't. The only
overlap in consistency between them, is that, as is the case
with Ruby methods, you can call Ruby's super with or without
parenthesis. But the similarities stop there. 

`super` (more generally) is a fundamental feature of most OO
languages which provides a ubiquitous methodology for access
to the superclass object. Now, how exactly that feature is
implemented in each OO language depends greatly on the needs
and opinions of the devs/users of said language. So of
course Ruby's super will not behave _exactly_ like a Ruby
function, nor should it! Neither should it be assumed to
work exactly like Python's super, because now we're talking
about a completely different language with completely
different design philosophy. However, feel free to quote
from any official source which argues (hopefully
compellingly) that Ruby's super somehow fundamentally
violates the nature of what is expected from an OO language.

Finally, you forgot to show the third (explicit argument
passing form) of Ruby's super:

    super(ag1, ar2, ..., argN)

> If you want to argue that's a useful feature, okay, I'll
> give you the benefit of the doubt. But useful or not, it's
> still weird and surprising. And deeply, fundamentally
> inconsistent.

I'm not here to protect Ruby. But if Ruby's super is as
"weird and surprising" and "deeply, fundamentally
inconsistent" as you claim it to be, well then, you've
failed to provide sufficient evidence here. 

We are entitled to our own opinions, Steven. But we are not
entitled to our own facts.



More information about the Python-list mailing list