Never create global variables and functions. A function, accessible from everywhere, must be created as a public functions of an NVO.

They are an atavism survived from the early days of programming. Modern technologies (like Java and .NET) don't have these obsolete features at all. PB has them only for backward compatibility, so don't create new ones (there is only one exception - global functions, used in DW expressions if other solutions are more problematic).

All developers, using the Object-Oriented approach, know about encapsulation, so usually there are no questions about global variables - they are an "obvious evil". But what is so bad with global functions? If you have a small, simple function, then making it a public method of an NVO (instead of a global function) seems to bring no advantage at first glance, and even more it requires to mention the NVO with dot notation. BUT...

1. If you will want to extract a part of the function's code into a new function (according to the principle of creation a subprogram for each logical task or simply because the script has become too long) - it will be impossible without creating another global function. And if you will need 20 such functions in the future? So, you have two bad choices:

A. To create an additional global function (with all the problems around). B. Not to create it (so the script will stay a long, unreadable and hardy managed buggers muddle).

But if you have created an NVO as a container for your function (which is declared public), then you can add to that NVO any number of additional "service" methods (kept private if they are not intended to be called from outside).

2. If you need to create a number of different functions, related to a same task/flow, putting them in one NVO will not only decrease the quantity of objects in the PBL, but will also signal that they are somehow related to each other. It is definitely better than a PBL overloaded with crazy mix of tens or even hundreds of global functions, belonging to different logical units.

3. The programmed process may require to store data (for example, between calls to the function, or to cache data, retrieved once, for multi-times use by different consumers over the application). If a global function is used, your bad choices are global vars and using another NVO (in the last case you will have related stuff in different locations). But if you have created the function as an NVO method, then there is no problems - declare instance variables (as well as constants for safer and more elegant code).

Despite all the above, you will find on this site a number of global functions - for example, iif() and f_throw(). I use them so freqently that it would be incovenient to write an object name (like gnv_util.iif()) each time they are typed. In fact, they have become a part of the framework core, so they are perceived more as language keywords (like if and throw) then as user-defined functions.