def linear(current, target, rate, dt):
    """
    This function returns the new value after moving towards
    target at the given speed constantly for the time dt.

    If for example the current position is 10 and the target is -20,
    the returned value will be less than 10 if rate and dt are greater
    than 0:

    .. sourcecode:: Python

        new_pos = linear(10, -20, 10, 0.1)  # new_pos = 9

    The function makes sure that the returned value never overshoots:

    .. sourcecode:: Python

        new_pos = linear(10, -20, 10, 100)  # new_pos = -20

    :param current: The current value of the variable to be changed.
    :param target: The target value to approach.
    :param rate: The rate at which the parameter should move towards target.
    :param dt: The time for which to calculate the change.
    :return: The new variable value.
    """
    sign = (target > current) - (target < current)
    if not sign:
        return current
    new_value = current + sign * rate * dt
    if sign * new_value > sign * target:
        return target
    return new_value
