Functons are used where you don't need memory attached, all data needed to complete the logic is passed as IN or IN_OUT parameters and the result is passed as a OUT or IN_OUT.
Good practice would dictate that you do not attempt to set parameters sent in as IN parameters and you don't user the OUT parameters as conditions until after you have conditioned them in the block.
Function Blocks are as they call them, blocks with memory, that is when called from the code, you must assign an Instance Data Block, where all IN, OUT, IN_OUT and STAT parameters are saved and can be used external to the FB if required.
I have seen code where they have created an FB as a distribution block, where there was no input or output parameters and no STAT's created. When the block was called they had to create an Instance DB, the only time I have seen empty DB's. That was a definate case where the block should have been a Function.