How to load correctly submodule into __init__.py Taking into account the use of bpy.ops.script.reload()?
It is not that bad to use the second method if you're not collaborate and distribute your project with other. In other words, personal usage is fine if you do take care of naming confliction.
The problem when you reload script is a common mistake that you assume that all object you imported from that module is reloaded by the reload method (imp.reload()). Instead reload all relative script, Python will only reload the required script, which is your module, not the * objects.
You can some how use Python built-in reload function to specify the updated script that you want to use and reimport * again:
from imp import reload
reload(function)  # bpy.ops.script.reload() seems like a sugar macro that handle the dependencies

from functions import *
# This is required since you don't reload e.g. `foo()` and `bar()` in your functions

And also if you want to use Method 1 for correctness:
from . import functions as fn
fn.foo('bar')

or
# You should take care about relative import path issue
from ./functions import (
    foo,
    bar,
    a_very_loooong_name_function,
)
foo(&quot;cool&quot;)
bar(&quot;hello&quot;)