Many people recognize one form of progress in programming language design: the addition of new features, usually forming higher levels of abstraction. Less recognized is the dual of this form of progress: the removal of older, usually lower level, features and freedoms. Paradoxically the removal of language freedoms frees the mind to concentrate on more important parts of the problem at hand.
The earliest programming languages, assembly languages, provided unlimited freedom at a micro level. As an example, each developer was able (actually required) to invent their own conventions for calling subroutines. They could pass parameters in (their own choice of) processor registers, or on a stack (ascending or descending), or in memory structures on a heap. Each of these techniques had benefits and drawbacks, but in the end it was more important to standardize so that developers could share libraries of common modules and free up cognitive space for other issues.
At a higher level, the C programming language (plus the operating system binary formats) standardized routine calling conventions, but left freedoms as to where variables are located and how they are passed. C provides primitive types and records, locates them on the stack or heap, and supports direct memory pointers and pointer manipulation. C++ adds slightly safer references, while retaining pointers. Java, safer and at a higher level, takes away pointers and leaves only references. Much of the safety becomes possible (and necessary) once memory garbage collection is added and low-level memory control is taken away.
Other higher-level languages continue this pattern of addition and subtraction. Python and Ruby add lists and dictionaries as built-in types, and take away direct use of native hardware types.
Perl (yes, the topic of this post) is the oddball. It added many beneficial higher-level features later found in Python and Ruby, but did not remove the low-level freedoms of C++ or even assembly. Like assembly, Perl does not have a single built-in way to pass arguments to functions; instead "there's more than one way to do it" (the Perl motto) so users of CPAN libraries need to pay attention to the calling conventions for each library [and the common ways to do it, @_ and shift, are ridiculous]. Like C++, Perl has references. It needs these because it allows objects to reside on either the stack or heap. But there is no good reason for this distinction in a high-level garbage collected language, and it forces the programmer to explicitly reference (take address-of) and dereference using \, $, etc. (like & and * for C pointers!). Even Java references don't require explicit dereferencing and disallow address-of.
Perl has these issues partly because it was an early introducer of new higher-level features, and didn't want to break compatibility with older Perl programs by removing lower-level functionality and freedoms. But this means the language requires much more cognitive space to understand than newer languages like Python and Ruby, and leaves less cognitive space available for solving the problem at hand.