Classing{js} Tutorial

Function Overloading

Why Function Overloading ?

The aim of Classing{js} is to create an object oriented environment that looks and behaves exactly like the classical object oriented environment.If you developed in a classical environment before (like C++ , Java or C#), you know that you can overload the constructor of the class to intialize the objects in differnt ways, including the way using an existing object of the same class (known as the copy constructor).So, to fully achive the aim of Classing{js}, function overloading was implemented to give the developer the ability to overload the constructors of classes and any other functions wanted.

How to create overloaded functions ?

Creating an overloaded function is done by calling the function Function.create in the way specified here , in the black box with the red gear:

Function.create
Function.create(mode , overloads)
mode Boolean

The mode of Overloading :typed or non-typed.true for typed , false for non-typed

overloads Array

an array containing the overloads.

returns Function

the overloaded function

Non-Typed Overloading

An example of non-typed overloading is the function say defined in the following :

var say = Function.create(false , [
	function(msg1) {
		console.log(msg1);
	},
	function(msg1 , msg2) {
		var concat = msg1 + " , " + msg2;
		console.log(concat);
	},
	function(msg1 , msg2 , msg3 , msg4) {
		var concat = msg1 + " , " + msg2 + " , " + msg3;
		console.log(concat);
	}
]);
					

say here has three instances that accepts one argument, two arguments and four arguments respectively with no restriction on the type of the argument passed. You can pass numbers , strings , objects or any thing and no error will be thrown.The only case an error will be thrown is if you passed a number of arguments that has no instance in the function. Namely , if you passed four or more , two or no arguments , an error will be thrown idicating that no instance matches the argument list.

say("Hi"); //Ok
say("Hi" , 5); //Ok
say("Hi" , "Welcome" , "to Classing{js}" , 1) //Ok

say(); //Error
say("Hi" , "Welcome" , "to Classing{js}"); //Error
sya("Hi" , "Welcome" , "to Classing{js}" , "v" , 1 , "." , 0); //Error
				

To make the code more readable , the library provides the constnat classing.xNonTyped which is equal to false that can be passed as the first argument to Function.create indicating a non-typed overloading mode. As this constant is expectd to be used repeatedly, a global shortcut is provided so it could be written fast without calling it from the classing namespace.

var add = Function.create(xNonTyped , [function(a,b){return a+b;} , function(a,b,c){return a+b+c;}]);
				

Heads Up !

  • The overloads array must contain only functions. if a non-function element exists , an error will be thrown.
  • var join = Function.create(xNonTyped , [function(a,b){return a + "," + b;} , "function(){}"]); //Error
    							
  • each function in the overloads array must have a unique number of parameters. if two functions had the same number of parameters , an error will be thrown.
  • var echo = Function.create(xNonTyped , [function() {return "Void";} , function(a){return a;} , function(b) {return "'" + b + "'";}]); //Error
    							

Typed Overloading

The syntax to create a typed overloaded function is similar to that of non-typed but with a little difference in the format of the overloads array. To fully define an overload instnace you'll need two elements of the array , the first one to hold the types list and the one that follows it to hold the function itself.the type list is created through the function classing.types.There's also a global shortcut for that function.

types
classing.types(c1 , c2 , c3 , ...)
types(c1 , c2 , c3 , ...)
ci Function

the constructor function of the type (either native or custom)

returns _xTypes Object

the type list object to be passed to Function.create

For example , to write a type list of a function , a boolean value , an array , a string and finally a number , we write:

types(Function , Boolean , Array , String , Number)
					

A correct-formated overloads array follows this pattern : the type list comes first , then in the next element comes the function associated with that type list (The number of types and the number of paramters in the associated function must be equal). Note that any overloads array not in this format will throw an error. An example of a typed overloaded function is the add function defined in the following:

//a Custom type represnting complex number
function Complex(r , i) {
	this.real = r;
	this.imaginary = i;
}

var add = Function.create(true , [
	types(Number,Number) ,
	function(a , b) {
		return this.a + this.b;
	},
	types(Array , Array),
	function(A , B) {
		if(A.length === B.length) {
			var C = new Array(A.length);
			for(var i = 0 ; i < A.length ; i++) {
				C[i] = A[i] + B[i];
			}
		}
	},
	types(Complex,Complex), //the custom type
	function(Z , W) {
		return new Complex(Z.real + W.real , Z.imaginary + W.imaginary);
	}
]);
					

Here , add has three instances , each of which accepts two arguements but with different types. the first one accepts two numbers , the second accepts two arrays and the last one accepts two objects of the type Complex (which is a custom type). Any call to add with an argument list matching a defined instances in both number and types will work fine. Any call with an argument list that doesn't match any defined instance will throw an error.

add(40,89.69); //Ok
add([1 2 3] , [-1 0 9.678]); //Ok
add(new Complex(7 , 0) , new Complex(1 , -6)); //Ok

add(80); //Error
add(80,"Hello"); //Error
add([1 4 7] , new Complex(7 , 52)); //Error
				

Like in non-typed overloading , the library provides the constnat classing.xTyped which is equal to true to be passed as the first argument of Function.create indicating a typed overloading mode. An xTyped global shortcut is also provided.

var divide = Function.create(xTyped , [types(Number , Number) , function(a , b) {return a / b;}]);
				

The following are the categories of types that can automatically be recognized in the typed overloading mode:

For custom types that has a constructor of the form:

var <constructorName> = function(a,b,c, ...) { ... }
					

a stamping step must be made before Classing{js} can recognize it. the stamping is done using the function classing.xStamp

xStamp
classing.xStamp(Constructor)
Constructor Function

the custom constructor function to be stamped

For example:

var Human = function(a) {
	this.age = a;
}
classing.xStamp(Human);
var add = Function.create(xTyped , [
	types(Human,Human),
	function(H1,H2) {
		return new Human(H1.age + H2.age);
	}
]);

add(new Human(41) , new Human(16)); //Ok