The reason why a function cannot be nested like a program is that it gets stored in the repository which is available to the entire run-unit and not just to one compilation unit.
Although you cannot use global variables within a function you can use external variables in order to share data other than the parameters which are passed to the function.
Example:
$set preservecase case repository(update ON) id division. function-id. myfunction. working-storage section. 01 myexternal-data pic x(5) external. linkage section. 01 myparam pic x(5). 01 myresult pic x(5). procedure division using myparam returning myresult. move myparam to myresult move all "2" to myexternal-data goback. end function myfunction. id division. program-id. mytest. environment division. repository. function MYFUNCTION. data division. working-storage section. 01 myparameter pic x(5) value "12345". 01 myresult pic x(5) value spaces. 01 myexternal-data pic x(5) external. procedure division. move all "1" to myexternal-data move function myfunction(myparameter) to myresult display myresult goback. end program mytest.