Hacker News new | ask | show | jobs
by preordained 1031 days ago
I'd argue that better relative ergonomics had diddly squat effect on Python's current position. It's first mover advantage, plain and simple. It got its hooks in data science like JavaScript got its in the browser.

I can say that personally using Ruby, Python felt like a massive step backward. I can see how others might disagree, but I feel like it's all in what you know first. On a certain level, most of us know JavaScript is just terrible, but there have been millions of new devs who knew nothing else and thought it's fine--better than fine, its great, it's the other stuff that's weird! But then you go on for a while, maybe eventually find lisp and/or functional programming, and you realize how brain-damaged our most commonly used tools really are.

5 comments

I'd argue that better relative ergonomics had diddly squat effect on Python's current position.

And you'd be wrong.

I can confidently say that since I fully expecteded python to win over ruby and it did. Every time I used to hear hipsters dev being all the rage about ruby, I knew they implicitly discounted the cognitive load that goes with learning ruby.

The path from pseudo code to working python code was ( is? ) straight forward and ruby doesn't bring anything in term of paradigm over python that justifies foregoing that advantage.

So everytime a bright mind wanted to implement a library in her field of expertise, python was her tool of choice. And that's how python conquered field after field.

> I'd argue that better relative ergonomics had diddly squat effect on Python's current position.

I'd agree with that. I've done a lot of work in Python and Ruby. I mostly do Python these days. I think Ruby's ergonomics were better, especially for novices. (E.g., if you want to know what methods you can call on an object, in Ruby you can just look at the object, but in Python there are a whole zoo of global functions you're supposed to know about. [1]) But I think ergonomics just don't matter much when compared with more practical considerations like availability of libraries or number of developers available to hire.

[1] https://docs.python.org/3/library/functions.html

Python was already the #2 scripting language (after perl; not counting Visual Basic) back in ~1994 when I learned it. Tcl was already dying out by then and Ruby hadn't been released. So you basically had Perl or Python. You're right that it was a "first mover" advantage but I don't think data science had a lot to do with it. Perl didn't evolve gracefully over the 1995-2005 period but Python did. I think it is probably as simple as that.

By 2005 or so Python was already the #1 scripting language (other than PHP, I guess).

Was python really ahead of shell for scripting in 1994?
I remember it as at that time Windows and Unix was the common systems. I know we collected statistics for our business software offering that could run on multiple types of Unix and on Windows. Around 1998 I think 70% of all customers choose Windows. It was easier and cheaper.

So, I would say that the most common scripting language in the late 90s was VBScript.

I also can't recall any of the Unix gurus at our company using Python. They used bash, zsh or other shells.

1998 was pretty different than 1994, though?
No :-)
Can you explain more about how (you feel) Python is a step backwards? I'm curious if the "steps backward" are syntax level?

I feel the Ruby community is very syntax oriented. As evidence of this:

I see Ruby developers interested in Elixir and Crystal, languages that are syntactically similar, but technically very different.

I do not see Ruby developers interested in Python, even though, if we ignore syntax, Python and Ruby mine as well be the same language. Technically speaking, and in the grand scope of all languages, Ruby and Python are very very similar.

I really wanted to love Python. As a Ruby programmer I thought Python would be like Ruby, but with a prettier syntax because of the syntactic white space.

Unfortunately this turned out not to be the case. Here's my gripes with Python as a Ruby developer that really wanted to love Python:

There's a bunch of global functions that should have been methods on objects, like `len()`. OO in general seems slapped on later, as evidenced by the weird double underscores, and the explicit this object as first arguments for methods. (OO is core to Ruby and very elegantly implemented imo).

Higher order functional programming is a lot more awkward than you would expect from a scripting language that's generally praised for its data processing qualities. It's nice that function definitions are closures but you can't make them anonymously as function arguments, the reason apparently being that Guido didn't want to complicate the parser. This is a contrast with Ruby's most interesting and unique feature, the do syntax which is a syntactic trick making it really easy to use higher order functions that take a single function as their last argument.

Sort of an aside, but from an interview I read with Guido I understand that he actually regrets making Python have semantic whitespace, he actually doesn't like it. To me the semantic whitespace is one of Python's few redeeming qualities and I just wish Ruby would have adopted it as well. Maybe if it had we'd all be unanimously using Ruby.

> There's a bunch of global functions that should have been methods on objects, like `len()`. OO in general seems slapped on later, as evidenced by the weird double underscores, and the explicit this object as first arguments for methods.

From some angles these are strange, but from where I sit they seem elegant and pragmatic.

The global functions and double underscore methods are part of the same thing: the language defining and enforcing a protocol that many types of objects should support. Other languages do this by having common names (.length() or whatever), but this has problems that the python way avoids:

- it's hard to add new ones because they share the same namespace as user code - they may have different meanings in different contexts (e.g. a line has a length, but isn't iterable) - the language can't enforce the protocol (e.g. len accepts only one argument, checks the result is an integer, and raises the correct exceptions)

For operator overloading, using regular methods with special names is nice because it avoids having special syntax for it, and makes it easier to interactively inspect and experiment with (as you can just call the methods).

The explicit self thing is similar, in that it avoids a load of special syntax: no this keyword, no syntax for static methods, no syntax for superclass calls (until super was added). It even means that there's only really one 'kind' of call.

I can see some confusion about where self actually comes from, but then most languages i've experienced where this is implicit also have corner-cases and awkwardness around it.

IMO these kind of simplifications seem a bit frivolous when looked at in isolation, but end up simplifying your mental model of the language, which helps beginners get more out of it quicker.

> It's nice that function definitions are closures but you can't make them anonymously as function arguments.

I thought this for a while, and it would still be nice in a few situations, but really it's not a burden to name your callbacks, and discouraging overly-clever code isn't a bad thing if you're trying to build an ecosystem that's accessible to as many people as possible. I used to use map/reduce/filter a lot, but most of the time list comprehensions and regular loops end up easier to read.

I agree with the objective observations, but subjectively I prefer Python.

Python's OO does feel slapped on. As a Python user I've come to see object-oriented code as just some syntax to organize data and functions. To me, it's all functions, always has been.

I'm curious to know if you have similar thoughts biased towards objects? Do you view functional code as just a way of creating and organizing object-like concepts? I have heard that Ruby is quite pure in its philosophy and approach to object orientation, like SmallTalk, but I don't know either language well enough to fully appreciate this way of thinking.

I think Ruby has a super interesting middle ground. It’s strictly OOP in that everything is an object or a method (or a block), but because of implicit method calls (no parens), implicit return values, ease of use creating anonymous blocks passed to methods, and meta programming allowing dynamic control flow (i.e. calling a method by name at runtime), it has a lot of the elegance of writing functional code. You end up with small, unit-testable, methods that you can chain together, concise syntax, and meta programming that is second only to Lisp macros. It feels a little bit like if you asked a functional programmer to design an OOP language.
For the case of Javascript, (I think) it followed "Worse is better" principle. It's been trying to be as practical as possible. And it's everywhere even though it was not really great (until new standards and Typescript come). So a new joiner would pick Javascript so he/she can have a wide choice of possibility later.

Same things are happening with Python. And if I have to be honest, if I come from a different profession and want to change my career, I would pick either Python or Javascript for my first step.