Home     |     .Net Programming    |     cSharp Home    |     Sql Server Home    |     Javascript / Client Side Development     |     Ajax Programming

Ruby on Rails Development     |     Perl Programming     |     C Programming Language     |     C++ Programming     |     IT Jobs

Python Programming Language     |     Laptop Suggestions?    |     TCL Scripting     |     Fortran Programming     |     Scheme Programming Language


 
 
Cervo Technologies
The Right Source to Outsource

MS Dynamics CRM 3.0

Fortran Programming Language

generic routines, to what end?


I make a good deal of use of "records," defined types consolidating
the data spectific to some entity.  Typically for record types foo and
bar, I will have a foo module and a bar module, defining the
respective types and supplying the subroutines necessary to process
them.  Often, the routines that I write to process different types of
records are almost identical across record types; they will often
differ only in the definition section, where one will will say
"TYPE(foo),INTENT(in) :: rec", and another will say
"TYPE(bar),INTENT(in) :: rec", and otherwise the code will be
identical.

To process records, say, confabulate them, I will often have
subroutines foo_confabulate and bar_confabulate defined in the
respective modules, and I will define a generic interface with this in
the foo module:

INTERFACE confabulate
   MODULE PROCEDURE foo_confabulate
END INTERFACE

and the analogous in the bar module.  That way in code that uses these
modules, I can just go "CALL confabulate(foo_rec)" or "CALL
confabulate(bar_rec)".

But it seems to me that Fortran's generic interface facility is almost
a complete waste of time!  I still need to maintain multiple sets of
almost identical code, and to endure the consequent pain of having to
ensure that any modifications I make are identical as well.  And why
even bother to define the interface, since I always know whether I
want to call foo_confabulate or bar_confabultate, and could call each
directly?

I suppose I can see the advantages of generic routines from the point
of view of an eventual consumer of a library that employs them, but I
can see no advantages for anyone who is already familiar with the
source code.

Most particularly I wish it were possible to write exactly one
subroutine and somehow specifiy that it might be called with records
of type foo or type bar. (Obviously if this accessed record
components, the components accessed would have to be defined on each
type of record.)  Then at compile time, this could be translated into
two different incarnations, saving me the trouble of maintaining
multiple source codes.

I am somewhat new to Fortran 90/95, so perhaps this indeed is
possible?  Or something, at any rate, that saves having to maintain
several essentially identical routines?

On 3 mei, 15:09, Mark Morss <mfmo@aep.com> wrote:

You can achieve this (or something very similar) in Fortran 2003.

For Fortran 90/95 the solution might be:
- Use INCLUDE to copy identical pieces of code into the source at
compile-time
- Define a single record type holding the identical pieces and use
specific
  record types to hold the general information and specific
information
  (i.e. aggregation)

Something like:

type general
    ... all general stuff
end type general

type recordA
   int :: A
   type(general) :: general_stuff
end type recordA

And subroutines/functions according to a pattern like this:

subroutine print_A( rca )
    type(recordA) :: rca
    write(*,*) 'RecordA:'
    write(*,*) '    A = ',rca%a
    call print_general( rca%general_stuff )
end subroutine print_A

Regards,

Arjen

On May 3, 9:09 am, Mark Morss <mfmo@aep.com> wrote:

<snip>

> But it seems to me that Fortran's generic interface facility is almost
> a complete waste of time!  I still need to maintain multiple sets of
> almost identical code, and to endure the consequent pain of having to
> ensure that any modifications I make are identical as well.  And why
> even bother to define the interface, since I always know whether I
> want to call foo_confabulate or bar_confabultate, and could call each
> directly?

Fortran, unlike C++, does not have templates.

I have not tried it, but I think the Forpedo http://www.macanics.net/forpedo/index.php
preprocessor for Fortran 90 code by Drew McCormack is designed to fill
this gap in Fortran.

"Forpedo is a preprocessor for Fortran 90 code, written in Python. It
can handle some typical preprocessing tasks, like including code from
one file in another, but it is mostly designed to provide advanced
techniques to pre-Fortran 2003 versions of the language. In
particular, there is support for C++ like generics (templates), and
run-time polymorphism from Object-Oriented Programming (OOP) (click
here for more details on OOP in Fortran)."

On May 3, 9:24 am, Arjen Markus <arjen.mar@wldelft.nl> wrote:

I have the latest IBM compiler for my system, AIX, but apparently it
doesn't implement Fortran 2003.  Thanks for those other ideas.
On May 3, 10:02 am, Beliavsky <beliav@aol.com> wrote:

Thanks.  I have Python on this machine, so that is definitely an
option.
On May 3, 3:09 pm, Mark Morss <mfmo@aep.com> wrote:

Fortran 95 does not have templating and F2003 takes only a tiny step
in that direction with parameterized types. Templating means
generating many procedures from single code block - something
different from object polymorphism supported in F2003.
F95 generic interfaces actually are all the genericity the user of a
library needs (corresponds to overloading in C++).
Templating can be achieved only externally, via various macro
processors.
Others have mentioned Forpedo; I have a good experience with combining
m4 with Fortran. In Unix-like environments, m4 is almost always
present.
I have also written a Vim plugin for doing simple Fortran templating
directly inside the editor.
Personally, I'm not convinced that templating should be a part of the
language. IMHO the only (yet big) advantage of C++ templates over
using a macro processor is implicit instantiation. There is a number
of disadvantages on the other hand.
F2008 may contain "smart macros", which would provide a powerful macro
processor inside the language; however, it cannot do implicit
instantiation.
In article <1178197743.398867.266@p77g2000hsh.googlegroups.com>,
 Mark Morss <mfmo@aep.com> wrote:

> I still need to maintain multiple sets of
> almost identical code, and to endure the consequent pain of having to
> ensure that any modifications I make are identical as well.

I think it was pointed out a few posts back that the closest to this
that you can do in f90 or f95 is with the INCLUDE statement.  The
shared code is placed in a separate file, and included into the
various specific routines.  The specific routines must have the
appropriate declarations (which themselves may be parameterized with
KIND values), but there is then only one file that has the actual
code in it.  For example, you can imagine code that defines a single
parameter to define the real kind, then then uses the INCLUDE
statement to bring in the whole subprogram, declarations and
everything.

This works well in those cases where the code really doesn't change
from one routine to the next.  However, in many cases the code does
need to change, a little or a lot, depending on the KINDS.  For
example, a single precision routine might use a table of 10 values
to do something (a gaussian quadrature, for example), while the
double precision version might need a table of 20 values.  In these
cases you are faced with writing clever obscure code that abstracts
these differences enough so that it can be shared, or writing simple
obvious code that is almost the same.

There are preprocessors that can do this too.  I use filepp which is
a perl script (see google for the web site).  You basically define a
loop, and each pass through the loop outputs a new version of the
subprogram.  The subroutine name must be a macro that is changed
each pass through the loop.  This is a little more flexible than a
simple INCLUDE statement because you can further define conditional
code that changes each pass through the loop.  But, as I said above,
this is sometimes too clever and obscure to be maintained by more
than one person or even by a single person over time.

$.02 -Ron Shepard

Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc