1. A computer-implemented method for facilitating the development and execution of a software program, comprising: during runtime of the software program, obtaining a function call associated with an overloaded function and a generic type hierarchy that lacks contravariance; determining an applicability of an implementation of the overloaded function to the function call; selecting the implementation for invocation by the function call based on the determined applicability and a partial order of implementations for the overloaded function; and performing type inference on one or more generic type parameters of the implementation by: obtaining a set of initial limits on the one or more generic type parameters; propagating one or more lower limits from the set of initial limits through a set of constraints for the generic type parameters; if the propagated lower limits specify non-empty intervals for the constraints, choosing the one or more lower limits as bindings for the one or more generic type parameters; and if the propagated lower limits specify empty intervals for the constraints, determining that the implementation is not applicable to the function call.