Hacker News new | ask | show | jobs
by beat 4172 days ago
You know what rocked? Perl 4.

I started on Perl 4 in the mid-1990s. It was fantastic! I started replacing thousand-line C programs with hundred-line Perl programs that were more robust and worked better, and replacing shell scripts made of awkward sed/awk pipelines with neat, tight Perl. Arrays and hashes as first class data structures? Marvelous!

Then Perl 5 ruined it all. The ridiculous, bloated "object oriented" syntax rendered it basically unreadable, without adding much useful functionality. The layers of syntax options forced teamwork-driven Perl (I wrote about 10k lines of it) to pay close attention to coding standards, closer than more consistent languages, just to not step on each other or have fights.

Then along came Python and Ruby, which shared most of the benefits of Perl (scripting, mostly), but added very clean, elegant OO syntax. Everyone who actually cared about writing decent OO scripts switched. Plus Python had much better math libs, and Ruby soon had Rails.

And Perl 6? Fourteen years and nothing to show for it, and it'll have to be backwards compatible to all the things violently wrong with Perl 5. There's no use case that isn't already covered by Python and Ruby. Unless some new technology comes along and Perl jumps in firstest with mostest (like Ruby did with Rails), no one will really care.

The average age of Perl programmers has been increasing by about one year per year since 2002 or so. I don't see that changing anytime soon.

9 comments

> And Perl 6? Fourteen years and nothing to show for it

... except a nearly feature-complete [1] compiler [2] and an impressive test suite [3]

[1] http://perl6.org/compilers/features [2] http://rakudo.org/ [3] https://github.com/perl6/roast/

> and it'll have to be backwards compatible to all the things violently wrong with Perl 5

Not at all. The whole point about Perl 6 is that it breaks backwards compatibility to fix the things that are wrong with Perl 5.

> The whole point about Perl 6 is that it breaks backwards compatibility

I think this is is a contributor to why Perl 6 will never amount to anything. That boat has sailed. Python 3 broke backwards compatibility and to my knowledge everybody is still using Python 2. Python has a lot of energy right now, so that might save it, or it might go the way of Perl when the next cool language comes out and everybody jumps ship.

Everybody IN ENTERPRISE is still using Python 2. Realistically, most of the Python ecosystem is compatible 2+3, we are seeing new libraries and programs compatible 3.3+-only, and there's no broad reason to use Python 2 anymore, with minor exceptions.
> and there's no broad reason to use Python 2 anymore, with minor exceptions.

If you count big chunks of legacy python 2 code a "minor exception", I agree.

Anyway, the big difference between python 2 -> 3 transition and the Perl 5 and Perl 6 coexistence is that nobody within the Perl community tried to end-of-live Perl 5.

Yes, that means less incentives for migrating to Perl 6, but it also reduces the risk for Perl 5 users.

I don't think anyone advocated for converting large legacy codebases 2->3. But 3 should be the "default" for new projects, and only use 2 if they have a reason.
> Python 3 broke backwards compatibility

While this is true, it's possible to write a script that will run on both Python2 and Python3, so long as you have that goal in mind. The breaking of backwards compatibility is the breaking of several APIs and assumptions.

> to my knowledge everybody is still using Python 2

This is mostly because the release of Python 3 didn't see everyone stop everything and immediately start coding in Python 3. Conversion has to bubble up from the major libraries (e.g. Django, Flask, SciPy, etc) first, before people are able to convert.

Also, switching the default Python on Linux distros takes time because you have to go through all of the packages in the package manager looking for Python scripts and make sure that anything pointed at /usr/bin/python will work with Python 3[1].

Another point is that a number of libraries delayed conversion, and didn't consider Python3 to be "stable" until around Python 3.3. Some of other libraries (cough Flask cough) delayed support for a long time because the maintainer just didn't like Python 3.

[1] I know that these aren't always working well though. A while back I found out that Comix (installed via Ubuntu) had "/usr/bin/env python" in the shebang line instead. Launching it from a Virtualenv that doesn't have PyGTK doesn't work so well... :P

One way to look at things is that Perl 6 breaks backwards compatibility with Perl 5. Another is that Perl 6 has well designed language interop and evolution features that make it so easy to nicely use code and libs from other languages that backwards compatibility becomes irrelevant.

The big problem with Perl 6 has been that the implementation has trailed the ambitions of the design. But that's changing due to pieces like Inline::Perl5 falling in to place. (See my comments nearby for more details.)

Well, not quite irrelevant. Just because language interop is easy doesn't make the fact that there doesn't exist the interop for a library you need. That said, it's also a good chance to get good sane default implementations in first. On of the problems with CPAN is finding the best of the multiple modules available that fit the need.
As I said elsewhere in this thread, Inline::Perl5 hasn't been tested against all 130,000 modules on CPAN to my knowledge, but, based on what I know of the tech and its 100% success rate so far, I'm going to assume until I hear otherwise that it already works, or will do so this year, for the vast majority.

In the unlikely event there's a module that doesn't work, then yes, you have to learn and wield a new language that isn't backwards compatible. But it is Perlish, and it is designed to coexist beautifully with Perl 5.

Ah, I had heard that Inline::Perl5 worked with (some?) XS modules, but wasn't sure I was remembering correctly, and assumed it didn't. Unfortunately, my ability to keep abreast of new Perl 6 developments has taken a big hit the last six months or so, due to increased workload. :(
Perl 6 is a new language. Its not a Python like scenario where people are looking to migrate their existing code bases from 2 to 3.

Perl 6 is for new projects. Perl 5 ecosystem continues evolve untouched. Unlike the Python 2 scenario, where 2.x won't be supported and 3.x series and its library ecosystem isn't ready anymore.

Absolutely right - Perl 4 had a clear niche (text processing, UNIX system scripting etc) and did this very well. Perl 5 added so much cruft and ugly syntax on top of this in an attempt to try to become more 'general purpose' that it lost its focus. At this point it became easier to switch to Python for 'real' programming.

There are still a lot of problems in the Perl 4 space and to be honest I wish that distributions shipped with a supported version of 4.036.

It would be rather pointless to ship Perl4, as Perl5 is almost completely backwards compatible with Perl4. Most of the parts where backwards compatibility was removed weren't actually used to a large extent. Also Perl5 didn't add that much syntax, and a big reason it was ugly is that Perl4 didn't leave a lot of space for the extra features. Which is also why Perl6 breaks backwards compatibility.

There are also some features that were eventually removed from Perl5, but not really. For example setting $[ was removed (it was a pretty stupid idea), but if you try to use it Perl loads the module arybase which re-implements that feature. (removing it simplified the internals)

If you seriously think that Perl5 is less suitable for text processing than Perl4 was, I suspect you haven't actually used the language in a while... it's still perfectly good for that. Perhaps even better, since 5.8 added extensive support for Unicode (without requiring explicit conversions and breaking everything like Python 3 did).
From a quick skimming through the docs[0], Perl 5.8's Unicode support sounds a lot like Python 2's except that the default encoding is latin1 instead of ASCII - i.e. unlike the Python 3 way of explicitly decoding binary data into Unicode text at the point where it's read (where presumably the encoding of the data is known), it will defer the decoding until the data is used (at some completely unrelated point in the program) and decode it with some assumed globally agreed upon encoding. Since there is no globally agreed encoding (Windows even has different legacy encodings between Win32 and the command prompt!) this will appear to work as long as the data is ASCII but later, when you least expect it (and someone inputs a non-ASCII string), give UnicodeDecodeError in Python 2 or garbage data in Perl 5.8.

Ned Batchelder gave an excellent talk[1] that explains how the Python 3 approach to Unicode works. I think it makes a lot more sense once you understand it; the Python 2 way was clearly broken, and it looks like Perl 5 has the same problem but hides it better.

[0] http://search.cpan.org/~jhi/perl-5.8.0/pod/perluniintro.pod

[1] http://m.youtube.com/watch?v=sgHbC6udIqc

Why are you pointing to the unicode entry doc in an ancient version of Perl?

Also according to perlunifaq the minumum version you should be using is 5.8.1 which the documents for 5.8.0 would of course not mention.

Really if you want good unicode handling you should probably use 5.16.0 or later. If you want the latest version of Unicode there are ways of changing which version of Unicode Perl is compiled with, but it is easier to just use the latest version of Perl, which is 5.20.

http://perldoc.perl.org/perluniintro.html http://perldoc.perl.org/perlunitut.html http://perldoc.perl.org/perlunifaq.html http://perldoc.perl.org/perlunicode.html

p.s. I noticed in the Python talk you linked that no one knew that the pile of poo symbol is in there because the japanese characters for luck and poo are very similar. ( I am unable to find a link to where I first read this ) The Japanese are also responsible for why we call them emoji (e means image, and moji means character. ) http://www.fastcompany.com/3037803/the-oral-history-of-the-p...

The documentation you're looking at is quite old; I'd recommend looking at the current version for a better view. (The implementation is largely the same; the documentation has just improved quite a bit since then.)

http://perldoc.perl.org/perluniintro.html

Anyways, Perl5's Unicode support is quite different from Python's.

Specifically, it doesn't have distinct "Unicode string" and "byte string" types; instead, it has a single unified string type. These strings may be internally stored as Latin1 or UTF-8, depending on how they were created, but they behave identically for almost[1] all purposes, and there are easy ways to force Perl to convert between the formats. It's still possible to create a nonsensical string if you do something silly like append Unicode characters to a string containing raw UTF-8 data, but that's not something the language can entirely protect you from.

[1]: The only exceptions I'm aware of are functions which explicitly operate on the utf8 status, like utf8::is_utf8(), and bitwise operations like &|^ and vec().

The perl developers greatly underestimated the importance of syntactic sugar and familiarity. (Java was helped a lot by looking like C).

PHP was much more friendly towards new programmers than Perl 5, it was so much easier to make simple web pages. So it took over. It didn't matter that Perl 5 was more advanced.

(oh, you uploaded module to same dir and didn't remember to add something to @INC)

> The perl developers greatly underestimated the importance of syntactic sugar and familiarity.

I don't think that's the case. The problem is that the generation of tools that have stuff in common with perl (awk, sed, shell) are completely unfamiliar to programmers which started programming in the last 15 years, compared to those that started 30 years ago.

Look at how much boilerplate code you need in Perl 5 to create a class versus C++/Java's simple class MyClass { }

You need to assign to a variable named @ISA, you need to return 1; at the bottom of the file. And 'public' members have to be listed in the EXPORT variable.

It is really funny that Perl 5 OO need more boilerplate code than Java!

A small correction there, you aren't making them public by putting them in EXPORT. What you're doing is actually using another module to munge the namespace that used your class. In fact by default all functions defined in a package that is used as a class are public by default.

And here's the boiler plate for more modern perl:

    package MyClass;
    use Moose;
    1;
You can define properties of the class using has 'property'; This will setup any accessors and also handle initializing them in the constructor that's created for you by default.
Why do you need to return 1 though? That seems pretty ridiculous.
Because that's how [require](http://p3rl.org/require) works:

> to indicate successful execution of any initialization code

Other dynamic languages have problems with "half"-loaded code. This mechanism is a defense against that.

It has uses. Sometimes you can also use it to write code that runs like a script if called in script mode (what some people are calling a modulino. If you really hate it there's a number of packages on CPAN to make it disappear.

Also new versions of Perl allow you to define a package scope and skip the '1;' Most Perl programmers don't use this yet since the benefit is very small and the cost is losing some back compatibility. Maybe in a few years it will be more common:

package MyApp::Web { ... }

Like a lot of things in Perl it has a use that might not be immediately evident. Its also possible a more elegant solution could have been found as well. Generally when I write real code I never notice it (the 1; is drowned out by docs and real code.

Technically, you don't need to return 1; you need to return a truthy value. The string "Perl syntax is dumb and hateful" works just as well.
What? I'm not a PERL programmer - I used it a bit before it grew OO features, roughly at the same time I used Turbo Pascal, so really long ago. Yet, in these examples: http://stackoverflow.com/questions/1037312/how-do-i-create-a... I see no boilerplate you speak of. If you look at this http://stackoverflow.com/questions/1037312/how-do-i-create-a... answer you'll see comparison to C++, which isn't exactly in the favour of the latter in terms of conciseness.

And then, even if it was true and you really needed to "add public methods to EXPORT variable" that's no different than modern JavaScript, right? That's how modules work in JS. Having to "return" something at the end of a module is a requirement in Lua, too - again, it's just how the module system works.

Anyway, I don't know PERL, but knowing many other languages I find your claims suspicious. It reads as if you were a recent Java convert who tries to rationalize his decision to leave PERL or something like that.

"public static void" is more boilerplate per method than Perl has per module.
You know, that's actually really insightful. I never bothered to learn awk, sed and shell because Perl did it all under one roof. I can only imagine moving from that mess to Perl must have seemed like a revelation to those that came before me, while Perl 5 to Perl 6 is less obvious.
Even Duke Nukem Forever shipped before Perl 6.
MooseX::Declare makes Perl OO actually pretty good. I like the traits system. Not that I'd pick it as a first starting point for new work, it's nice for using with existing legacy work.
Big rewrites = death
It seems so.

* Perl 6: almost everyone is on Perl 5, or switched to another language

* Python 3: many libraries and devs will stick with Python 2, several devs switched to Go

* PHP 6: unicode rewrite never released, new features backported to 5.3+, several books were published in advance with PHP 6 in the title, next release will be named PHP 7 to avoid confusion

* Lua 5.2+: half of the community stuck with 5.1 as supported with LuaJIT and is many applications (World of Warcraft, Photoshop Lightroom, Facebooks AI platform, etc.)

* VB.Net: many stick with VB 6, many switched to web development

* VBA.Net: everyone still use VBA 6/7 in various Office applications

* ASP.Net: many stuck with ASP coded in VBS/JS, many switched to similar platforms e.g. PHP

The opposite:

* Node.js: it seems many consider the io.js fork based on up-to-date v8 js engine with ES6 support (nodejs 0.11/12 branch fork) and may leave the old nodejs 0.10.x behind

* Angular.js - Don't want to be preaching - but it looks like version 2 will be die in the same way.
How does the generally successful ruby 1.8 to 1.9 transition fit in?

I think maybe is the answer it managed to barely do just as much backwards incompat as it could get away with. (Barely, it drove a lot of people crazy). But it was quite possible to write code that worked in both ruby 1.8 and 1.9, quite intentionally, despite the backwards incompatibilities.

Combined with a commitment from key players (esp Rails) to move to 1.9 and stop supporting 1.8, forcing the issue. And that it happened at a point when ruby/rails were at the peak of their popularity, not already on the downslide (Perl). Which of course effected how much backward incompat you can get away with.

That's the trick, predicting how much backwards incompat you can get away with, of course.

But of course, there's another lesson here too, which the OP astutely calls out in the "greenfield" section -- if you focus too much on stability and supporting existing projects, that's just another way to make the ecosystem go stale.

What can we learn from this? That we shouldn't attempt major changes that aren't backwards compatible?
Breaking backwards compatibility is a more apt description of that list than major rewrite.

Part of the lesson from Python 3 is that large numbers of people will only spend 3 years deciding whether a 5 year plan to make a major change to a 20 year old language succeeded or not.

Agreed. If there's one thing that Bill Gates understood better than everyone else (with the exception of maybe Intel) is that you never break backwards compatibility. You have instantly leveled the playing field for all of your competitors. Why should your users use YOUR new language if there are other languages that already exist and they are just as incompatible as your language?
It's not as simple as that. Eventually continued backwards compatibility hacks will cause non-negligible problems, and some of those same customers may start viewing the competition differently when they finally decide to rewrite or choose a new system to replace their aging one. It's a fine line.
> we shouldn't attempt major changes that aren't backwards compatible?

I think is more about practicality. Incompatible releases are a huge hassle for users; the payout should be equally huge to make it worth the effort of porting.

As the post says, a language should try to be the best choice for new projects: easier and more powerful than other choices, delivering better results with less effort. An incompatible release starts from a position where it requires more effort, so it must deliver much better results in much less time or it will be discarded on practical ground (and all the while having the same feel and strengths as previous releases - you can't make Go, call it Python 4 and expect people will love it). That's very difficult to deliver.

And compatibility was big reason why Windows 95 was a success.
I guess we should learn to design languages with extensibility in mind from the outset, so that later incompatible changes are much less likely to be necessary.
io.js has one major advantage over your other examples: it is tracking the same javascript that browsers are running.

When every major browser is moving in the same direction with a language, any server-side counterpart is best served moving in the same direction.

Without browsers, io.js would have likely ended up in the same place as all the examples above.

> The opposite: > * Node.js: it seems many consider the io.js fork based on up-to-date v8 js engine with ES6 support (nodejs 0.11/12 branch fork) and may leave the old nodejs 0.10.x behind

It seems too soon to tell what's going to happen with io.js. It was released just a few days ago.

You can add IPv6 to that list.
also opposite:

what is considered good c++ has changed pretty dramatically from what I learned in the 90s. Though afaik none of those changes were breaking.

The irony here, then, is that Perl 5 took the object system that Python had in 1995 as an example to emulate.
Is there an actively maintained fork of Perl 4 (or earlier) somewhere? Sounds like there should be.
There's really not much point. Perl 5 is 99% backwards compatible with Perl 4, so if you think Perl 4 was great, just use the Perl 5 compiler (but none of the new features).
Perl5 even still supports some of the really ugly features of Perl4 that people generally wish would go away (like &function_calls, and nested'packages'like'this.)
Indeed. While personally I think Tcl is a better language than either, professionally I jumped straight from Perl 4 to Python, bypassing Perl 5 altogether. The combination of needing rigid standards to make a codebase maintainable in big projects, with the dynamic nature of the language meaning that tool support for it was scarce, was a double whammy.

Now that I think about it, not even that big projects, teams of 10 or so devs, getting bogged down in language issues that Python simply didn't have (and no one even wished for tool support for, the was no need!)

This sounds less like "perl 5" was a downgrade, and more like, "switching from sysadmin scripts to building enterprise projects (in ~2001-~2008 Amazon.com was written in Perl) made Perl less fun".
Tcl is Fantastic.