Understanding Functions – Arguments

There is a very short list of programming structures you have to learn to be reasonably comfortable in most modern object-oriented languages. Functions are one of them.

In Understanding Functions, we learned that Functions are a way to bundle code statements together into a tight little unit that we can invoke (or “call”) any time we like, and as often as we like. There are two very important features to learn about Functions: Arguments and Return Values. We’ll figure out Arguments in this article.

Til You’re Blue in the Face

Arguments aren’t as unfriendly as they sound. They’re just additional pieces of information we can send to a Function during a Function call. You’ll remember that a Function call looks like this:

doSomething();

Quite often, we need to pass additional information to Functions to make them super-useful. Let’s imagine we have a text input field where the player can enter his name. The player types in his name and clicks a button, and the game says “Hello, John” (or whatever the player’s name is). The dynamic, or changing, part of that Function is the player’s name. Here’s how that Function might look if it was “hard-coded”:

function sayHello()
{
    trace("Hello, John.");  // ain't nothing dynamic about this
}

Note: Unity javascript people will want to start the function name with a capital letter as a best practice, and use either print or Debug.Log in place of trace.

This is okay, but the problem is that every time we call (run, execute, do) that Function, it’s going to say “Hello, John.” What if the player’s name isn’t John? Well, we need to make that part dynamic, because it changes.

Dynamic!

Let’s set up our Function so that we say “Hello”, and then tack on a variable that holds the player’s name:

function sayHello()
{
    trace("Hello, " + playerName);
}

(When working with Strings, the + operator glues two strings together.)

It’s getting better, but we have a new problem: the code interpreter is going to see playerName and think “playerName? What the heck is that?” Then it’s going to freak out and the Earth is going to crash into the Sun, and we don’t want that.

We need to declare and define the playerName variable somewhere. But instead of just declaring playerName any old place, we’re going to tell the sayHello Function which playerName we’d like it to say. We’re going to set our sayHello Function up so that it has a parameter. We do that between the round brackets in the Function declaration:

function sayHello(playerName : String)
{
    trace("Hello, " + playerName);
}

Parameters go between the round brackets in a Function declaration. In the continuing tradition of seeing our blocks of code as visual elements, check this out:

Parameters

If you’re a visual person, learning to see code in blocks like this could help you out a lot.

When we structure a Function this way, we say that the sayHello Function accepts one parameter, which is called playerName. The type of playerName is a String (a list of letters and/or numbers). Notice that even though this is kind of like a variable declaration, we don’t need to use the var keyword.

Exact Change Required

i like to think of parameters as the payment that a Function accepts. The sayHello Function takes one argument and stores it in its first parameter. Since the first parameter is of type string, we need to “pay” it a string. If we pay any other datatype (int, float, number, boolean, array), the compiler will throw an error.

Here’s how we “pay” a string to the sayHello Function:

sayHello("Murphy");

Freeze frame! Let’s become the Pac Man-like code interpreter and follow the logic of this statement for a moment.

The interpreter gets to this line and recognizes it as a Function call, thanks to those round brackets at the end.

Step 1

It also sees – hey! – the programmer has passed an argument to the Function inside those round brackets. So Pac Man puts that in his suitcase, hops in the DeLorean, and travels off in search of the sayHello Function.

Step 2

When he finds it, before he starts chewing through the statements in the statement block (between the curly braces), the Pac Man-like code interpreter drops off the argument into the waiting playerName parameter bucket, between the round brackets of the Function declaration.

Step 3

Now the parameter called playerName has a value of “Murphy”. Since “Murphy” is a String, and since the sayHello Function demands exact change (one argument of type String), we’re good to go!

With payment resolved, the code interpreter chews through the statements in the statement block (between the curly braces), reaches the bottom of the Function, and hops back in the DeLorean to pick up where he left off, back at the end of the Function call.

Step 4

Because the value of the variable playerName is the String “Murphy”, the result is that the console/output window says Hello, Murphy. It will say Hello to whatever name we pass in as an argument.

Breakamage Pt.1 – Wrong Datatype

It’s really important to break code and cause errors, so that when you’re in a jam on a project and an error comes up, you’ll know what it means and how to deal with it.

Try tweaking the sayHello Function call so that you pass an int (integer/whole number) instead of a String:

sayHello(42);

42 is not a String. Your first clue is that it’s missing those double-quotation marks around it. Since the sayHello Function DEMANDS exactly one string as payment, the compiler throws an error.

This is what that error looks like when we use ActionScript 3:

Scene 1, Layer ‘Layer 1’, Frame 1, Line 1 1067: Implicit coercion of a value of type int to an unrelated type String.

i really take exception to the way eggheads write error messages. They could stand to be a LOT more clearly written. But here’s what this error is trying to say: “implicit coercion” means you’re trying to force something to be something else, and ActionScript 3 can’t manage it. In this case, you’re trying to force an int (42) to become a String when Pac Man delivers the goods to the sayHello Function, and the compiler is having a minor freak-out. That’s your clue that you may have passed a mismatched type as an argument to a Function.

This is the error message that the same mistake will cause in Unity javascript;

Assets/NewBehaviourScript.js(4,10): BCE0017: The best overload for the method ‘Tutorial.sayHello(String)’ is not compatible with the argument list ‘(int)’.

Ugh! You eggheads are killing me. Forget what an “overload” is and focus in on the part that (sorta) makes sense to you right now: something is not compatible with the argument list. You can see quite clearly that one is a String, and the other is an int. That’s your clue that you’ve botched the argument type. Go back and patch this up, and you’ll be golden.

Extremely Argumentative

So is that it? Can Functions only accept one argument? No … they can actually accept multiple arguments. Be sure to comma-separate them, like this:

makePizza("pepperoni", "mustard", "tree bark");
 
function makePizze(topping1 : String, topping2 : String, topping3 : String)
{
 
}

B..but … do they all have to be the same datatype (String)? Heck no! You can mix and match. The only rules are that you need to pass the arguments into the Function in the same order as the parameter list, and you need to pass the same number of arguments the Function requires. The Pac Man-like code interpreter unpacks these one at a time in order. So let’s pretend there’s a function that takes a String, an int and an Array (in that order):

function initPatient(patientName : String, age : int, aPhobias : Array)
{
 
}

As long as we pass in a String, an int and an Array, in that order, it works:

var theName : String = "Shaggy";
var theAge : int = 17;
var aThePhobias : Array = new Array("like, ghosts", "like, zombies", "like, creepy-crawly things");
initPatient(theName, theAge, aThePhobias);

That’s fine. But as soon as we mix up the order, there’s trouble:

var theName : String = "Shaggy";
var theAge : int = 17;
var aThePhobias : Array = new Array("like, ghosts", "like, zombies", "like, creepy-crawly things");
initPatient(theAge, theName, aThePhobias);
 
// ERROR!  Totally long-winded explanation that could really be made a lot more clear, but eggheads aren't about making other people's lives easier (unfortunately).  In short, argument type mismatch.

So far so good? You may have noticed that i made the names of the variables i passed into the Function as arguments conspicuously different than the names of the parameters i accepted in the initPatient Function. This is because i wanted you to see that there is a difference between these two things, and that there CAN be a difference. When you call a Function and pass it some arguments, the variable names you pass in don’t matter … it’s the values stored in those variables that Pac Man takes with him on his journey.

Breakamage Pt.2 – Wrong Number of Arguments

Just as sending in the wrong type of argument will throw an error (ie paying a quarter when the Function wants a nickel), the compiler will throw an error if you pass in the wrong number of arguments.

In this example, we have a Function that accepts one argument, but we try to pass it two arguments:

function eatBacon(numberOfStrips : int)
{
    trace("OM NOM NOM!  I just ate " + numberOfStrips + " strips of delicious bacon.");
}
 
eatBacon(57, "i can haz heart attack"); // ERROR!!

The function wants only one argument, but we’re sending it two. Here’s what the error looks like when we use Actionscript 3:

Scene 1, Layer ‘Layer 1’, Frame 1, Line 6 1137: Incorrect number of arguments. Expected no more than 1.

Thankfully, this is one of the clearest error message i’ve ever seen an egghead write.

This is what the error looks like when we use Unity javascript (changing trace to either print or Debug.Log and using a capital letter to begin our Function name):

Assets/NewBehaviourScript.js(8,9): BCE0017: The best overload for the method ‘NewBehaviourScript.eatBacon(int)’ is not compatible with the argument list ‘(int, String)’.

That’s the same error we get when there’s an argument type mismatch, so the Actionscript eggheads did a slightly better job of communicating the problem than the Unity eggheads did. The important thing is that you learn to recognize why Unity or Flash are throwing the error so that you can fix it quickly and get on with your project.

Note that you’ll throw an error even if you “overpay” a Function. If a Function wants exactly two arguments, and you give it nine, you’ll get one of these errors.

But Wait – There’s More!

There are two more advanced topics when it comes to passing and accepting arguments – optional arguments, and Rest arguments. They’re useful, but not crucial. We’ll be sure to cover them in future articles.

For now, get some practice passing arguments to your Functions, and writing parameters to store those articles. The fate of the free world may depend on it! Or whatever.

For more Flash AS3 Tutorials and a pile of other useful stuff, check out our Flash and Actionscript 911 feature.

Leave a Reply

Your email address will not be published. Required fields are marked *