|Perl: the Markov chain saw|
Juerd's scratchpadby Juerd (Abbot)
|on Jun 01, 2004 at 17:07 UTC||Need Help??|
Perl 5 had void context, scalar context and list context. Perl 6 does too, but one name has slightly changed. Respectively, they are now void context, item context and list context1.
The word scalar is overloaded in Perl 5 and 6: it can be a named scalar variable, a reference to a scalar variable (written in allcaps: SCALAR), or an anonymous scalar variable. To make things worse, there are also scalar values, that are actually a scalar variables too. (Often, readonly scalars are not called variables, even though they are.)
Perl 6 also has Scalar, written with a single capital letter. This is the type that all scalars have. It is a supertype. For example, the Str (string) and Num (number) types are subtypes of Scalar.
Every type has a corresponding context, that depending on circumstances may cause type errors or type coercion (conversion). Having the same word for things that are all scalar variables is usually not a problem, but it would be very annoying to have both scalar context and Scalar context, so scalar context is now known as item context. This works until someone decides to write a class or role named Item, but let's assume that someone doing that is smart enough to include a namespace indicating what kind of item it is.
Lists can be lazy, which means that the values are generated on demand, but that is outside the scope of this article.
Item context has many sub contexts, most being a specific type of Ref (reference context), some being pure scalar types, like Num and Str. System native types (written in all lowercase) are left out of this discussion.
A list is not really a thing. It is a collection of elements. A list can only exist in list context, and each of the elements is then also in list context, flattening to one big list.
List context can be of a certain type. Then, every element is expected to be of that type, and if it is not, it is coerced into it, or an exception (error) occurs.
The new Array type is a subtype of Ref. Its context is called Array context. The same applies to Hash. However, Scalar, is not a subtype of Ref. It is the other way around: Ref is a subtype of Scalar. This means that a value in Scalar context does not have to be a reference.
Scalar is the default (normal) type for both item context and list context.
Certain operators create certain contexts. For example, the infix + operator creates Num context on both sides: both values are evaluated in Num context. Perl 5 had this too, but the subtypes of scalar context were only seldomly discussed.
An array in Perl 5's scalar context would evaluate to its number of arguments. In a standard Perl 6 item context, an array evaluates to a reference to itself. Because Array context is a form of item context, a pure array in Array context first evaluates to an array reference, which is exactly what was expected. Hashes also evaluate to self-references when used in normal item context.
When used in more specific item contexts, however, both arrays and hashes do something else: in Num context, they evaluate to their numbers of elements, in Str context, they evaluate to a string representation of the aggregate.
In list context, arrays and hashes evaluate (flatten) to their individual elements. The elements of a hash, by the way, are pairs. Each pair has a key and a value. A pair is an object, and thus a reference. The type and context are both called Pair.
This may appear complex, and it is okay if you don't grok it yet. However, the underlying system is quite simple and not that different from what Perl 5 had. Types were added, which complicate matters a little, but the power, check points and expressiveness they add are well worth it.
1 Pugs, the Perl 6 compiler, currently calls list context slurpy context, and uses cxtSlurpy for it internally.