Why we teach the subroutine ampersand

In Learning Perl, we tell readers to use the & to prefix subroutine calls when we introduce the idea of reusable code. This doesn’t sit well with some programmers because it’s not how the experienced programmers work. The & does some magic, which we don’t mention in the book, and it’s a bit crufty for the Perl 5 programmer.

But newbies don’t work like experienced programmers. In general, newbies in anything don’t work like experienced practitioners. Trying to make them work the same way from Day One dumps too much information on them. It’s information overload and task loading. People will absorb only so much during an hour lecture or the first reading of a chapter (and we say as much in the preface where we explain we will lie a little). Learning Perl is decidedly not a reference; we give the reader enough information (and hide enough information) that they can pick up the essential and salient points.

I love sigils. They save me time because I don’t have to know the list of keywords and special names to choose a name for my variable. I remember my first day with Python. I tried to use a variable named count, but it conflicted with something I had loaded. It wasn’t the fault of the language; it was my knowledge of the language. It’s why Perl has sigils.

That applies to subroutines in Perl too. Randal likes to use the example of log, a natural name for a user-defined subroutine that outputs some debugging or progress information.

#!/usr/bin/perl

log( "Hey there!" );

sub log {
    print "[LOG] @_\n";
    }

This program has an odd error message:

Can't take log of 0 at test.pl line 3.

For the person in the middle of their first day of Perl, this doesn’t make sense. In my Learning Perl class, I don’t even talk about the log built-in. Math and science people figure it out quickly, but other people not so much.

There’s another beginner issue, though. We typically tell people to put subroutines at the end of the program. That means that the parser doesn’t see their definitions until after they are invoked. This doesn’t work but there’s no error message:

#!/usr/bin/perl

show_message;

sub show_message {
    print "Hello World\n";
    }

In that example, Perl doesn’t know what show_message is when it compiles that code. It hasn’t seen the subroutine definition yet. To get around that, we can prepend an & to let Perl know that it will get a definition eventually, and when it does to use that. We tell readers that the & gives the hint to the Perl parser.

#!/usr/bin/perl

&show_message;

sub show_message {
    print "Hello World\n";
    }

There are better ways to do this (I like show_message()), but I know from years of teaching that new people don’t quite understand argument lists, much less empty ones. Students frequently try to invoke the subroutine name without a hint. That’s the beauty of Learning Perl: it’s classroom tested with 20 years of direct student testing behind it.

We tell the beginner to use the & to invoke a subroutine until they get to know the Perl built-in names. That’s the important thing that people miss when they complain about our use of &: They ignore that we told them this is an expedient use to avoid a class of newbie problems. It’s one of the problems producing new Perl programmers: other programmers yell at them for not working like an experienced programmer.

This code, with the &, works as the first day programmer would program it:

#!/usr/bin/perl

&log( "Hey there!" );

sub log {
    print "[LOG] @_\n";
    }

There’s yet another reason that we teach the & sigil though. We’ll need it later in Intermediate Perl when we want to dereference a subroutine reference in the same way that we did for scalar, array, and hash references where we use the sigils in some cases. Most of our class focuses on consistency and elucidation of the patterns hidden in the syntax.

print $$scalar
keys %{ $hash }
foreach ( @$array )
defined &$code_ref;

Readers need to be aware of the & for Intermediate Perl and they need to be comfortable for it for Mastering Perl‘s subroutine jury-rigging. And there’s a progression there. Each book adds to the reader’s understanding as they spiral above a topic. You don’t learn a language once; you learn what you need and augment that. Sometimes you re-learn things, but only when you are ready for that. The process continues for your entire career.

There’s a third reason we do this, though. We aren’t only teaching people to write new code. We’re also teaching them to read old code. They are going to see that & in old code. They are certainly going to see it in Perl 4 code which requires the & (and Perl 4 code still out there). There’s quite a bit of legacy code out there and people are forced to work with it.

Some other things to read

Leave a comment

1 Comments.

  1. I agree with you. Beginners don’t need everything. All they want to grasp the concept well.

    In school days they taught us that an atom contain electrons, neutrons and protons. But in graduate phiysics course I came to know that it has other subatomic particles as well.

Leave a Reply

Your email address will not be published. Required fields are marked *