Hacker News new | ask | show | jobs
by sulam 4172 days ago
Speaking as someone who lived through this period during the formative years of my programming career, the author has completely missed the most influential language of the time and, in my mind at least, the number reason why Perl lost.

Yes, I'm talking about Java. It's easy to hate now, but Java back then replaced all the server-side Perl programming that I did in the space of about 3 years, from 1994 where CGI programming was king to 1995 and the applets craze to 1999 when I was still regularly having conversations with people about the benefits of Java vs Perl to 2001 when you were actively hurting your career by not learning Java (not least because it seemed like the only people hiring were doing enterprise Java with horrible things like EJB and CMP/BMP).

Why did Java beat Perl? Well, there's a lot to that -- but at least part of it has to do with that fact that Java was simpler and didn't have nearly as many tricks up its sleeves (also known as the write-only problem). This is similar to the argument people today make when picking Go over other options like Scala. I also don't think it hurt that Java came out of Sun, which on the one hand was extremely influential because they sold the hardware everyone with money used, but on the other wasn't influential at all because they were "big iron" to the web's "why would I buy a Sparcstation when I can just put a PC under my desk?"

Fundamentally, though, Java was very successful at becoming the language you wrote code in if you wanted to be taken seriously as a software engineer building web applications and you didn't already have 5+ years of C++ experience. Perl programmers didn't get the same respect, and so Perl died.

3 comments

There were two sides - PHP was eating a ton of share from Perl for people and businesses who just wanted to get some simple web thing going. Sun pulled out the "Java is Enterprise" card early and successfully marketed it as being a professional scalable web programming solution for enterprise class applications with a few targeted buzzwords for whatever market segment they were going for. Perl seemed like it was always looked at as an amateur tool (much as PHP/ASP generally were), while Java was taken seriously in "enterprise" spaces (largely due to Sun's success at marketing Java to businesses).

There's a wrinkle, too. Perl isn't just a web thing. It was (and is) still used in "enterprise" spaces for scripting on servers. It's still out there being used to create scripts rather than applications. In that space Ruby/Python are competing, but there's still plenty of sysadmins who use Perl since it works.

> In that space Ruby/Python are competing, but there's still plenty of sysadmins who use Perl since it works.

I don't know how it looks now, but if you login into the likes of HP-UX, Aix, Solaris and so on, usually only Perl is available.

This is what made me learn Perl, back when I was mostly into Python (.com days).

I've dabbled in the source-code of many projects. And personally I've never seen projects more incomprehensible than some of the ones I've seen built with Java. Of course, I've also seen well written Java code, however Java projects tend to be massively over-engineered and tasteless. Its popularity doesn't help either, the signal to noise ratio in the pool of Java developers being awful.

On people picking up Go over other options, well that's because people never learn and we are bound to propel shitty languages ad-nauseam.

What do you mean about Go? (And no...I'm not trying to pick a fight--just curious)
There is a common theme to early Java discussions and discussions about golang right now. I'll sum it up as "All that power/functionality/expressivness of language x is really a distraction from getting stuff done. Further it complicates the software development model of large disparate groups."

I'm not sure that theme is wrong even, but to many of us who lived through early java, golang's least common denominator approach to developer sourcing is eerily familiar.

I agree and have made that point before. Java tried to be a language for "enterprise programming", which tried to keep the language so simple that having lots of people wouldn't muck up your code. IMHO, it failed epically at this, and today we would basically laugh at the idea that Java is good at that, but it was in fact a design criterion back in the day. One could make the case that it sort of succeeded at the isolation bit, but at the cost of making everything so verbose that it's absurd and a constant stream of technologies to deal with this has been coming out for Java ever since.

Despite the taint Java left on it, it's actually a good idea! It's a common use case. After years of programming in Perl in a fairly large programmer environment I can see the virtue of the idea of using a simpler language helping keep a lot of programmers in sync in their code base, instead of living in a world where I can look at the source and virtually instantly tell both when and who it came from due to massive differences in dialect. But Java seems to have failed so badly that it soured everyone on the entire idea, and nobody has tried since.

I think Go actually has a better chance at this, not for any large reason but for a series of smaller ones. Defaulting to object composition, once you understand it, is a powerful-yet-simpler approach to putting objects together than inheritance, and makes it much easier to both use the objects of others and to create objects to use for others, because you don't need to worry about what will be F'ed up in the "child classes", as there is no such thing. Implicitly satisfied interfaces don't sound like they'd be a big change over Java, in practice it's night-and-day to be able to declare interfaces that are automatically satisfied by objects you don't control. Contrast how many ways there are to write the same Go function as there is to write it in, say, Scala. And writing some decent multithreading primitives into the core is probably a good idea for this use case, too.

It won't happen tomorrow or next year, but, arguably, rather than Rust or even Python, the language that Go is the biggest threat to in the long term is Java. And it's a threat for precisely the reasons that people on HN tend to complain about. Indeed, I personally have the same objections that most HN'ers do for personal usage, but right now bar none Go is the language I'd most like to work in, precisely because it was written for the Google use case which also happens to be the one I have.

> I agree and have made that point before. Java tried to be a language for "enterprise programming", which tried to keep the language so simple that having lots of people wouldn't muck up your code.

Wind back 35 years or so and you could have said the exact same thing about COBOL.

COBOL also failed so epically that it soured its entire core idea for decades. (That's just an additional observation, I'm not saying you claimed otherwise.)

I won't guarantee that Go will experience wild success and become an A-list language, but I will guarantee that barring some major change in approach or leadership, it will not fail so spectacularly as to destroy the entire idea of trying to create a language for programming at scale. While HN bitches, Go's penetration into exactly the space I'm describing marches on and has passed critical mass.

Wasn't COBOL more about "your accountants can understand this"?
The same arguments can be said about Perl.

An expressive language is good to work in, because reading 1 line of code instead of 100 is always better for readability and also verbosity is a cause of accidental bugs - one line of code that does the same work as 100 lines is much less probable to contain accidental bugs. Plus, the closer you have code that precisely models the business logic, the more readable it is (assuming that we aren't talking about a retarded, badly designed, non-composable DSL).

However Perl is a heavy language that also lacks common means for abstractions that people do use in Perl, like OOP. Therefore, not only are we speaking about a heavy language, but one in which you get a dozen libraries for doing things like OOP, all of them slightly incompatible with each other. Of course, Moose came along, but Moose was late (i.e. the damage was already done) and I'd argue that Moose is also overly complex. This goes over the principles outlined by Guy Steele in his "Growing a Language" presentation - either a language is very simple, with a core set of orthogonal and powerful features that allows you to build whatever you want on top (i.e. Scheme), or it's a more complex language that provides everything you need. Perl is neither of those. So one can argue that Perl is badly designed.

So you could say that Perl tainted the idea of using expressive languages, just like Java tainted the idea of using simple languages. And actually "simple" in this context is incorrect, because there's nothing simple about Java's flavor of OOP, it's just that people are familiar with Java's blend of OOP, but familiarity is not necessarily about simplicity. But I digress.

And it's a pity. For example right now my favorite is Scala. In my opinion Scala's expressivity is very different from Perl's expressivity, in that Scala's constructs are necessary and almost orthogonal and usually properly used and the abstractions are well defined. I also programmed in Perl and after 2 years of doing it I would still have problems reading code from other people, whereas this never happens to me in Scala and even if that would be the case, I have an IDE to help me out. And in my experience of training rookies to work with Scala, it's not the syntax that's problematic, but rather the design patterns and abstractions used and that have been imported from Haskell and hence are foreign to many developers. Yet in spite of this, I've seen many superficial opinions floating on the web that a language like Scala is too complicated and then when you ask those people why, it turns out that in most cases we are talking about misconceptions and unjustified fear coming from a superficial understanding of a language.

Going back to Go, the problem with Go it that it lacks the means for abstraction that I'm looking for. Go lacks generics for example, which means that building abstractions that involve higher-order functions is not feasible. And I'm sure that Go will get generics at some point, since it is inevitable, however Go is not the type of language to ever implement higher-kinded types and type-classes. I personally need type-classes, being a very different means for ad-hoc polymorphism, when compared with OOP, with different use-cases.

For example I want to work with monads or applicative functors, which in spite of their scary reputation, are just design patterns that aren't very hard to understand, their reputation being a direct consequence of them being explained by Haskell developers with a mathematical mindset. And I want to build generic functions that work over monads or applicative functors, because once you discover their power, it's very hard to go back and life is too short to reinvent the wheel every single time. And Go is not the kind of language that will ever appeal to my needs, whereas languages like Scala, Clojure and arguably Rust are such languages.

But here's the real problem that I'm seeing - scaling a software development team is done in two ways ... you either hire more people, or you hire really good people that can produce better abstractions. This is horizontal scalability versus vertical scalability. And the problem is, in a software development company, these 2 approaches are incompatible. The companies that want to scale horizontally are exactly the companies that prefer familiar languages, whereas the companies for which that isn't feasible (i.e. startups) are the companies that prefer powerful languages.

And of course, you would think that it's better to scale horizontally, depending on the problems solved, but therein lies another problem - the difference between really good people that can juggle with abstractions and juniors is not necessarily one of productivity, but rather in the range of problems they can solve. Given enough difficulty, you can hire how many juniors you want and they might still not be able to solve certain problems, whereas those same problems might be feasible for 2-3 people that are really good. Amdahl's law is also very relevant to software development. The more people you have, the more you introduce concurrency and points of synchronization, which in turn kills the parallelization possible and thus productivity.

What I'm talking about is the software crisis problem, which is still very relevant. And my personal bet is on vertical scalability, which implies working with better tools and abstractions. Because that's how we scaled math and that's how we went beyond the pyramids.

I think that's well written and makes many good points that I agree with, but something that jumps out at me is this:

> I also programmed in Perl and after 2 years of doing it I would still have problems reading code from other people

> I've seen many superficial opinions floating on the web that a language like Scala is too complicated and then when you ask those people why, it turns out that in most cases we are talking about misconceptions and unjustified fear coming from a superficial understanding of a language

That's generally the same thing I see when talking to people about Perl. I don't know the level of knowledge you gained with Perl, so I don't know if it really applies the same, but from the outside, it does look the same.

I generally view this a a problem of language power AND complexity. Complex languages take longer to learn and be comfortable with, but if the complexity is because they provide more power, what you are really doing is front-loading work to make future work easier, which pays dividends in the end. I think this also fits your description of leverage quite well.

Having spent a fair bit of time thinking the same way about growing developer teams and bouncing from 1 side of the equation to the other, I've started thinking about it like leverage.

With a lot of leverage, like a requirement for sophisticated developers and powerful languages, you can get huge payoffs. The kind that are unlikely without it. But also like leverage, small, sometimes unavoidable problems can utterly destroy your efforts.

I'm not convinced that I've ever seen a big group of average developers be highly successful, and I have seen that with a small group of great developers. But I've also seen a medium sized group of above average developers completely submarined by the complexities of their language.

I just wanted to say I agree to everything you just said. I don't feel like I've heard this viewpoint expressed better before.
Ditto on the Sys Admin side with Python - Perl had modules for everything, but the inbuilt punctuation variables mixed with regexs for everything and the flexibility Perl offered led to a perception that nobody could maintain anybody else's stuff.

Sys admins were still about getting shit done quickly at scale, and Python slowly began to replace Perl. Python 2 had string methods built in, Red Hat switched everything to Python, tool.s like LXML started coming out right when we all had to munge XML all day and suddenly that was it.