NOTE: This is a set of ramblings that may at some point turn into a full essay. As of now, however, it is a fairly disconnected set of notes. Perl needs to die. It was a nice experiment, a useful hack for a while, but it is now getting too large and have to much baggage to be fixed. Thanks for the service - Perl has taken a number of things and made them ubiquitous, it has given us some interesting perspectives on language, and it has given us the best tool ever to write one-liners - the best that has been, and maybe the best that ever will. It has also taught us a number of lessons, lessons that we should do well to bring along to our later work. These are extremely apparent when working with Perl and Ruby side by side - where Ruby is a design done with heavy inspiration from Perl, intended to fill the same space, but ten years later. - Autovification is good for small projects, and extremely evil for large ones. - If we DO check for extistence of variable names, we should do this BY DEFAULT, not on a per module basis. And it had better work. Always. (When "use strict" fails, I spend half a day debugging...) - Counting arguments to methods are suprememly important. Any implementation that does not count the number of arguments given to a method/subroutine/function/procedure/whatnot by default will lead to a large number of extra bugs. - Hashes should be harder to use than creating an object. Make hashes too easy, and people start pushing around hashes when they should be pushing around objects. This leads to hell down the road. - Methods and fields should look the same, for later override. - Attaching an OO system to an existing language does not usually work, as the system library etc won't be object oriented. This leads to a much more clumsy API. - Introducing references into a language that basically only support concrete items (as in the transition from perl 4 to perl 5) leads to Evil. A lot of extra syntax etc will be needed to support it, and this leads to chaos. - Real structures should be easier to create than hashes, or people will push around structures where a simple typo results in a bug, not a direct error message. - Classes does not look like classes - the indentation is wrong, etc. - The only way to create a class without breaking the current context is to use "eval { package ...; }". This looks extremely clumsy, and blocks errors from the class definition. - "package" change the settings of the various flags (e.g. "use strict"), meaning that an object introduction HAS SIGNIFICANT OTHER SIDE EFFECTS. - The ad-hoc added exceptions do not work well at all - The standard library does not use exceptions - The backtraces printed by confess are horrible - Perl lead to hashes, hashes lead to hate, hate leads to suffering - 13:33 < vruz> 1) I'm not moving to perl even if they eventually come up with something fast and well designed 13:33 < vruz> 2) the perl community will still be what it is 13:34 < vruz> 3) ruby is on its way to reach better levels of performance, and even better language expresiveness - undef++ and undef .= "stuff" DOES NOT GIVE AN ERROR - Warnings and errors do not generate backtraces by default. This is BAD. EXTEMELY bad for taints. - There is no way to get taint status (and other data) without using e.g. Devel::Peek. Not part of standard library. - The UNIVERSAL::isa hack isn't always used - people tend to go for ref() because that is more easily available. - The taint checks seems to possibly sometimes be wrong (but that may be an error in the code base I'm working on. The lack of easy testing for taints makes it hard to do more than inspection presently...) - Mix up between package names, class names, and class objects. These almost always work side by side except they don't - and "bless into reference" is a nasty problem when it occur. The issues lead to bad design when somebody that do not know objects REALLY WELL use the system. - It is decidedly non-trivial to check if two values are the same. Watch: sub _are_a_and_b_equal($$) { my ($a, $b) = @_ if (!defined($a)) { return !defined($b); } if (!defined($b)) { return 0; } if (ref($a)) { if (ref($a) ne ref($b)) { return 0; } # Here, we should do a deep compare. However, for the sake of # simplicity, we'll just define that references cannot be compared for # equality, and use undef for that case. A scalar and a reference # really needs to be different, of course. return undef; } if (ref($b)) { return 0; } my ($tmp_a, $tmp_b) = ($a, $b); if ($tmp_a != $tmp_b) { return 0; } if ($a ne $b) { return 0; } return 1; } Note that the use of undef is a cop-out - it really should be a deep compare. Instead, we just define that references can't be compared and are always different. The use of temps is because we do not want to modify the passed-in scalars. If we did a direct comparison on them, they would be cast to numbers. I'm not entirely sure if check for numeric difference is necessary - I think the string compare may be a strict superset of the numeric compare *but I am not sure*, even after having worked five years with Perl. - There is no simple way to generate a hash (value) from a hash (dictionary). From slashdot: Take for instance my favourite hate-object: Autovivification. Perl fills in whatever you use as a hash reference to be a hash reference, so you don't have to do it yourself. Great for small, short programs where you are bulding data structures. A liability for large programs, where the problems with this (e.g, $stuff = undef; if (exists($stuff->{foo})) makes $stuff == {} - an empty hashref) makes debugging the programs harder.

Or the automatic conversion of numbers to and from strings, requiring that there are different operators for comparing strings (eq, ne, cmp) and numbers (=, !=, <=>). This is great for small, simple programs - removing the need for writing explict conversions is a boon, and automatically being able to mix data coming from a text file and a database is great. However, it gets in the way of writing generic code, and lead to small inconsistencies when one tries to work around it. As an example: Yesterday I had to write code that work with IDs in a sorted order, and had to use regexp checks to find out if it is to do numeric or string compares. That still won't be be stable for sets that mix integers and strings - fortunately, I could just disallow that for the time being. 14:11 < eek> lypanov: exceptions in perl are constructed over eval/die 14:12 < lypanov> eek: right but don't the abstractions work slightly better than direct usage? 14:12 -!- randrew [~raj@dolmen.cc.columbia.edu] has joined #ruby-lang 14:12 < eek> lypanov: which means they interfere a bunch with other stuff that also use eval/die - e.g, the exit methods in mod_perl 14:12 < eek> lypanov: sort of. 14:12 < eek> lypanov: except when they fail horribly. 14:13 * StelK stacca 14:13 < eek> lypanov: which they can do e.g. if you miss a semicolon at the end of a catch {}; block, in which case it will usually eat the next statement, give no error, and just plain not work. 14:13 < eek> lypanov: (that's from the standard Error class) 14:13 < eek> "standard" 14:15 < eek> dr_bob: yeah, and all the $this->XYZ pairs, and the lack of #-of-arguments checking, and the idea that you probably want to interpolate a textual representation of the address of a hash table in memory into your SQL query. that was certainly your intent. no way this could have been an error on your part. 14:15 < eek> and auto-vivification is SOOO nice. (well, it is. for one-liners. ONLY.) 14:16 < eek> (for readers that don't know: auto-vivification is when perl make up an empty hash for you if you have a typo.) my @array = [@{$this->GetAnotherArray()}]; Do you think this gives an array initialization? An error? Think again. It gives an array containing a single array ref. anybody that hear claims that "Perl is better than Ruby because of CPAN": debunk them. say that Ruby is better than perl because RAA *doesn't* mirror unmaintained and broken packages and make them available for eternity, because even the core perl packages are broken. (so far, we've had prError.pm, Locale, Test::Unit,