On Thu, 2012-06-07 at 08:42 -0600, Neil Carlson wrote:
> Ondřej,
>
> You've got a long section section on callbacks and the associated
> 'type casting'. It's useful to see, in order to contrast and compare,
> the different ways it _could_ be done, but you've left out what is
> arguably the 'best' way to do this in modern Fortran.
Damian Rouson, Jim Xia, and Xiao Feng Xu have written a book entitled
"Scientific Software Design: The Object-Oriented Way. The examples are
mostly in Fortran 2003, but there are some sections also showing how
equivalent things are done in C++. The book is based on the Trilinos
framework for multi-physics simulation.
> To adapt your example of an integration method, this would look
> something like this.
>
> module integrals
>
> use types, only: dp
> implicit none
> private
>
> public :: integrand, simpson
>
> ! User extends this type
> type, abstract :: integrand
> contains
> procedure(func), deferred :: eval
> end type
>
> abstract interface
> function func(this, x) result(fx)
> import :: integrand, dp
> class(integrand) :: this
> real(dp), intent(in) :: x
> real(dp) :: fx
> end function
> end interface
>
> contains
>
> real(dp) function simpson(f, a, b) result(s)
> class(integrand) :: f
> real(dp), intent(in) :: a, b
> s = ((b-a)/6) * (f%eval(a) + 4*f%eval((a+b)/2) + f%eval(b))
> end function
>
> end module
>
> The abstract type prescribes exactly what the integration routine
> needs, namely a method to evaluate the function, but imposes nothing
> else on the user. The user extends this type, providing a concrete
> implementation of the eval type bound procedure and adding necessary
> context data as components of the extended type.
>
> Here's your usage example adapted to this better method:
>
> module example_usage
>
> use types, only: dp
> use integrals, only: integrand, simpson
> implicit none
> private
>
> public :: foo
>
> type, extends(integrand) :: my_integrand
> real(dp) :: a, k
> contains
> procedure :: eval => f
> end type
>
> contains
>
> function f(this, x) result(fx)
> class(my_integrand) :: this
> real(dp), intent(in) :: x
> real(dp) :: fx
> fx = this%a*sin(this%k*x)
> end function
>
> subroutine foo(a, k)
> real(dp) :: a, k
> type(my_integrand) :: my_f
> my_f%a = a
> my_f%k = k
> print *, simpson(my_f, 0.0_dp, 1.0_dp)
> print *, simpson(my_f, 0.0_dp, 2.0_dp)
> end subroutine
>
> end module
>
> A second general comment about the website. It would appear to present
> itself as a consensus view of the Fortran community (especially given
> the domain name.) Until that time it actually does, I'd suggest making
> it clear that you are the author and that the content really reflects
> your views on the topic. Nevertheless, I think that websites like this
> would be immensely useful to the community, and I applaud you for your
> effort.
>
> Best regards,
> Neil
>
> On Mon, 2012-06-04 at 23:08 -0700, Ondřej Čertík wrote:
> > Hi,
> >
> > I wanted to publicly announce a modern Fortran webpage that I have
> > been working on for some time:
> >
> > http://fortran90.org/
|