When Context Gets Complicated (and why it's not a problem)

| 2 Comments

In Essential Skills for Perl 5 Programmers I mentioned that no one can be an adept Perl programmer without understanding context. This trips up many, many people -- and you often hear (unfair) criticisms of Perl 5 based on misunderstandings and guesses about how context works.

Context is reasonably easy to explain. (The previous sentence is grammatically correct.) Contexts is not difficult to understands. (The previous sentence is grammatically incorrect, even if you speak the Queen's English.)

If you can find the errors in the previous paragraph, you can understand quantity context in Perl 5: like subject-verb agreement in terms of number, expressions in Perl 5 can behave differently in contexts that imply zero, one, or more results.

fetch_something_awesome();              # void   context
my $item  = fetch_something_awesome();  # scalar context
my @items = fetch_something_awesome();  # list   context

Context gets a little bit trickier when you need to coerce what would normally be one context into another:

my ($item) =        fetch_something_awesome(); # list   context
push @items, scalar fetch_something_awesome(); # scalar context

If you know the visual cues (if you don't randomly sprinkle punctuation about your program until it works), those are easy to understand as well.

The subtlety comes when dealing with complex contexts, usually with nested expressions:

# list context, thanks to say
say reverse $name;

my %values =
(
    # list context, thanks to hash assignment
    name => get_name(),
    rank => get_rank(),
);

# list context (param flattening)
$screen->flip( $fleet->get_spaceships() );

This is often where more fair criticisms of Perl 5 suggest that context may not be worth it, because you have to understand what a line of code means and what it implies to read it correctly.

There's a fair point there, but it's also silly in some ways. Skimming code which calls other functions may give you some idea of what those functions do, but you rely only on the names of those functions and not their documentation to tell you any other details. Do they modify global or thread-local variables? Do they have caching or performance characteristics? Do they block? Do they require special initialization or error handling? Do they return special values?

The valid point is that chaining multiple expressions into complex compound expressions can have interesting effects. (I see this in Haskell code often; invisible partial application means that I personally can't skim Haskell code without tracking down the arity of functions to figure out what happens where.)

That's no argument against language features. It's an argument against making expressions more complex than necessary. Note that the same argument applies against complex prefix-unless expressions. unless can be amazingly useful when used properly. If you abuse it, you make amazing problems. Don't make problems.

2 Comments

In most cases, I intend to avoid to use 'context', simply because it makes me feel that I would make mistakes. Although in most cases, I don't.

A comment on Reddit about pre-++ vs post-++ reminded me of this page. Specifically: If anybody says C doesn't have context, remind them of ++ and *, which do different things in different places. And of course there's always operator overloading in C++.

On the other hand, I don't know if anybody *actually* says "C doesn't have context and Perl does, ergo C is better", so it's probably just a straw man. :) But I thought I'd mention it, nevertheless.

Modern Perl: The Book

cover image for Modern Perl: the book

The best Perl Programmers read Modern Perl: The Book.

sponsored by the How to Make a Smoothie guide

Categories

Pages

About this Entry

This page contains a single entry by chromatic published on February 1, 2010 3:39 PM.

Subtle Encouragement Toward Correctness was the previous entry in this blog.

A Perl Programming Maintenance Checklist is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.


Powered by the Perl programming language

what is programming?