This coding tip is intended to demonstrate the
Principle of Parameter Parsimony.
It basically means this:

You should be as stingy and as sparing
as possible when adding new parameters to your scripts, database
schemas and application designs. The goal is to minimize the number
of ways your application can go wrong.

This example deals with the simple scenario of assigning the same value
to more than one scalar.
This node shows an interesting way to do it. This node
explains why the previous interesting way can cause problems. The problem
comes from violating the Principle of Parameter Parsimony.

### This is nice and compact, but what happens if you
### add new variables? You have to remember to keep count.
### You are essentially saying the same thing in two
### different places, and in two different ways.
my ($a, $b, $c) = ('TRUE') x 3;
### A more parsimonious example
my $a = my $b = my $c = 'TRUE';

We see from Example1 that we introduce problems when we aren't stingy
with the way we arrange parameters in our code. The goal is to *avoid* saying
the same thing in more than one place, and in more than one way.

Example2: Superfluous 'Status Flags'

Example2 deals with a more 'real world' scenario. Consider the
following data structure that is based on a user database for a
popular website.

The basic strategy behind this data structure is to automatically
consider a user 'new' if she has never used the site before. New
users start with blank information. Afterwards, the 'never_used_this_site_before'
flag is set to '0' when the user first signs on to setup an account
on the "New User" page.

Seems harmless enough, right? Wrong! This is another example
of non-parsimonious parameterization!

The problem is this. What happens if the user starts to sign
on under the "New User" page, but then goes on a lunch break
after filling in the fname field, and then leaves for lunch leaving some of the information blank? Suppose there is a session timeout? The never_used_this_site_before
flag is turned to '0', but the user still has not filled in all the
required information!

Based on this scenario, when the user comes back to log on
to the site, it will tell her the password is blank, assume she is a new user and needs to create an account. When she goes
to create an account, however, it will tell her that an account
with that name *already exists* because fname and
never_used_this_site_before have been initialized.

A more parsimonious
way to do what we want is to *get rid* of the never_used_this_site_before flag, and simply
evaluate whether all required fields are filled in (non-blank) before determining
whether to send the user to the "Create New User" page or the "Edit Account Info" page.

NOTE: Obviously there are a lot of assumptions and serious design issues painted in this example, but it is included here because this *specific* case has happened often enough to motivate this point on parsimony. Numerous other issues beyond the scope of this note are excluded.

In Summary: Be Stingy with your Parameters and Variables

Unlike with humans, where it is good to paraphrase and say the same
thing in multiple variations so as to get your point across, this
practice of redundancy is not as generously rewarded in the programming
realm. Keep the parameters to a minimum, say things as parsimoniously as possible, and you will minimize the number
of ways things can go wrong in your code.

I cannot tell you how many times I have encountered this issue. And not only does it complicate things from the user side (as you described), I have found it many times makes code totally unreadable. You example shows only one flag, but I have dealt with code and database tables which had 5 or more flags. The justification is usually that it "speeds things up", but this is a classic case of premature optimization.

I'm not sure anybody will read this, since I'm a bit late. However, the term 'superfluous' status flags is a little bit indescriptive. For instance, I find the status flags in Apache::Session to not be superfluous, but then again I'm sure they could be replaced... how do you define superfluous in this case? Are they status flags that lead to mistakes in code logic? Aren't all mistakes in code logic a problem? What 'superfluous status' flags simply aren't mistakes in code logic rather than "Parsimonious Parameterization."

Superfluous status flags are those which can readily be inferred from the rest of an object's state. They denormalize the data structure (in relational database terms) and the additional code required to update them in sync with the actual data violates the Once And Only Once principle.

There have been a number of Perl submissions there, though not as many as one might expect. Check out The Guy Who Invented Arrays for an example. I guess VB has captured the majority of the crop of casual programmers who are prone to pretzel logic, where ten years ago a much larger percentage of those would be using Perl.

First, thanks for the link, thats an interesting site. :-) But i have to quibble a little with this particular example. Obviously the code posted in that link appears hokey. Not using pack/substr or vec for the index string strikes me as a little odd for instance. But the overall strategy represented there is not IMO that crazy. Consider that if you have large numbers of strings such a strategy can greatly reduce the overhead of storing it in perl. Each SV in perl represents a certain amount of space, for the sake of the discussion lets say 20 bytes, versus the 2 - 8 required by a representationg akin to the one mentioned. So if we are storing large numbers of strings this overhead can be quite burdensome. Also, by using such an approach you can grab a large chunk of memory at a single go instead of doing a large number of small allocations. (Its interesting (if a little obvious) to consider that if you have 100k null terminated strings you are using 100k to simply store the end of string point :-)

Anyway i didnt think such comments were worth posting on the site you linked to, but I do think its worth mentioning here.

#merges the elements of two or more arrays together so that the values+ of one
# are appended to the end of the previous one
sub array_merge{
my(@array1, @array2) = @_;
foreach my $element (@array2){
@array1 = (@array1, $element);
}#foreach
return @array1;
}#array_merge

A higher-level view of this is that the programmer must be aware of when a transaction is happening, and avoid installing any "holes" that allow the transaction to end up partially committed. The analytical/reductionist mindset of "break it down into steps" must be balanced by the synthetic/holistic flipside that says "this whole thing is just one step". Transactions are not just something that database programmers have to worry about. I think training
in transactional thinking tends to fall through the paradigmatic cracks because transactions can't be classified as functions or events or objects. If anything, a transaction is most closely related to the logic programming paradigm, which is undertaught. A transaction can be viewed as a sort of hypothesis that can either be proven or disproven. A partially proven hypothesis is of little use.

When putting a smiley right before a closing parenthesis, do you:

Use two parentheses: (Like this: :) )
Use one parenthesis: (Like this: :)
Reverse direction of the smiley: (Like this: (: )
Use angle/square brackets instead of parentheses
Use C-style commenting to set the smiley off from the closing parenthesis
Make the smiley a dunce: (:>
I disapprove of emoticons
Other