Skip to content

Commit

Permalink
Revised chapter 1 for 2013/2014 edition.
Browse files Browse the repository at this point in the history
  • Loading branch information
chromatic committed Jul 28, 2013
1 parent e25ebfe commit bd6996d
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 105 deletions.
79 changes: 42 additions & 37 deletions sections/context_philosophy.pod
Expand Up @@ -9,25 +9,26 @@ it; the local I<context> helps clarify the intent. For example, the
inappropriate pluralization of "Please give me one hamburgers!"N<The
pluralization of the noun differs from the amount.> sounds wrong, just as the
incorrect gender of "la gato"N<The article is feminine, but the noun is
masculine.> makes native speakers chuckle. Consider also the pronoun "you" or
the noun "sheep" which can be singular or plural depending on context.
masculine.> makes native speakers chuckle. Other words do double duty; one
sheep is a sheep just as two sheep are also sheep.

Context in Perl is similar. It governs the amount as well as the kind of data
to use. Perl will happily attempt to provide exactly what you ask for--provided
you do so by choosing the appropriate context.
Context in Perl is similar. It describes the I<amount> as well as the I<kind>
of data to use. Perl will do the what you mean to do to data if you choose the
appropriate context for that data.

Certain Perl operations produce different behaviors when you want zero, one, or
many results. A specific construct in Perl may do something different if you
write "Do this, but I don't care about any results" compared to "Do this, and I
expect multiple results." Other operations allow you to specify whether you
expect to work with numeric data, textual data, or true or false data.
For example, several Perl operations produce different behaviors when you
expect zero, one, or many results. A specific construct in Perl may do
something different if you write "Do this, but I don't care about any results"
compared to "Do this and give me multiple results." Other operations allow you
to specify whether you expect to work with numeric data, textual data, or true
or false data.

Context can be tricky if you try to write or read Perl code as a series of
single expressions extracted from their environments. You may find yourself
slapping your forehead after a long debugging session when you discover that
your assumptions about context were incorrect. If instead you're cognizant of
context, your code will be more correct--and cleaner, flexible, and more
concise.
single steps in isolation. That's not how Perl works! Every expression is part
of a larger context. You may find yourself slapping your forehead after a long
debugging session when you discover that your assumptions about context were
incorrect. If instead you're cognizant of context, your code will be more
correct--and cleaner, flexible, and more concise.

=head2 Void, Scalar, and List Context

Expand All @@ -40,21 +41,22 @@ I<Amount context> context governs I<how many> items you expect from an
operation. The English language's subject-verb number agreement is a close
parallel. Even without knowing the formal description of this linguistic
principle, you probably understand the error in the sentence "Perl are a fun
language". In Perl, the number of items you request determines how many you
get.
language"N<In terms of amount context, you could say that the verb "are"
expects multiple nouns.>. In Perl, the number of items you request determines
how many you get.

X<void context>
X<context; void>

Suppose you have a function (L<functions>) called C<find_chores()> which sorts
your household todo list in order of task priority. The means by which you call
this function determines what it will produce. You may have no time to do
chores, in which case calling the function is an attempt to look industrious.
You may have enough time to do one task, or you could have a burst of energy on
a free weekend and desire to accomplish as much as possible.
your household todo list in order of task priority. The number of chores you
expect to read from your list determines what exactly the function will do. If
you expect nothing, you're just pretending to be busy. If you expect one task,
you have something to do for the next fifteen minutes. If you have a burst of
energy on a free weekend, you could get all of the chores.

If you call the function on its own and never use its return value, you've
called the function in I<void context>:
When you call a function on its own and never use its return value, you've used
I<void context>:

=begin programlisting

Expand All @@ -65,8 +67,8 @@ called the function in I<void context>:
X<context; scalar>
X<scalar context>

Assigning the function's return value to a single item (L<scalars>) evaluates
the function in I<scalar context>:
Assigning the function's return value to a single item (L<scalars>) enforces
I<scalar context>:

=begin programlisting

Expand All @@ -84,13 +86,16 @@ list, or using it in a list, evaluates the function in I<list context>:

my @all_results = find_chores();
my ($single_element, @rest) = find_chores();

# list of results passed to a function
process_list_of_results( find_chores() );

=end programlisting

The parentheses in the second line of the previous example group the two
variable declarations (L<lexical_scope>) so that assignment will behave as you
expect. If C<@rest> were to go unused, you could also correctly write:
variable declarations (L<lexical_scope>) into a single unit so that assignment
assigns to both of the variables. Note that a single-item list is still a list,
however. You could also correctly write:

=begin programlisting

Expand Down Expand Up @@ -155,11 +160,11 @@ X<value context>
X<context; value>

Perl's other context--I<value context>--governs how Perl interprets a piece of
data. You've probably already noticed that Perl's flexible about figuring out
if you have a number or a string and converting between the two as you want
them. In exchange for not having to declare (or at least track) explicitly what
I<type> of data a variable contains or a function produces, Perl's type
contexts provide hints that tell the compiler how to treat data.
data. You've probably already noticed that Perl can figure out if you have a
number or a string and convert data between the two forms. In exchange for not
having to declare (or at least track) explicitly what I<type> of data a
variable contains or a function produces, Perl's value contexts provide hints
about how to treat that data.

X<builtins; C<eq>>

Expand Down Expand Up @@ -190,8 +195,8 @@ X<context; numeric>

X<builtins; C<==>>

The C<eq> operator treats its operands as strings by enforcing I<string
context> on them. The C<==> operator imposes I<numeric context>. In numeric
Where the C<eq> operator treats its operands as strings by enforcing I<string
context> on them, the C<==> operator imposes I<numeric context>. In numeric
context, both strings evaluate to C<0> (L<numeric_coercion>). Be sure to use
the proper operator for the type of context you want.

Expand All @@ -207,7 +212,7 @@ X<context; explicit>
In rare circumstances, you may need to force an explicit context where no
appropriately typed operator exists. To force a numeric context, add zero to a
variable. To force a string context, concatenate a variable with the empty
string. To force a boolean context, double the negation operator:
string. To force a boolean context, double up the negation operator:

=begin programlisting

Expand All @@ -217,6 +222,6 @@ string. To force a boolean context, double the negation operator:

=end programlisting

Type contexts are easier to identify than amount contexts. Once you know which
Value contexts are easier to identify than amount contexts. Once you know which
operators provide which contexts (L<operator_types>), you'll rarely make
mistakes.
79 changes: 41 additions & 38 deletions sections/expressivity.pod
Expand Up @@ -5,16 +5,16 @@ Z<expressivity>
X<Wall, Larry>
X<Larry Wall>

Larry Wall's studies of linguistics and human languages influenced the
design of Perl. The language allows you tremendous freedom to solve your
problems, depending on your group style, the available time, the expected
lifespan of the program, or even how creative you feel. You may write simple,
straightforward code or integrate into larger, well-defined programs. You may
select from multiple design paradigms, and you may eschew or embrace advanced
features.
Larry Wall studied of linguistics and human languages. Then he designed Perl.
Unlike other languages designed around a mathematical notion, Perl takes into
account how people communicate. In return, you get the freedom to decide how to
arrange your programs to meet your needs. You may write simple, straightforward
code or combine many small pieces into larger programs. You may select from
multiple design paradigms, and you may eschew or embrace advanced features.

Where other languages enforce one best way to write any code, Perl allows
I<you> to decide what's most readable or useful or fun.
Where other languages claim that there should be only one best way to solve any
problem, Perl allows I<you> to decide what's most readable, most useful, most
appealing, or most fun.

X<TIMTOWTDI>
X<Tim Toady>
Expand All @@ -23,19 +23,20 @@ Perl hackers have a slogan for this: I<TIMTOWTDI>, pronounced "Tim Toady", or
"There's more than one way to do it!"

Though this expressivity allows master craftworkers to create amazing programs,
it allows the unwise or uncautious to make messes. Experience and good taste
will guide you to write great code. The choice is yours--but be mindful of
readability and maintainability, especially for those who come after you.

Perl novices often may find certain constructs opaque. Many of these idioms
(L<idioms>) offer great (if subtle) power. It's okay to avoid them until you're
comfortable with them.
it also allows the unwary to make messes. Experience and good taste will guide
you as you design your code, but the choice is always yours. Express yourself,
but but be mindful of readability and maintainability, especially for those who
come after you.

Learning Perl is like learning a new spoken language. You'll learn a few words,
string together sentences, and soon will enjoy simple conversations. Mastery
comes with practice of reading and writing. You don't have to understand every
detail of Perl to be productive, but the principles in this chapter are vital
to your growth as a programmer.
then string together sentences, and then enjoy simple conversations. Mastery
comes from practice of both reading and writing code. You don't have to
understand every detail of Perl to be productive, but the principles in this
chapter are vital to your growth as a programmer.

Perl novices often find certain syntactic constructs opaque. These idioms
(L<idioms>) offer great (if subtle) power in the hands of experienced
programmers, but it's okay to avoid them until you're comfortable with them.

As another design goal, Perl tries to avoid surprising experienced (Perl)
programmers. For example, adding two variables (C<$first_num + $second_num>)
Expand All @@ -48,21 +49,23 @@ numbers by using a numeric operator. Perl happily does so.
X<DWIM>
X<principle of least astonishment>

Perl adepts often call this principle I<DWIM>, or I<do what I mean>. Another
phrasing is that Perl follows the I<principle of least astonishment>. Given a
cursory understanding of Perl (especially context; L<context_philosophy>), it
should be possible to understand the intent of an unfamiliar Perl expression.
You will develop this skill.
Perl adepts often call this principle I<DWIM>, or I<do what I mean>. You could
just as well say that Perl follows the I<principle of least astonishment>.
Given a cursory understanding of Perl (especially context;
L<context_philosophy>), it should be possible to understand the intent of an
unfamiliar Perl expression. You will develop this skill as you learn Perl.

X<baby Perl>

Perl's expressivity also allows novices to write useful programs without having
to understand everything. The resulting code is often called I<baby Perl>, in
the sense that most everyone wants to help babies learn to communicate well.
Everyone begins as a novice. Through practice and learning from more experienced
Perl's expressivity allows novices to write useful programs without having to
understand the entire language. This is by design! Experienced developers often
call the results I<baby Perl>. This is a term of endearment, because everyone
begins as a novice. Through practice and learning from more experienced
programmers, you will understand and adopt more powerful idioms and techniques.
It's okay for you to write simple code that you understand. Keep practicing and
you'll become a native speaker.

For example, an experienced Perl hacker might triple a list of numbers with:
An experienced Perl hacker might triple a list of numbers with:

=begin programlisting

Expand Down Expand Up @@ -96,12 +99,12 @@ For example, an experienced Perl hacker might triple a list of numbers with:

=end programlisting

All three approaches accomplish the same thing, but each uses Perl in a
different way.
Every program does the same thing, but each uses Perl in a different way.

Experience writing Perl will help you to focus on I<what> you want to do rather
than I<how> to do it. Even so, Perl will happily run simple programs. You can
design and refine your programs for clarity, expressivity, reuse, and
maintainability, in part or in whole. Take advantage of this flexibility and
pragmatism: it's far better to accomplish your task effectively now than to
write a conceptually pure and beautiful program next year.
As you get more comfortable with Perl, you can let the language do more for
you. With experience, you can focus on I<what> you want to do rather than
I<how> to do it. Even so, Perl will happily run baby Perl just as well as
expert Perl. You can design and refine your programs for clarity, expressivity,
reuse, and maintainability, in part or in whole. Take advantage of this
flexibility and pragmatism: it's far better to accomplish your task effectively
now than to write a conceptually pure and beautiful program next year.
2 changes: 1 addition & 1 deletion sections/idioms.pod
Expand Up @@ -316,7 +316,7 @@ pragmas you need:

...

B<exit main( @ARGS );>
B<exit main( @ARGV );>

=end programlisting

Expand Down
35 changes: 18 additions & 17 deletions sections/implicit_ideas.pod
Expand Up @@ -2,10 +2,9 @@

Z<implicit_ideas>

Context is only one linguistic shortcut in Perl. Programmers who understand
these shortcuts can glance at code and instantly understand its most important
characteristics. Another important linguistic feature is the Perl equivalent of
pronouns.
Programmers who understand Perl's linguistic shortcuts can glance at code and
instantly understand its most important characteristics. Besides context, Perl
has default variables--the programming equivalent of pronouns.

=head2 The Default Scalar Variable

Expand Down Expand Up @@ -46,7 +45,7 @@ precise details of its behavior.>:
C<$_> has the same function in Perl as the pronoun I<it> in English. Without an
explicit variable, C<chomp> removes the trailing newline sequence from C<$_>.
Perl understands what you mean when you say "C<chomp>"; Perl will always chomp
I<it>, so these two lines of code are equivalent:
I<it>. These two lines of code are equivalent:

=begin programlisting

Expand Down Expand Up @@ -139,11 +138,12 @@ X<builtins; C<grep>>

=end programlisting

As English gets confusing when you have too many pronouns and antecedents, you
must take care mixing uses of C<$_> implicitly or explicitly. Uncautious
simultaneous use of C<$_> may lead to one piece of code silently overwriting
the value written by another. If you write a function which uses C<$_>, you
may clobber a caller function's use of C<$_>.
As English gets confusing when you have too many pronouns and antecedents, so
does Perl when you mix explicit and implicit uses of C<$_>. If you use it in
multiple places, one piece of code may silently override the value expected by
another piece of code. For example, if one function uses C<$_> and you call it
from another function which uses C<$_>, the callee may clobber the caller's
value.

As of Perl 5.10, you may declare C<$_> as a lexical variable (L<lexical_scope>)
to prevent this clobbering behavior:
Expand Down Expand Up @@ -175,7 +175,7 @@ clobbering an existing instance of C<$_>:

=end programlisting

Of course, using a named lexical can be just as clear:
Of course, using a named lexical may be even clearer:

=begin programlisting

Expand Down Expand Up @@ -210,7 +210,7 @@ X<C<@_>>

Perl also provides two implicit array variables. Perl passes arguments to
functions (L<functions>) in an array named C<@_>. Array manipulation operations
(L<arrays>) inside functions affect this array by default, so these two
(L<arrays>) inside functions operate on this array by default. These two
snippets of code are equivalent:

=begin programlisting
Expand All @@ -235,7 +235,7 @@ X<builtins; C<pop>>
Just as C<$_> corresponds to the pronoun I<it>, C<@_> corresponds to the
pronouns I<they> and I<them>. I<Unlike> C<$_>, Perl automatically localizes
C<@_> for you when you call other functions. The builtins C<shift> and C<pop>
operate on C<@_> with no other operands provided.
operate on C<@_>, if provided no explicit operands.

X<default variables; C<@ARGV>>
X<variables; C<@ARGV>>
Expand All @@ -255,8 +255,8 @@ Perl's C<< <$fh> >> operator is the same as the C<readline> builtin.
C<readline $fh> does the same thing as C<< <$fh> >>. As of Perl 5.10, a bare
C<readline> behaves just like C<< <> >>, so you can now use C<readline>
everywhere. For historic reasons, C<< <> >> is still more common, but consider
using C<readline> as a more readable alternative. You probably prefer C<glob
'*.html'> to C<< <*.html> >>, right? It's the same idea.
using C<readline> as a more readable alternative. (What's more readable, C<glob
'*.html'> to C<< <*.html> >>? The same idea applies.)

=end tip

Expand All @@ -265,7 +265,7 @@ X<null filehandle>
C<ARGV> has one special case. If you read from the null filehandle C<< <> >>,
Perl will treat every element in C<@ARGV> as the I<name> of a file to open for
reading. (If C<@ARGV> is empty, Perl will read from standard input.) This
implicit C<@ARGV> behavior is useful for writing short programs, such as this
implicit C<@ARGV> behavior is useful for writing short programs, such as a
command-line filter which reverses its input:

=begin programlisting
Expand Down Expand Up @@ -294,4 +294,5 @@ If you run it with a list of files:

... the result will be one long stream of output. Without any arguments, you
can provide your own standard input by piping in from another program or typing
directly. Yet Perl is good for far more than small command-line programs....
directly. That's a lot of flexibility in a small program, but Perl's only
getting started.

0 comments on commit bd6996d

Please sign in to comment.