different outcome based on function execution method
If you have a function that does an UPDATE and you try to call that from a SELECT statement, you should get an Oracle error saying that you cannot do DML inside a query.  So your SELECT statement should be throwing an error.  My first guess would be that you have an exception handler somewhere that, intentionally or not, is catching and discarding the error.  My next guess would be that the function was declared using an autonomous transaction pragma, which is almost certainly a bug because that would mean that the function was running in a separate transaction scope from the calling code and could not see uncommitted changes made by the caller (such as, for example, inserting the row that the function is trying to update).

In general, if you have a piece of code that is doing an update, that should be a stored procedure not a stored function.  That would mean that it cannot be called from SQL (just like a function that does DML cannot be called in a SQL statement).  But that is exactly what you want.  You don't want a function called in a SQL statement to have a side effect because you cannot control things like how many times the function is called.  Even in a SELECT from dual, the function could be called multiple times by Oracle (though that is unlikely).