HN2new | past | comments | ask | show | jobs | submitlogin

When reading your section on Python and ending statements with "pass", and after not finding other references to it in your blog, I have to ask about Ruby. It seems like it would check many boxes (highly extensible, no significant whitespace, begin-end blocks, quite lispy...). If you've played with Ruby, what drawbacks have you found?

What are the major advantages you found in Python and in what cases do they exceed those in CL (aside of e.g. the type system you wrote about in 2008)?



I've never written any Ruby code but I did look into it once. What turned me off was its extreme approach to object orientedness. If I want to add two numbers I want to be able to write (+ x y) or x+y. I don't want to have to write x.add(y). That's weird syntax in service of an ideology that I don't subscribe to.

There were a couple of other weird things that turned me off but I don't offhand remember what they were.

This doesn't mean I think Ruby is a bad language, just that it had some in-your-face features that didn't resonate with me.


Although the early versions weren't so, after the replacement of the base object model (see new style classes), in Python everything is an object as well, and many seem to miss that.

    print(type(1))
    print(dir(1))
produces,

    <class 'int'>
    ['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'as_integer_ratio', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']


That's true, but actually using a literal as a object is forbidden by the syntax.

    Python 3.8.9 (default, Mar 30 2022, 13:51:16) 
    [Clang 13.1.6 (clang-1316.0.21.2.3)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> 1.__abs__
      File "<stdin>", line 1
        1.__abs__
          ^
    SyntaxError: invalid syntax
    >>>
Ruby allows this:

    irb(main):001:0> 1.2.to_s
    => "1.2"
I think that's weird.


Only because those are special methods only allowed to be directly called by the runtime, doesn't change that the language model is actuall OOP based.

You could have used one of those that is allowed instead, example:

    >>> (3.2).is_integer()
    False
The parentheses are needed due to parsing precendence.

So here is your Ruby like example in Python.


Fair enough. I guess I should probably take another look at Ruby.


? Are you sure you're not confusing Ruby with something else?

x+y works just fine in Ruby.


Yeah, I was misremembering the details. But here's an example of the sort of thing that I don't like.

If I want to convert a number to a string, I do:

    x.to_s
which would lead me to think that to take the square root of a number I would do:

    x.sqrt
but I don't. It's:

    Math.sqrt(x)
So for every operation I have to remember whether it is invoked by x.op or op(x). In Lisp I don't have this cognitive load. It is always (op x).

That is not unique to Ruby. What is unique to Ruby is that the x.op style is applicable to literals. So you get weird things like 3.14159265.to_s which just looks bizarre to me.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: