From: fj on
On 25 fév, 19:30, Dave Allured <nos...(a)nospom.com> wrote:
> Richard Maine wrote:
>
> > Dave Allured <nos...(a)nospom.com> wrote:
> > > What is the best way to add a module interface to a predefined external
> > > procedure, without changing the name of the procedure?
>
> > and later added:
>
> > > Expanding on yours, would this work, or what else would be needed?
>
> > > module mod1
> > >   interface
> > >     integer function vincent (x)
> > >        real, intent(in) :: x
> > >     end function vincent
> > >   end interface
> > > end module mod1
>
> > Yes. I'd have given basically the same answer as Jim, except with a
> > different emphasis. He seemed to be emphasizing the name mangling
> > issues, whereas I thought you were more talking about the explicit
> > interface issues. So I'll elaborate slightly on the explicit interafce
> > aspect.
>
> > I think that the term you are looking for is "explicit interface".
> > That's the general term for the property that allows various kinds of
> > argument checking, along with lots of other features new as of f90.
> > Module procedures do always have explicit interfaces, but that's not the
> > only way to have an explicit interface.
>
> > Yes, the way to get an explicit interface for an external procedure is
> > to write an interface body for it. Jim showed just the most trivial case
> > of an interface body - a subroutine with no arguments (probably because
> > that's what your original example showed). But the princinple applies to
> > any interface. Not only can you add the information about argument and
> > function return characteristics, you *MUST* do so. Your interface body
> > is required to agree with the actual procedure. You will not in general
> > get compile-time checking of that agreement; you have to get that part
> > right yourself. (There might be compilers that can do such checking, but
> > it isn't something that you can count on in general). But once you have
> > the interface body written, the compiler will check that the calls are
> > compatible with that interface.
>
> > You can put an interface block with its interface body directly in each
> > procedure that calls the external, possibly using an include file so
> > that you only have top get it right once. The other option is to put the
> > interface block in a module, as in the example above. Then you just USE
> > the module like any other (and you can take advantage of the rename
> > feature of USE, if that's part of what you want, though I didn't read
> > your question that way; I thought that you more wanted to avoid
> > renaming).
>
> Great, this will work fine for my purposes.  I really did mean to use
> the term "module interface" because I want the end product to appear as
> a single opaque module to application programs.  I am trying to wrap a
> third party library package in a module, replacing an include file with
> a module interface, to improve interface checking.
>
> I have a couple more questions.  Consider this:
>
module mod1
  integer, parameter :: XX_KIND = 4
  interface
    subroutine sub1 (arg1)
      character(*), intent(in) :: arg1
    end subroutine sub1

    function func2 (arg2) RESULT(r)
import xx_kind
      integer arg2
integer(xx_arg) :: r
    end function func2
  end interface
end module mod1

The import statement of F2003 is for that purpose

From: fj on
On 25 fév, 19:30, Dave Allured <nos...(a)nospom.com> wrote:
> Richard Maine wrote:
>
> > Dave Allured <nos...(a)nospom.com> wrote:
> > > What is the best way to add a module interface to a predefined external
> > > procedure, without changing the name of the procedure?
>
> > and later added:
>
> > > Expanding on yours, would this work, or what else would be needed?
>
> > > module mod1
> > >   interface
> > >     integer function vincent (x)
> > >        real, intent(in) :: x
> > >     end function vincent
> > >   end interface
> > > end module mod1
>
> > Yes. I'd have given basically the same answer as Jim, except with a
> > different emphasis. He seemed to be emphasizing the name mangling
> > issues, whereas I thought you were more talking about the explicit
> > interface issues. So I'll elaborate slightly on the explicit interafce
> > aspect.
>
> > I think that the term you are looking for is "explicit interface".
> > That's the general term for the property that allows various kinds of
> > argument checking, along with lots of other features new as of f90.
> > Module procedures do always have explicit interfaces, but that's not the
> > only way to have an explicit interface.
>
> > Yes, the way to get an explicit interface for an external procedure is
> > to write an interface body for it. Jim showed just the most trivial case
> > of an interface body - a subroutine with no arguments (probably because
> > that's what your original example showed). But the princinple applies to
> > any interface. Not only can you add the information about argument and
> > function return characteristics, you *MUST* do so. Your interface body
> > is required to agree with the actual procedure. You will not in general
> > get compile-time checking of that agreement; you have to get that part
> > right yourself. (There might be compilers that can do such checking, but
> > it isn't something that you can count on in general). But once you have
> > the interface body written, the compiler will check that the calls are
> > compatible with that interface.
>
> > You can put an interface block with its interface body directly in each
> > procedure that calls the external, possibly using an include file so
> > that you only have top get it right once. The other option is to put the
> > interface block in a module, as in the example above. Then you just USE
> > the module like any other (and you can take advantage of the rename
> > feature of USE, if that's part of what you want, though I didn't read
> > your question that way; I thought that you more wanted to avoid
> > renaming).
>
> Great, this will work fine for my purposes.  I really did mean to use
> the term "module interface" because I want the end product to appear as
> a single opaque module to application programs.  I am trying to wrap a
> third party library package in a module, replacing an include file with
> a module interface, to improve interface checking.
>
> I have a couple more questions.  Consider this:
>
> module mod1
>   integer, parameter :: XX_KIND = 4
>
>   interface
>     subroutine sub1 (arg1)
>       character(*), intent(in) :: arg1
>     end subroutine sub1
>
>     integer(XX_KIND) function func2 (arg2)
>       integer arg2
>     end function func2
>   end interface
> end module mod1
>
> 1.  What is the best way to make the kind definition of XX_KIND
> available to the function statement for func2?  Above does not seem to
> work.  I am reluctant to hard code "4" into each function statement.
>
> 2.  Is it okay to use a single unnamed interface block to contain all of
> my procedure interfaces, as shown?  Or does each interface need its own
> interface block?  These are all 1 for 1 interfaces, no generic
> interfaces.

Yes it is OK ! And notice that an interface with a name is very
different to an interface without name.

With a name you declare a generic interface, i.e. a single name for
several subroutines, all the subroutines having different signatures
(constraint).

Without name, you just declare an explicit interface for each routine
in the interface block. No constraint about these routines ...

I would have preferred a different keyword, for instance GENERIC
instead of INTERFACE, to declare a generic interface.

From: Richard Maine on
fj <francois.jacq(a)irsn.fr> wrote:

> On 25 f�v, 19:30, Dave Allured <nos...(a)nospom.com> wrote:

> > module mod1
> > integer, parameter :: XX_KIND = 4
> >
> > interface
> > subroutine sub1 (arg1)
> > character(*), intent(in) :: arg1
> > end subroutine sub1
> >
> > integer(XX_KIND) function func2 (arg2)
> > integer arg2
> > end function func2
> > end interface
> > end module mod1
> >
> > 1. What is the best way to make the kind definition of XX_KIND
> > available to the function statement for func2?

As fj noted in his other post, that's what the f203 import statement is
for. If you don't want to count on availability of an f2003 feature
(though admitedly a pretty simple one), the f90/f95 approach is to put
the parameter definition in a separate module, which you can then USE in
the interface bodies. There really wasn't any other way to do it in
f90/f95. (And there were cases where that wouldn't work either, but you
aren't in that area.)

> > 2. Is it okay to use a single unnamed interface block to contain all of
> > my procedure interfaces, as shown? Or does each interface need its own
> > interface block? These are all 1 for 1 interfaces, no generic
> > interfaces.
>
> Yes it is OK ! And notice that an interface with a name is very
> different to an interface without name.
....
> I would have preferred a different keyword, for instance GENERIC
> instead of INTERFACE, to declare a generic interface.

Me too. Looks to me like someone was trying to simplify the combined
case where you both wanted to have several interface bodies and also
declare a generic based on them. But I think the result causes far more
confusion than the few lines of code it saves in some cases.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
From: Richard Maine on
Dave Allured <nospom(a)nospom.com> wrote:

> Richard Maine wrote:

> > I think that the term you are looking for is "explicit interface".
> > That's the general term for the property that allows various kinds of
> > argument checking, along with lots of other features new as of f90.
> > Module procedures do always have explicit interfaces, but that's not the
> > only way to have an explicit interface.

> Great, this will work fine for my purposes. I really did mean to use
> the term "module interface" because I want the end product to appear as
> a single opaque module to application programs.

I'm still not quite sure precisely what you mean by that. This leaves me
unsure of whether you would be achieving what you think. Having an
explicit interface achieves many things. There isn't much more that
being in a module achieves, and some of that remainder you don't get by
putting an interface body for an external procedure in a module.

1. You can use the rename feature of USE. That you do get, but its about
the only concrete thing I can think of.

2. You do *NOT* get the privacy and opacity features of module
procedures. In particular, you don't get the protection against the
external procedure being accessed without a USE at all. It is still an
external procedure. That means that if someone attempts to access it
without the USE statement, they will still get it, albeit without the
explicit interface. If that's what you were after, there is no way to
achieve that without actually putting the procedure in a module.

3. Because the procedure is still actually an external procedure instead
of a module procedure, an obscure limitation of f90/f95 applies. You
cannot use it in a module procedure statement (in a generic interface
block). His in turn has odd secondary effects, such as making it tricky
if you want the same procedure to be a specific in multiple generics.
F2003 removed this misfeature by removing the keyword "module" from the
module procedure statement, along with removing the requirement that
only module procedures be used. (The f90/f95 form remains as an option
for compatibility, but I can't imagine any other reason to use it).

4. I suppose there is one extra-language aspect - that it could be handy
from a documentation perspective to describe it as part of the module.
That you mostly get, but not with 100% opacity. Items 2 and 3 above are
not opaque. They are a bit arcane (at least item 3), but are the kinds
of things that can generate bug reports if you try to ignore them in
your documentation.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
From: Dave Allured on
Richard Maine wrote:
>
> Dave Allured <nospom(a)nospom.com> wrote:
>
> > Richard Maine wrote:
>
> > > I think that the term you are looking for is "explicit interface".
> > > That's the general term for the property that allows various kinds of
> > > argument checking, along with lots of other features new as of f90.
> > > Module procedures do always have explicit interfaces, but that's not the
> > > only way to have an explicit interface.
>
> > Great, this will work fine for my purposes. I really did mean to use
> > the term "module interface" because I want the end product to appear as
> > a single opaque module to application programs.
>
> I'm still not quite sure precisely what you mean by that. This leaves me
> unsure of whether you would be achieving what you think. Having an
> explicit interface achieves many things. There isn't much more that
> being in a module achieves, and some of that remainder you don't get by
> putting an interface body for an external procedure in a module.
>
> 1. You can use the rename feature of USE. That you do get, but its about
> the only concrete thing I can think of.
>
> 2. You do *NOT* get the privacy and opacity features of module
> procedures. In particular, you don't get the protection against the
> external procedure being accessed without a USE at all. It is still an
> external procedure. That means that if someone attempts to access it
> without the USE statement, they will still get it, albeit without the
> explicit interface. If that's what you were after, there is no way to
> achieve that without actually putting the procedure in a module.
>
> 3. Because the procedure is still actually an external procedure instead
> of a module procedure, an obscure limitation of f90/f95 applies. You
> cannot use it in a module procedure statement (in a generic interface
> block). His in turn has odd secondary effects, such as making it tricky
> if you want the same procedure to be a specific in multiple generics.
> F2003 removed this misfeature by removing the keyword "module" from the
> module procedure statement, along with removing the requirement that
> only module procedures be used. (The f90/f95 form remains as an option
> for compatibility, but I can't imagine any other reason to use it).
>
> 4. I suppose there is one extra-language aspect - that it could be handy
> from a documentation perspective to describe it as part of the module.
> That you mostly get, but not with 100% opacity. Items 2 and 3 above are
> not opaque. They are a bit arcane (at least item 3), but are the kinds
> of things that can generate bug reports if you try to ignore them in
> your documentation.

Richard, those are all good points. This is a terminology problem. I
coined the term "module interface" as a shortcut, thinking that it would
be universally understood. What I meant was adding a module-like
wrapper or encapsulation around an older fortran library which includes
external subroutines, external functions, and numeric constants.
Objectives are better interface checking and eliminating preprocessor
kludges. I imagine that this must be a regular occurrence in the world
of public software.

In short, I wanted to add some interface blocks and call it a module,
albeit imperfect as per (2) and (3). Do you have a concise term for
such an encapsulation?

--Dave