- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have been doing a great deal of proof-of-concept work in MS Excel with VBA macros. The idea is to get these macros/algorithms working on a spreadsheet and then transfer them without too much change to Fortran.
The current problem lies with form. I have created a module which makes use of three class modules in VBA. The class module A is a solver, as in it has algorithms for solving equations. Class module B is a function base class with function prototypes for use by the solver. Class module C is an override of B which has the actual implementation of function(s)/subroutine(s) for the solver.
I call class A with reference to class C, and the solver thus knows which functions and subroutines to use for the solving. I would like to use something equivalent on the Fortran side, but am unsure of the constructs. I need to be able to let the Fortran module A have functions and subroutines outside of the module which it can access with the names not being hard-wired. I recognize Fortran 2003 has this capability, but I am unaware of the particulars.
Is there a forum topic or a book/web-site which may give me a clue as to how to implement this?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you. I have "Modern Fortran Explained" by Metcalf, Reid and Cohen. I am having a bit of trouble understanding procedure pointers and the like. I am assuming this is what I need but have as yet to determine this. I have not yet devised the actual algorithms needed to solve the problem at hand, so there remain many problems that still require my inspiration and perspiration.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, I think you'd do this with type-bound procedures, type extension and procedure overriding. Procedure pointers would not likely enter into it, though I suppose they could.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The terminology is causing me some grief. I have programmed in OOP, and am familiar with the terms superclass/subclass and the like.
I would assume when you are saying "type-bound procedures" and "type extension" and "procedure overriding" you are speaking of a superclass (base class) being extended by a subclass (child class) with the overridden procedures being in the type extension. Again, this all became utterly confused when I discovered the Fortran 2003 keyword "class".
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Terminology does vary, but your assumptions are basically correct.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have begun the coding of this subtlety in Fortran 2003. Let me quote the code which is not compiling:
module FuncBase_Module
use PRECISION_SPECIFICATION
implicit none
type FuncBase
contains
procedure :: Func
procedure :: FuncV
procedure :: MaximumStep
procedure :: CheckDirection
procedure :: FDJAC
end type FuncBase
contains
REAL (KIND = F) Function Func(X)
REAL (KIND = F), INTENT(IN) :: X
Func = 0.0_F
End Function Func
...
The compiler complains bitterly "error #8262: For a type-bound procedure that has the PASS binding attribute, the first dummy argument must have the same declared type as the type being defined.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When you have a type-bound procedure - that is, a procedure named after the CONTAINS in a type - the default is that the first argument to the routine is the derived type variable you used for the reference. So let's say you had a variable of type FuncBase named Z. If you call Z%Func(), there is an implicit first argument to Func of Z. That means you have to declare Func as having a first argument of TYPE(FuncBase) (or CLASS(FuncBase)). If you don't want that, you can add NOPASS to the procedure declaration in the type, but then you lose some of the object-orientedness of it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you Steve. I noted that when reading the examples roughly five minutes after posting. I have now rigged a "this" argument to the beginning of each argument list, being declared as
class(FuncBase)
and everything is compiling okay aside from warnings about routines where arguments are not used. In essence I am trying to build prototypes for the subclasses which would actively implement those routines. I am assuming this is the way to implement.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, that's right.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve,
Do you know why the Fortran standards committee did not choose to make the "this" arg implicit? (like most other OO languages)
The compiler can currently disambiguate name spaces in a hierarchy (ASSOCIATE, procedure, USE, COMMON). Then why not extend to member of type/class?
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I wasn't on the committee in the F2003 timeframe. Remember that the actual function is just an ordinary function that can be called directly. The compiler has no idea about implicit arguments and can be external. You can say NOPASS in the type and get no "this" argument and you can put that argument elsewhere in the argument list if you like.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
jimdempseyatthecove wrote:
Steve,
Do you know why the Fortran standards committee did not choose to make the "this" arg implicit? (like most other OO languages)
The compiler can currently disambiguate name spaces in a hierarchy (ASSOCIATE, procedure, USE, COMMON). Then why not extend to member of type/class?
Jim Dempsey
I was on the Fortran Standard Committee from November 1993 through November 2002. This included all of the time that the OOP features were developed and implemented. Malcolm Cohen of the Numerical Algorithms Group (NAG) headed up the design of the OOP features.
My memory is not complete, but the general approach of designing any new features in Fortran is to make them as upwardly compatible with existing features as possible. This includes not only syntax and semantics but the general mental model as well. Up until the time of OOP, the standard required that all procedure arguments be explicit. If a type-bound procedure (TBP) had an implicit argument, this would have been a discontinuity in the mental model.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Craig,
Thanks for your input. Maybe you can answer this backwardsly compatible situation:
module FooBar
integer :: someVar
end module FooBar
...
subroutine FooFoo
USE FooBar
...
someVar = 1234 ! someVar is in scope and thus requires no decoration or required dummy
The contains functions/subroutines could have easily extended upon the USE... scoping rules for accessing member variables. Procedure contained functions/subroutines do this.
BTW you do realize that the scoping rules are applied to the contains functions/subroutines ("member functions") themselves.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
jimdempseyatthecove wrote:
Do you know why the Fortran standards committee did not choose to make the "this" arg implicit? (like most other OO languages)
Yesterday afternoon I posted Jim Dempsey's question on the Fortran Standards Committee's mailing list. Yesterday evening Malcolm Cohen provided the following answer.
[Begin Malcolm Cohen answer]
Yes.
1. As noted in the question itself, not all other OO languages have an implicit "this" arg.
2. Like other OO languages, the "this" arg is implicit at the call site - it is only in the procedure that it is not implicit.
3. At the time, the following (already noted by others) were indeed factors in the decision:
(a) making "this" a reserved variable name would be a complete nonstarter as far as Fortran is concerned since we do not have reserved keywords at all;
(b) it is nice to be able to call it what you like;
(c) it is desirable to be able to specify other attributes;
(d) it enables use of the same procedure for multiple types when appropriate.
I would say that (a) and (b) were more significant than (c) or (d).
4. It enables use of ordinary procedures to implement these, instead of having to invent some kind of new "magic" procedure with special syntax. We already have enough different kinds of procedures...
5. It enables implicit object passing for a non-initial argument, giving us type-bound operators and assignment where the derived type in question is the second operand. Yes you can define all your overloading outside the type using INTERFACE blocks, but then type-bound assignment is especially important for avoiding the accidental loss of defined assignment that is possible with INTERFACE ASSIGNMENT(=) and careless use of the ONLY clause on a USE statement.
6. In my opinion, the overhead of having to declare the passed-object dummy is totally insignificant compared with the clarity it gives. The procedure is just a normal procedure following the normal rules and the passed-object dummy is (inside the procedure) just a normal dummy argument. Nothing complicated to get confused by.
There are certainly design decisions in F2003 that I regret, but this is not one of them.
[End of Malcolm Cohen answer]
Hope this helps.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This is extremely helpful - Thank you much, Craig.
I agree with the overall assessment: I find Fortran 2003 design on this OO aspect consistent with the base language construct while also being quite flexible - great job by the standards creators, especially considering all the constraints and differing opinions that they would have encountered.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Okay, now that I "have" a class structure, I am having trouble "using" it. I attempt to run the code, and get the nebulous "Program Exception, Access Violation" error. According to the traceback, the error occurs with a call to
Call FP%Set_WellData(N, WELL_SET)
Routine
Set_WellData
is of
type(FuncBase)
where the object
FP
is of
type(FuncPressure)
.
type, extends(FuncBase) :: FuncPressure
I am confused by the error.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
NotThatItMatters wrote:
Okay, now that I "have" a class structure, I am having trouble "using" it. I attempt to run the code, and get the nebulous "Program Exception, Access Violation" error. According to the traceback, the error occurs with a call to
Call FP%Set_WellData(N, WELL_SET)
Routine
Set_WellData
is of
type(FuncBase)
where the object
FP
is of
type(FuncPressure)
.
type, extends(FuncBase) :: FuncPressure
I am confused by the error.
Perhaps others can make more sense out of this error, but I would need a lot more detail to figure out what is going on. I use type-bound procedures ("class structures" as you call them) extensively and I've never come across such an error.
Can you post your complete code, or if you cannot do that, then create a simple, generic example that reproduces the problem?
If you can't provide reproducible code, then refer to Dr. Fortran's blog on many books that give example code for type-bound procedures - try to use these examples and see if you can get them to work. You can then adapt these examples to your situation.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Perhaps it is best if I could explain what I did to FIX it. This might seem insanely obvious, but I am only learning Fortran OOP at present. The problem lies between the declaration
type (FuncPressure) :: FP
and the declaration
class (FuncPressure), pointer :: FP
If I were in another language, I would assume the second declaration does not instantiate anything whereas the first does. Well, guess what, this is how Fortran works. I just had seen so many examples which used the class pointer that I was blinded to the underlying idea.
I am sorry for wasting your time.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, CLASS has a specific meaning in Fortran in relation to a polymorphic type. It is not to be confused with class terminology used in other OO languages such as Java or Microsoft's .NET languages such as C#, Visual Basic, etc.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page