Procedures

A procedure is a block of code you write, that functions similarly to built in Mel Commands.
The mel command to make a sphere is sphere;.
If you really wanted, you could make your own sphere procedure, like so:

global proc IWantToMakeSpheres ()
{
	sphere;
}

execute that in the script editor, then type IWantToMakeSpheres.
A sphere is born.

There are two types of procedures in Mel, local and global.
This should sound familiar, remember variable scope?
A global procedure may be called from any script anywhere.
Local procedures are only local if they are created in a file that 
is executed using the source directive.  In that case they are available
only within that specific file.
A local procedure is declared like this:

proc IWantToMakeSpheres ()
{
	sphere;
}

Just don't put in the keyword global.

Argument List

A procedure's argument list is the list of values it takes when you call it.
You create the argument list this way

global proc IWantToMakeSpheres (int $many, string $message)
{
	int $i;
	for ($i = 0; $i < $many; $i++)
	{
		sphere;
		print $message;
	}
}

This part, (int $many, string $message) is the argument list.
Now you can tell the proc how many spheres you want it to make.

Now that the procedure has an argument list, you are required to give values for them when
you call the proc.
IWantToMakeSpheres procedure now you must call it like:
IWantToMakeSpheres 12 "Some string goes here\n". 
You can use explicit values, or variables:

{
	int $number = 12;
	string $sayThis = "I hate spheres.\n";
	IWantToMakeSpheres $number $sayThis;
}

But if you don't fill the argument list you'll get an error.
There are two syntaxes for calling a procedure. One is the way you just saw, the other is this:

{
	int $number = 12;
	string $sayThis = "I hate spheres.\n";
	IWantToMakeSpheres($number, $sayThis);
}

The two variations have a slightly different syntax when it comes to getting return values.

Return Values in Procedures

Just like a mel command returns a value, you can have a procedure return a value.
after the word proc, but before the argument list, put the type of variable you want it to return:

global proc string IWantToMakeSpheres (int $many, string $message)
{
	int $i;
	for ($i = 0; $i < $many; $i++)
	{
		sphere;
		print $message;
	}
	return ("You made " + $many + " horrible spheres.\n");
}

then

{
	string $spherish = `IWantToMakeSpheres 25 "I don't not hate spheres.\n"`;
	print $spherish;
}

the alternate syntax looks like this:

{
	string $spherish = IWantToMakeSpheres( 25, "I don't not hate spheres.\n");
	print $spherish;
}

Notice you leave off the `...`
I prefer the first syntax because it looks more like a call to a regular mel command.

One thing to know about the return command.
It acts like a break command in a loop.
When the procedure reaches the return command, it ends there.

You can use this to your advantage.  Say you don't want the user to create more than 100
spheres.  One way to keep that from happening would be to use the return command in this way.

global proc string IWantToMakeSpheres (int $many, string $message)
{
	int $i;
	for ($i = 0; $i < $many; $i++)
	{
		sphere;
		print $message;
		if ($i == 99)
			return ("More than 100 spheres is hazardous to your health.\n");
	}
	return ("You made " + $many + " horrible spheres.\n");
}