CHAPTER 3: FUNCTION OVER FORM



It's time to start learning one of the most useful means of recycling code: the function! Not much to say, so read on!


LESSON 3.1: FUNCTION DECLARATION

Functions are blocks of code that can be called from anywhere once they've been declared.

function foo(x, y, g){
	local exclaim = "!";
	print(x + " " + y + " " + g + exclaim);
};

foo("I'm", "coding", "Squirrel");

Apart from the word "function" appearing before the name, this looks a lot like an if or a for statement, right? Well, it's not like either of those. What sets this apart is instead of a condition list, it has an argument list, which are separated by commas instead of semicolons. Arguments are a temporary variable created for the function that are deleted as soon as the function ends its execution, but functions can also have internally-declared locals as well. Like an if or a for, however, the block is optional, but preferred to keep code looking clean and neat. In fact, it's conventional to always include a block, even for functions with single statements.

A function can then be called by writing its name, followed by the argument list with values in place of each variable's name. Arguments are treated like local variables, and override any outside variables by the same name.

EXERCISE 3.1

Write a function by any name, and insert whatever code you like using what you've learned so far. Call the function after you've declared it.


LESSON 3.2: RETURN STATEMENTS

Functions can manipulate variables both inside and out, but did you know they can be used to create new values for variables as well? This is what the return statement is for. Just like you can pass data into a function with an argument, you can pass it back out with a return.

function foo(n){
	return n * 50;
};

local a = foo(12);

print(a);

See how a was assigned to foo(12)? The program will output 600 because 12 * 50 is 600. You'll notice the return statement is followed immediately by a math expression. While one could create a variable inside to hold that data and then return the variable, as explained in lesson 2, that's not always favorable. Return statements can use any type of data one could store in a variable, even the result of other functions!

Return statements don't have to have a value, though. A function will always end when it reaches a return, whether or not it has anything after it. Mixing this with an if statement, you can make a function that terminates before finishing its execution, or return alternate values.

function divide(a, b){
	if(b == 0) return "Cannot divide by zero!";
	
	return a / b;
};

print(divide(12, 0));

EXERCISE 3.2

Write a function using a return statement. If you want to, try writing multiple functions with one that takes the result of the others. Don't forget to call one of them when you're done!

LESSON 3.3: OVERWRITING FUNCTIONS

If you've ever used C++ or other languages like it, you've probably heard of function overloads. If you haven't, I'll give it to you in a nutshell (heheh). Overloads are functions with the same name that have different arguments, and sometimes different code. They're usually used to handle data of different types in languages with static (unchangible) datatyping. Since Squirrel is dynamically datatyped, overloads are not needed for this, and are thus not supported. Instead, when a function is declared a second time, it overwrites the old definition. See here:

function foo(){
	local a = 0;
	
	return a;
};

print(foo() + " ");

function foo(){
	local a = 100;
	
	return a;
};

print(foo());

The first foo()'s output will be 0 while the second will output 100. With function overloading, it's possible to have your program's functionality be altered during runtime. This might sound fun, but it can also be tricky. You should also know that if you run two .nut files in the same VM, any functions in the .nut loaded second will also overwrite the first, but everything that does not match will remain unchanged. With this, it is possible to write very simple mods for any Squirrel application simply by having it load a .nut with matching function names. You should be careful, though; unless changed, other code will not notice the potential change in arguments as well, and may lead to a runtime error!

Another thing to remember is that Squirrel is completely case-sensitive, meaning it will not treat foo() and Foo() as the same function. This applies to everything, not just functions. If you try to call Print(), your program will crash because it is not the same as print().

EXERCISE 3.3

Copy the code above, and add a third definition of foo() with anything you want, then print it.


LESSON 3.4: DEFAULT ARGUMENTS

Remember how I said Squirrel doesn't support overloads? Well, what if you want to make one version of a function that has more arguments than the other, and the one with less simply uses default values? You can do this by defining default arguments!
function foo(x, y, g = "Squirrel", s = "!"){
	return x + " " + y + " " + g + s;
};

print(foo("I'm", "a"));

This function will output I'm a Squirrel!. Notice that only two arguments had to be given when calling foo(). The rest can be left alone, BUT, if you want to redefine one, you must also redefine all the other defaults before it! Not providing a value for them will cause the app to crash, however, you do not have to redefine any defaults after the one you want; as long as they succeed all others, they can be left alone. You also can't have undefined arguments following a default argument.

EXERCISE 3.4

You've probably guessed by now what I'm going to ask you to do. Well, smarty pants, you're wrong. I want you to take a break and get a drink or something. Then, when you get back, you can write a function using default arguments, if you want to, but don't stress it too much; the next section will feature your first coding project!


CHAPTER 3 REVIEW

Write a function that takes two arguments, x and y. Return the product of x * y as a string that says The product of X and Y is Z where X is x, Y is y, and Z is the product.


Well done! Now you know how to define your own functions. Feel free to experiment with them a little before we move on to the next section, where you'll be applying everything you've learned so far in your first major project.

Are you enjoying this tutorial? If so, why not send a donation? You can do so by clicking the donate link at the top of the screen, and if you do, please attach a note to your payment letting me know it's for the tutorial!

<< PREV | NEXT >>