<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -1,20 +1,269 @@
 Z&lt;functions&gt;
 
+X&lt;function&gt;
+X&lt;subroutine&gt;
+
+A I&lt;function&gt; (or I&lt;subroutine&gt;, though less often) in Perl is a discrete,
+encapsulated unit of behavior.  It may or may not have a name.  It may or may
+not take parameters.  It may or may not return arguments.  It represents a type
+of control flow, where the execution of the program proceeds to another point
+in the source code.
+
+Functions are a prime mechanism for abstraction and encapsulation in Perl 5;
+many of the other mechanisms for abstraction, encapsulation, and re-use build
+on the concepts of the function.
+
+X&lt;subroutines; declaration&gt;
+
+Use the C&lt;sub&gt; keyword to declare a function:
+
+=begin programlisting
+
+    B&lt;sub&gt; greet_me  { ... }
+
+=end programlisting
+
+Now C&lt;greet_me()&gt; is available for invocation anywhere else within the
+program (with appropriate namespacing or exporting caveats).
+
+=begin notetip
+
+You do not have to declare Perl 5 functions before you use them, except in the
+special case where they modify I&lt;how&gt; the parser parses them.  See
+L&lt;attributes&gt;.
+
+=end notetip
+
+Invoking a subroutine is similar; mention its name and pass a list of
+arguments:
+
+=begin programlisting
+
+    greet_me( 'Jack', 'Brad' );
+    greet_me( 'Snowy' );
+    greet_me();
+
+=end programlisting
+
+=begin notetip
+
+You can I&lt;often&gt; omit parameter-grouping parentheses if your program runs
+correctly with the C&lt;strict&gt; pragma enabled, but they provide clarity to the
+parser and, more importantly, the reader -- so it's often wise to include them.
+
+=end notetip
+
+You can, of course, pass multiple I&lt;types&gt; of arguments to a function:
+
+=begin programlisting
+
+    greet_me( $name );
+    greet_me( @authors );
+    greet_me( %editors );
+
+=end programlisting
+
+... though see the L&lt;references&gt; section for more details.
+
 =for author
 
-declaration
+X&lt;parameters&gt;
+X&lt;functions; parameters&gt;
+X&lt;@_&gt;
+X&lt;parameter flattening&gt;
+
+Inside the subroutine, all parameters come in a single array, C&lt;@_&gt;.  If C&lt;$_&gt;
+corresponds to the English word I&lt;it&gt;, C&lt;@_&gt; corresponds to the word I&lt;them&gt;.
+Perl takes care of I&lt;flattening&gt; all incoming parameters into a single list for
+you, but the subroutine itself must unpack all parameters into any variables it
+wishes to use or operate on C&lt;@_&gt; directly:
+
+=begin programlisting
+
+    sub greet_one
+    {
+        B&lt;my ($name) = @_&gt;;
+        say &quot;Hello, $name!&quot;;
+    }
+
+    sub greet_all
+    {
+        say &quot;Hello, B&lt;$_!&quot; for @_&gt;;
+    }
+
+=end programlisting
+
+C&lt;@_&gt; behaves as does any other array in Perl.  You may refer to individual
+elements by index:
+
+=begin programlisting
+
+    sub greet_one_indexed
+    {
+        B&lt;my $name = $_[0]&gt;;
+        say &quot;Hello, $name!&quot;;
+
+        # or, less clear
+        say &quot;Hello, $_[0]!&quot;;
+    }
+
+=end programlisting
+
+You may also C&lt;shift&gt;, C&lt;unshift&gt;, C&lt;push&gt;, and C&lt;pop&gt; C&lt;@_&gt;; inside a
+function, these operators operate on C&lt;@_&gt; in the same way that they operate on
+C&lt;@ARGV&gt; outside of any function:
+
+=begin programlisting
+
+    sub greet_one_shift
+    {
+        B&lt;my $name = shift&gt;;
+        say &quot;Hello, $name!&quot;;
+    }
+
+=end programlisting
+
+=begin notetip
+
+It may seem clearer initially to write C&lt;shift @_&gt;, but the C&lt;shift&gt; assignment
+idiom is so pervasive in Perl 5 culture that it's important to learn the
+shorthand version anyway.
+
+=end notetip
+
+Do take care that assigning a scalar parameter from C&lt;@_&gt; requires C&lt;shift&gt;,
+indexed access to C&lt;@_&gt;, or lvalue list context parentheses.  Otherwise, Perl 5
+will happily evaluate C&lt;@_&gt; in scalar context for you and assign the number of
+parameters passed:
+
+=begin programlisting
+
+    sub bad_greet_one
+    {
+        B&lt;my $name = @_&gt;;  # buggy
+        say &quot;Hello, $name; you're looking quite numeric today!&quot;
+    }
+
+=end programlisting
+
+On the caller side, all arguments get flattened into a single list.  Thus
+passing a hash produces a list of key/value pairs:
+
+=begin programlisting
+
+    sub show_pets
+    {
+        my %pets = @_;
+        while (my ($name, $type) = each %pets)
+        {
+            say &quot;$name is a $type&quot;;
+        }
+    }
+
+    my %pet_names_and_types = (
+        Lucky   = &gt; 'dog',
+        Rodney  = &gt; 'dog',
+        Tuxedo  = &gt; 'cat',
+        Petunia = &gt; 'cat',
+    );
+
+    show_pets( %pet_names_and_types );
+
+=end programlisting
+
+The C&lt;show_pets()&gt; function works because the C&lt;%pet_names_and_types&gt; hash
+flattens into the list C&lt;'Lucky', 'dog', 'Rodney', 'dog', 'Tuxedo', 'cat',
+'Petunia', 'cat'&gt;.  The assignment within C&lt;show_pets()&gt; works effectively as
+the assignment to C&lt;%pet_names_and_types&gt; does.
+
+This is often useful, but there are limitations to understand.  If you wish to
+make a C&lt;show_pets_of_type()&gt; function, where one parameter is the I&lt;type&gt; of
+pet to display, you must pass that type as the I&lt;first&gt; parameter (or use
+C&lt;pop&gt; to remove it from the end of C&lt;@_&gt;):
+
+=begin programlisting
+
+    sub show_pets_by_type
+    {
+        B&lt;my ($type, %pets) = @_&gt;;
+
+        while (my ($name, $species) = each %pets)
+        {
+            B&lt;next unless $species eq $type;&gt;
+            say &quot;$name is a $species&quot;;
+        }
+    }
+
+    my %pet_names_and_types = (
+        Lucky   = &gt; 'dog',
+        Rodney  = &gt; 'dog',
+        Tuxedo  = &gt; 'cat',
+        Petunia = &gt; 'cat',
+    );
+
+    show_pets_by_type( 'dog',   %pet_names_and_types );
+    show_pets_by_type( 'cat',   %pet_names_and_types );
+    show_pets_by_type( 'moose', %pet_names_and_types );
+
+=end programlisting
+
+X&lt;parameter slurping&gt;
+
+As with any lvalue assignment to an aggregate, assigning to C&lt;%pets&gt; within the
+function I&lt;slurps&gt; all of the remaining values from C&lt;@_&gt;.  If the C&lt;$type&gt;
+parameter came at the end of C&lt;@_&gt;, Perl would attempt to assign an odd number
+of elements to the hash and would produce a warning.  You I&lt;could&gt; work around
+that:
+
+=begin programlisting
+
+    sub show_pets_by_type
+    {
+        B&lt;my $type = pop;&gt;
+        B&lt;my %pets = @_;&gt;
+
+        ...
+    }
+
+=end programlisting
+
+... but clarity might suffer.  The same principle applies when assigning to an
+array as a parameter, of course.  See L&lt;references&gt; for ways to avoid
+flattening and slurping when passing aggregate parameters.
+
+X&lt;parameter aliasing&gt;
+X&lt;functions; aliasing parameters&gt;
+
+One remanining feature of C&lt;@_&gt; can be surprising (though useful): it contains
+aliases to the passed-in parameters, at least until you unpack C&lt;@_&gt; into its
+own variables.  This behavior is easiest to demonstrate with an example:
+
+=begin programlisting
+
+    sub modify_name
+    {
+        $_[0] = reverse $_[0];
+    }
+
+    my $name = 'Orange';
+    modify_name( $name );
+    say $name;
+
+    # prints C&lt;egnarO&gt;
+
+=end programlisting
+
+If you modify an element of C&lt;@_&gt; directly, you modify the original parameter
+directly.  Be cautious with this.
+
+=begin notetip
+
+See the C&lt;signatures&gt;, C&lt;Method::Signatures&gt;, and C&lt;MooseX::Method::Signatures&gt;
+modules on the CPAN for declarative parameter handling.
 
-invocation
-    - passing parameters
-        - list context
-        - flattening
+=end notetip
 
 receiving arguments
-    - shift
-    - direct assignment
-    - aliasing
-    - slurpy array
-    - slurpy hash
     - Params::Validate
 
 namespacing
@@ -32,6 +281,7 @@ advanced:
     - lexicals
     - tail calls:
         - Sub::Tail::Call
+        - Sub::Tail::Recur
         - manual (blargh)
 
 avoid:</diff>
      <filename>sections/functions.pod</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>7f6a9b536bee96d71d39e5985bda5f7d46793801</id>
    </parent>
  </parents>
  <author>
    <name>chromatic</name>
    <email>chromatic@wgz.org</email>
  </author>
  <url>http://github.com/chromatic/modern_perl_book/commit/5b7b8e2f2ab36dec4cc499ce9f88dc3f4efcc1a8</url>
  <id>5b7b8e2f2ab36dec4cc499ce9f88dc3f4efcc1a8</id>
  <committed-date>2009-11-03T16:27:09-08:00</committed-date>
  <authored-date>2009-11-03T16:27:09-08:00</authored-date>
  <message>Started editing the functions/subroutines chapter.  Halfway through.</message>
  <tree>71b8f57d5fb97b7ad2593acf45ab966898f17cec</tree>
  <committer>
    <name>chromatic</name>
    <email>chromatic@wgz.org</email>
  </committer>
</commit>
