Composability, Scoping, and Non-Interference

| 1 Comment

Perl 5's flexibility allows the CPAN to exist and CPAN's flexibility allows Perl 5 to evolve. Where would Perl be without the DBI or TAP? Imagine using Perl 5 without LWP or Moose or Perl::Critic.

Even so, the difference between a core language feature and a language extension created and maintained and distributed outside of the core is immense. Certainly some code uses non-DBI database modules, but it's clear that DBI is the foundation of all modern and widespread database use in Perl 5 today. Similarly, try using a test module without Test::Builder. Moose hasn't quite taken over the CPAN yet, but it's a matter of time.

In other words, some language extensions become so prevalent that they might as well be core parts of the language. (I realize not everyone uses the boilerplate of strict and warnings and autodie and feature in every Perl 5 file they write, but enough do that writing the silly little Modern::Perl was a worthwhile abstraction and encapsulation. One of my current projects has 41 Perl 5 files at the moment and some 1866 lines of code. 4.2% of my SLOC count would be that boilerplate if it weren't for this pragma. Boilerplate adds up.)

Unlike core language features, language extensions have no strong single authority to ensure that they interact appropriately. (There's always the post hoc bug report, with its finger pointing and blame and the end result of a Pragmatic if Horrifyingly unPlanned programming language.) Language designers can only do so much to encourage the developers of extensions to consider how to work well with each other.

If I'm right about the history and motives of the development of Perl 5, the fundamental unit of encapsulation in modern Perl is lexical scoping. If that's correct, the boundaries between various components of a Perl program must have their hard edges at lexical scopes.

In specific, the warnings pragma is friendlier than the -w command-line argument to Perl 5 because it does not enforce global behavior for code outside of its lexical scope.

In specific, using global variables is dangerous because it ignores encapsulation boundaries. (Yes, the existence of so many magic superglobals in Perl 5 itself is a language flaw.)

In specific, using UNIVERSAL::isa() to check the class of a referent is an unneighborly design error because it does not allow the referent to control its own nature.

In specific, using direct dereferencing access for object attributes is a mistake because it bypasses any validation or indirection which you shouldn't even know exists in a well-designed system.

None of these should be surprises to experienced Perl 5 programmers, but the implications run deeper—especially when discussing CPAN distributions.

With the caveat that a pragma (autovivification or autodie) with well-defined semantics (and adherence to lexical scoping) is acceptable precisely for its side effects (which do not leak out), a well-behaved CPAN distribution both sets a strict lexical boundary around its encapsulation and does not interfere with other code by its existence.

Moose is yet again a good example: it does not subvert Perl 5's default OO and it interacts with Perl 5's default OO. (In truth, the single legitimate main gripe about the effect Moose has on programs is solely its effect on program startup time.)

You can see the flip side of this principle in other languages which encourage monkeypatching of core language features without regard for lexical scoping of changes. This has the potential to devolve into a squatter's rights free-for-all, with the battle to be the first, most widely used library to scribble all over core behavior with little regard for the needs of anyone else. You might think that in these cases core always wins, but by not defining a mechanism for these types of extensions to work correctly, core can't win.

Then again, you have to get scoping right before any of this has a chance of working correctly.

1 Comment

"Imagine using Perl 5 without LWP or Moose or Perl::Critic."

LWP: Can't imagine it. Virtually eliminates the use of CPAN.
Moose: I can imagine it, but I don't like it very much!
Perl::Critic: Not convinced its use is essential to Modern Perl. PBP is certainly a good concept but it means different things to different people.

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



About this Entry

This page contains a single entry by chromatic published on November 4, 2010 12:32 PM.

Extensibility and Composability was the previous entry in this blog.

When You Can't Write Methods Too Small 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?