i'm not surprised that you don't know about handles when coming from Python, since Python does all the handle stuff for you already. I'm a bit surprised that you don't know them from the C++ region though. Anyway, here's a bit of explanation.
Any variable contains data, data which needs to be somewhere within the RAM, data which can grow in size. An integer variable with 32 bits is 4 bytes in size, which isn't that much, thats why you usually don't use integer handles that much. But there are variables which can actually grow rather large over time. Consider reading a file into a string which is multiple megabytes in size. The string will have exactly the same size, probably even more, due to null termination and what else. Whenever you call a function which uses this string and doesn't use handles, the compiler will create a copy of this string just to be used within this function. Copying is a rather time-consuming task, especially if the data which needs to be copied is huge.
And now consider classes which contain multiple of those strings, each time you call a function with them as parameter they will get copied over, and those copies will be recycled as soon as the function terminates.
To prevent the compiler from copying huge amounts of data where it isn't actually needed, some inteligent guys invented handles. A handle simply knows the location of specific data inside the RAM, and what type the data is which you can find there. Thats all. That results in a fixed handle size, no matter what data you put into the variable. The handle size differs from OS to OS, but its usually something between 4 and 16 bytes.
OK, now you can, instead of copying data around in-memory, simply code a function which doesn't take the data itself, but a handle which shows the location of the data instead, because this handle is much smaller in size than the data itself. The function can then follow the handle towards the data and process it just like before.
There are even more possible situations in which handles can become useful, like writing functions which return more than just one value, or just-in-place modification of data without the need of a return value, but those are more advanced and can be found on several handle (or pointer) tutorials on the net.
Well, in BGT the thing works like this:
void print_string([email protected] data)
// bgt does the dereferencing for us already, which is kinda confusing at times, but you'll probably get the hang of it
alert("handle printer", data);
string data = "i'm quite a small string, but even i am already bulkier than my handle.";
[email protected] data_handle = @data;
// and because bgt always dereferences variables for us, we can access data_handle just like a usual string
// so we need to reference it as well
// it will print the exact same string twice, but in fact, its only stored in memory once
// and thanks for the smart bgt interpreter, we can even do this:
// since the interpreter knows that print_string() accepts a pointer, it will automatically and silently create a reference for us
Hope that helped.