News for hackers. Stuff that matters.
Re: How I learnt to love Perl by mechanical_fish on Sunday December 07, 2008 @01:35PM (#389003)
It's not that Perl examples are unusually bad. It's that Perl's syntax is bad. Really bad. Especially for newbs.

Declaring a function in PHP which accepts a scalar, an array and a hash:

   function foo($bar, $baz, $quux = array('quux' => "default")) {
Declaring the same function in Perl:

   sub foo {
     my ($bar, @baz, %quux) = @_;
  
Which is already terrible. Worse, despite being relatively intuitive (I've made the mistake of writing this more than once, whenever I forget too much about Perl) it's completely broken. In the words of the Camel book:

If you want to pass more than one array or hash into or out of a function and have them maintain their integrity, then you're going to want to use an explicit pass-by-reference. Before you do that, you need to understand references as detailed in Chapter 4. This section may not make much sense to you otherwise. But hey, you can always look at the pictures.

Here we see that Perl's syntax isn't just very ugly: It's hopelessly entangled with relatively-advanced concepts like references, and dereferencing, and pass-by-value vs pass-by-reference, and wacky only-in-Perl nonsense like "array context" vs "scalar context".

Even PHP can do arguments right. Meanwhile, Perl doesn't even apologize for being a language where you have to learn about pointers before you can walk.

Re: How I learnt to love Perl by DavidMcLaughlin on Sunday December 07, 2008 @02:47PM (#389047)
When you're passing parameters to a subroutine in Perl, all you're doing is passing a list. Not an array, but a list. The foo subroutine you posted, just wouldn't be written in Perl.

Besides, have you seen the syntax for passing arrays in PHP? Zend Framework is fugly:

    protected static function _assembleRoutes()
    {
        $routes = array();
        $routes['entry']  = new Zend_Controller_Router_Route_Regex(
            "[0-9a-z._!;, \=\-%]+-(\d+)",
            array(
                'module' => 'default',
                'controller' => 'entry',
                'action'     => 'view'
            ),
            array(
                'id' => 1
            )
        );
        return $routes;
    }
10 lines to create an object = foo($bar);
Re: How I learnt to love Perl by mechanical_fish on Sunday December 07, 2008 @03:56PM (#389109)
The foo subroutine you posted, just wouldn't be written in Perl.

I think I said that, didn't I? What I wrote is wrong, absolutely. I believe the correct thing to do is to either learn all about Perl references and dereferencing syntax so that you can pass lists of references to your Perl subroutines... or to switch to a different language. The history of PHP tends to suggest that most people pick Option Two.

PHP is a bad language filled with poor design choices. It is worse than Perl on every level except readability and learnability. Unfortunately, readability and learnability turn out to be very, very important. That's my only explanation for why PHP has crushed Perl in the web-language marketplace. (It's not as if Perl didn't have a big head start.)

I find myself working as a professional PHP programmer. But I, too, cannot find it in myself to love the example that you have posted. To pick on just one aspect: I am sick and tired of typing array() all the time. When PHP was mining Perl for ideas, couldn't they have chosen [] or {}?

And, yet, though I don't like the fact that your PHP example is 10 lines long and full of cruft, at least I can read it. I understand it. It is built out of very simple pieces, not the least of which is that damned array() syntax, which is used everywhere and which every PHP programmer learns to understand right away.

Let me ramble on about array() for a bit, because I often ponder it, as one might ponder Picasso's Guernica. The designers of PHP seem to have been so dead-set on making its datatypes simple (at least until they made two separate attempts to bolt on Java's ugly-ass class system, but don't get me started on that...) that (except for classes) PHP only has one non-scalar data structure, array(), which serves as both a hash and an array. This is an astounding design decision. On the one hand, PHP arrays are the centerpiece of my dislike for the language, because their semantics are just crazy. I complain about Perl's semantics, but PHP is unreal: Calling the wrong function on an array will transform all its string keys into arbitrary integers, or renumber your integer keys without telling you. You have to learn two ways to concatenate arrays: The one that turns all your keys into integers (discarding their original contents), and the one that doesn't. Or, consider: Until you explicitly sort it, a hash has an implicit sort order that is independent of the keys or values in the hash, but depends only on the order in which the elements were originally inserted. It's very quirky.

And, yet, I have to ask myself: Perhaps this only seems nuts to me because I learned Perl first. Perhaps newbies love the PHP array(), because when they see a variable they know that it is either a scalar or an array -- and, if it is an array, they know what to do with it! They don't have to worry about the distinction between an array and a hash. They don't have to worry about accidentally passing a hash to something that wants an array. The foreach() syntax is always the same. You see, the array may be a crappy data structure, but it is our crappy data structure, and OMG Alan Perlis was right even about PHP:

It is better to have 100 functions operate on one data structure than 10 functions on 10 data structures. -- Alan Perlis

Is this insane? Yes. But there has to be some reason why PHP is such a success.

Re: How I learnt to love Perl by DavidMcLaughlin on Sunday December 07, 2008 @04:26PM (#389123)
We're getting down to personal choices here. What you think is readable depends on how well you understand the language. Some people don't like sigils, which Perl uses in abundance.

Taking a look at your PHP example, you have:

function foo($bar, $baz, $quux = array('quux' => "default")) {

What is $baz supposed to be here? I have no way of knowing that it's supposed to be a scalar, array or associative array.

The strength of sigils for readability is revealed in the equivalent Perl code:

my ($bar, @baz, %quux) = @_;

Here I know instantly, without reading any further documentation, that this subroutine expects a scalar (which in OOP would be the current object instance), an array and then a hash. It took a while, but I find this readable.

What PHP has over Perl, and indeed every other language right now is lowest-barrier-to-entry for web development. Out of all the other languages, it's the only one designed for the web.

On top of that, developing Perl ,Python or Ruby on a Windows machine is NOT fun and it's not easy. You want to play with PHP? Wampserver or Xampp can get you up and running on XP and Vista in seconds. Even if you manage to set up a Perl environment, you've still got CGI and DBI to install before it matches what PHP does out the box. Already I've installed Strawberry Perl, Apache, mod_perl and standard CPAN modules and all I wanted to do is a simple contact me form on my website!

That's why PHP is such a success.

Re: How I learnt to love Perl by mechanical_fish on Monday December 08, 2008 @01:09AM (#389557)
I agree that sigils are quite nice for readability. But haven't we established that this:

  my ($bar, @baz, %quux) = @_;
while nice and readable, also isn't valid Perl? Because you have to pass references to get both an array and a hash into a Perl subroutine. So doesn't the actual Perl code look something like this? [1]

  my ($bar, $baz, $quux) = @_;
...and then, in the function, you have to remember to say @$baz because $baz is an array reference and %$quux because $quux is a hash reference? And then we have much the same readability problem as PHP, don't we? Except that the PHP programmer has to make fewer guesses, because the language has one fewer fundamental datatype. ;)

(I believe, in my own Perl, I used to work around this issue by using a lot of objects to encapsulate my hashes and arrays.)

Correct me if I'm wrong. I was never the world's most expert Perl programmer, I haven't used the language in several years, and Perl may have improved since I left.

---

[1] Not that there isn't more than one way to do it.

Re: How I learnt to love Perl by thwarted on Monday December 08, 2008 @03:39AM (#389666)
This is somewhat of a contrived example. I can't think of any subroutine in perl that I've written, or interfaced with, or seen in production code, that takes multiple types beyond the first argument. If any function is doing that, the function is too complex and should be refactored. What you do see a lot of is stuff of the forms:

   sub foo {
      my($someflag, @subjects) = @_

   sub foo {
      my($self, %options) = @_

   sub foo {
      my($positional, %named) = @_
etc. And in fact, when the way you call these is the 90% case for functions, at least in perl.

   sub dosomething_with_data(@) { ... }
   @data = (1, 2, 3);
   @moredata = (4, 5, 6);
   dosomething_with_data(@data, @moredata);

   sub invoke(%) { ... }
   %common_opts = (a=>1, b=>2);
   invoke(%common_opts, c=>3);
   invoke(%common_opts, c=>6, d=>5);
   %overrides = (b=>3);
   invoke(%common_opts, %overrides, c=>6);
(I included the subroutine prototypes for clarity). In this case, perl is exactly DYIM without the programmer having to think about list folding, array splicing, or hash merging. It just works. This would appear to be true dynamic typing, rather than dynamic typing where I still need to be strict about how I handle the values.
Re: How I learnt to love Perl by thwarted on Sunday December 07, 2008 @03:37PM (#389098)
I'm not sure that example, which doesn't do what it looks like it might do, supports your argument. Because

   sub foo {
     my($bar, @baz, %quux) = @_
Is just another way to declare your types:

   void foo(int bar, void *baz[], hash_t quux) { ...
Or in your untyped, dynamic language du jour with my bastardized Hungarian Notation:

   sub foo(Ibar, Abaz, Hquux) ...
However, as you point out, that syntax doesn't work because non-scalars need to be passed as references. Most non-scalar types need to be passed as references in C also (I can't remember which C standard let structs be passed as value), which is perl's heritage.
Re: How I learnt to love Perl by mechanical_fish on Sunday December 07, 2008 @04:19PM (#389117)
Yes, if you want to write C this sort of thing is the least of your problems. Perl is certainly simpler and easier to learn than C. I'd also agree that Perl's declaration syntax is simpler than Java's, but what isn't simpler than Java's type system at this point? ;)

The simple syntax works in multiple Perl alternatives: PHP and Ruby are the ones I know about. Both languages have intelligent defaults to eliminate the need, in many cases, for newbs to think hard about what they're doing. (By default, PHP passes an array of arguments, by value -- with hidden optimizations to avoid the overhead of excess copying. The PHP argument array may include entire arrays as arguments. Meanwhile, in Ruby everything is an object, so Ruby passes an array of object references.) These are the languages which constitute Perl's competition, today. (Along with Python, of course, which I am unfairly leaving out of my argument because but I don't know how Python handles arguments! But I'm sure the answer is "with reasonable intelligence".)

Re: How I learnt to love Perl by nostrademons on Sunday December 07, 2008 @08:07PM (#389325)
"but what isn't simpler than Java's type system at this point?"

Haskell's type system. ;-)

Re: How I learnt to love Perl by gaius on Sunday December 07, 2008 @04:10PM (#389114)
Hence the saying only Perl can parse Perl. Which is fine for 100-line scripts but for 50,000 line projects written by many people over many years (these exist!) it means you get basically zero tool support. Both Python and Tcl scale much more cleanly from small one-off scripts to larger applications (as well as any weakly dynamically typed language can, anyway).
Re: How I learnt to love Perl by SwellJoe on Sunday December 07, 2008 @06:43PM (#389273)
Our projects total about 450,000 lines of Perl code. I've worked on one large Python project (SciPy), and found it similarly comfortable. I didn't feel major pains going either direction (from Perl to Python or back to Perl again).

I also spent some time with a large Tcl project (OpenACS) and found it very painful. But, I've never learned Tcl with as much enthusiasm as I learned Perl or Python, so I might be wrong. Actually maybe it's just CMS that really suck. I hated spelunking in Zope, and I hate working with Joomla (for different, but no less strongly held, reasons).

Re: How I learnt to love Perl by chorny on Sunday December 14, 2008 @03:38PM (#397624)
You can parse Perl with PPI (look at your nearest CPAN mirror).