Best way to implement function currying

Currying in the LISP sense is not possible - Fortran does not allow you to construct functions. (Well, you can work around that limitation in a certain way (*))

The example code you show is quite close to what you can achieve. Maybe define a generic interface, so that mult can take either one or two arguments, so that you effectively hide the currying step.

Module variables are indeed not thread-safe, but that is actually beyond the Fortran standard. Such variables are accessible from any routine that uses the module. You could consider using coarrays if this is an important issue for you (or OpenMP/MPI as alternative multithreading paradigms).

What you can also do is use an object-oriented approach: a derived type holding the factor and the functions:

! curry.f90 --
!     Illustrate currying with an OO approach
!
module currying
    implicit none

    type :: function_t
        real :: factor
    contains
        procedure :: mult_xy => mult_x_y
        procedure :: mult_x =>  mult_x_factor
        generic   :: mult => mult_xy, mult_x
    end type

contains
real function mult_x_y( this, x, y )
    class(function_t) :: this
    real, intent(in) :: x, y

    mult_x_y = x * y
end function mult_x_y

real function mult_x_factor( this, x )
    class(function_t) :: this
    real, intent(in) :: x

    mult_x_factor = x * this%factor
end function mult_x_factor
end module currying

program test_currying
    use currying

    type(function_t) :: f

    f%factor = 2.0  ! Lazy, should provide init_currying

    write(*,*) f%mult(3.0, 2.0)
    write(*,*) f%mult(3.0)
end program test_currying

Regards,

Arjen

(*) Constructing “functions” on the fly a be done - I have illustrated that in my 2012 book Modern Fortran in practice. Whether it is a useful technique in your case, is, however, an open question.