We don't think it is a good idea to let a function body declare its own VALUEs (this complicates the syntax greatly in that the function body starts allowing multiple statements and this opens the door for trying to define functions inside functions), but we agree that there are arguments in favor of making FUNCTION bodies see existing VALUEs that we have.
Here's our thinking:
The pro of making a FUNCTION body see a VALUE is the ease of use. After you define a VALUE, you can use it in all text you write after that definition, be it a regular statement (SELECT) or a function (FUNCTION).
The con of making a FUNCTION body see a VALUE is that this introduces ambiguity: when a function body refers to @a, this could be either a parameter or a global value. If there is both a parameter named @a, and a global value named @a, the parameter should silently win (if we report this ambiguity as an error or let the global value win, then whenever you declare a new VALUE, you risk breaking functions that use the same name as a parameter, this is impossible to work with). So, there is an ambiguity that has to be resolved silently. Ambiguities that are resolved silently are nearly always bad, and here is why it is bad in this case: if you have both a parameter named @a and a global value named @a, decide that a function does not need to take @a as a parameter, remove it from the list of parameters, but forget to remove it from the function body, the function body will still compile but will probably not do what you want. It would have been better if it didn't compile and you got a reminder that you are still referencing @a even though you stopped passing it.
Another con of making a FUNCTION body see a VALUE is that after the function is compiled, the VALUE can be redefined, and when that happens, the compiled function will continue to use the old value. This is similar to how you can define FUNCTION f(), then define FUNCTION g() calling f(), then redefine FUNCTION f() to something else and g() has to continue using the old definition of f(), but while this is kind of inevitable with functions, it is not inevitable with values - because you can just never reference global values and accept them as parameters instead. That said, this whole notion of redefining functions and values exists mostly because we allow running SQL interactively in a command window, and redefining things is useful in that context. For persistent queries we are considering an option to disallow redefining functions and values, making any redefinition a runtime error. If we do this, this particular point in favor of not allowing function bodies see values will lose most of its strength.
Sum total: currently, functions can call other functions, global values can call functions and use other global values, but functions cannot use global values. There are arguments in favor of allowing functions to use global values. Some of the issues get easier if functions and global values can no longer be redefined, we are considering adding this restriction in some form.