http://www.perlmonks.org?node_id=405770

Scripting language designers face a temptation to drop all variable declarations. Variables can simply be created on first assignment. It seems so much easier than Java or C++ where everything must be declared before use. But there is a serious trade-off: misspelled variable names won't be caught until run-time. A restricted version of the language in which minimal declarations are required becomes necessary. Hence, Perl's "use strict" with "my" variables.

My first discovery of the value of this principle was in FORTRAN. In the old days people just started integer variables with I-N and float variables with other letters. But when I started using "IMPLICIT NONE" and found the power of compile-time typo-catching I never looked back.

Python and Ruby claim to be better-designed rivals to Perl, but neither of them has static checking for variable-name typos with the same power as Perl's. Variables on the left-hand side of assignments are particularly vulnerable to error. Python at least has PyChecker; Ruby has nothing.

Ruby users claim that everything can be caught by unit testing. That is a very poor idea because obscure paths through the code may be missed, and then a crash will happen during some crucial run later on. IMHO, unless Ruby comes up with a "strict" variant that allows some minimal static checking it will never be a serious rival for Perl for large projects.

Languages can do even more static checking without getting in the way. For example, OCaml does type inferencing based on the functions being applied to the variables. Explicit declarations are seldom needed for full compile-time type checking. The drawback is that operators have to be distinct by type: for example, "+." is used for floating-point addition and "+" for integer addition.

For me, Perl with "use strict" has a good balance between typo-catching power and simplicity of use. Additional optional "use stricter" checks might be worth looking into, for example doing the same sort of limitations on package-level variables.

use stricter; use Data::Dumper; # typo: should be $Data::Dumper::Maxdepth $Data::Dumper::MaxDepth = 3;
This might produce an error or warning about creating a new package variable in code outside the package, instead of silently failing as it does now.

Replies are listed 'Best First'.
Re: The power of strict typo-checking
by davido (Cardinal) on Nov 06, 2004 at 16:37 UTC

    I think at first people see the use of lexical (my) variables as just a side effect to the practice of programming under strictures. And naturally the primary benefit to that side effect is seen as typo-protection. Certanly that is one of the useful features of programming under strictures.

    But I have found that the more important effect (to me a primary effect) of programming with use strict is the fact that it ultimately encourages a certain style of programming; lexical scoping. Sure, you can use strict, and never really learn about lexical scoping. But honestly, I see lexical scoping as the primary reason to use lexical variables, and better error checking as one of the secondary reasons.

    And of course there are other effects of the use of strictures. Using strict prevents the accidental use of symbolic references, it prevents the undeclared use of non-lexical variables, and it prevents barewords from being used for anything but subroutines (except on the lefthand side of => operators in some cases).

    But I really see the primary advantage to using strictures the fact that it promotes the use of lexical variables, where I see lexical scoping as one of the more powerful underlying features of Perl.


    Dave

      ... and lexical variables is what gave us closures in Perl. :-)

      ihb

      See perltoc if you don't know which perldoc to read!
      Read argumentation in its context!

Re: The power of strict typo-checking
by tmoertel (Chaplain) on Nov 06, 2004 at 16:56 UTC
    The drawback is that operators have to be distinct by type: for example, "+." is used for floating-point addition and "+" for integer addition.
    This drawback is not part of the general tradeoff that comes with type checking but rather is an artifact of certain implementations. For example, Haskell's type system supports type classes and does away with this limitation:
    $ ghci ___ ___ _ / _ \ /\ /\/ __(_) / /_\// /_/ / / | | GHC Interactive, version 6.2.1, for Haskell 98. / /_\\/ __ / /___| | http://www.haskell.org/ghc/ \____/\/ /_/\____/|_| Type :? for help. Loading package base ... linking ... done. Prelude> :t (+) (+) :: forall a. (Num a) => a -> a -> a Prelude> 1 + 1 2 Prelude> 1.0 + 1.0 2.0 Prelude> :module +Ratio Prelude Ratio> 1%2 + 1%3 5 % 6

    Cheers,
    Tom