- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
As in my mind, type bound procedure with NOPASS attribute, the method is a static method, and can be referred to using the name of the class prototype. Otherwise, with PASS attribute the method is an instance method, and is referred to using the name of the particular instance of the class.
In intel fortran, it seems not support the using of class prototype to invoke nopass procedure. We must define or allocate a instance to call PASS or NOPASS procedures.
Before an allocatable derived type variable is allocated, its nopass procedure can be called correctly if no runtime check of null pointer and allocatable array references. Is it a advisable way to do that kind of things?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think the inappropriate mapping of terminology from other languages (and perhaps a requirement to fit in the .NET framework, in Lahey's case) onto Fortran is what initially lead things astray here.
This is more than a bit subjective, but my view is that in the design of standard Fortran, the syntax `object%binding(...)` is principally about runtime dispatch to a particular procedure based on the dynamic type of the object. There are some namespace nicety aspects to that syntax as well, but they are secondary to that dynamic dispatch capability.
That dynamic dispatch capability applies regardless of whether the binding is PASS or NOPASS - those attributes are more just conveniences to arrange the call for the underlying procedure interface.
To do dynamic dispatch based on dynamic type of an object - you need to have a valid object.
The concept "static method of a class" has nothing to do with dynamic dispatch. The subject type is known at compile time, hence the subject procedure is known. Putting accessibility aside for a moment, then to invoke that procedure... you just invoke it by its name.
That `object%binding` is principally about dynamic dispatch also arises with the common question "how do I call the procedure referenced by a binding in the abstract parent of a type - the compiler won't let me do object%parent%binding(...)". Again, the parent type of a particular type is fixed, hence the procedure that the binding of an object of the parent type will reference is fixed, hence there's no need to do dynamic dispatch - accessibility aside you just invoke the procedure by its name.
The `object%binding(...)` syntax can obviously be used in cases where the dispatch can be statically determined (say if the object is not polymorphic), but I think from a conceptual point of view this capability in the language should almost be regarded as inadvertent, rather than the principal design intent of the syntax.
(Practically, if there's a passed object then there will also, typically, be the need to construct a polymorphic descriptor or similar for the passed object too, which may have performance implications as mentioned above. I interpret the inability to avoid the construction of this descriptor, in a language that has performance as an important design criteria, as further evidence around design intent.)
From the point of view of the way the language handles accessibility aspects, accessibility in Fortran is based around modules, not around types. Further, unlike other languages, procedures don't belong to types - procedures are instead referenced by bindings in types. It is quite possible for the one procedure to be referenced by bindings in completely unrelated types.
Consequently, Fortran doesn't have an identical equivalent to a "static method of a class". The closest approximation isn't a NOPASS binding, it is simply an accessible procedure from the same module that defined the type.
The above isn't a justification of the language design, it is just a description of the philosophy and concepts that I interpret, retrospectively, to have informed the design.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Perhaps you can further elaborate on your question with concrete examples because your questions and concerns are not fully clear to me. As you would know well, type-bound procedures and their uses are intended to facilitate object-oriented programming (OOP) and as the vast body of literature on object-oriented techniques show, proper analysis and design are crucial [one example, structure of arrays (SoA) vs array of structures (AoS)] for efficient implementation. Almost all the established "good practices" for OOA, OOD, and OOP would largely extend to Fortran as well, so you may want to review OO literature closely, if general efficiency of OO implementations is what you're asking about. When it comes specifically to Fortran, books mentioned by Dr Fortran in his blog can be useful.
On some of your points about procedures with NOPASS and PASS attributes, note the snippet below shows several allowed uses for them in the standard but as to whether they are appropriate and efficient for your needs is something you would know best given your code as well as your OO analysis and design on the program. Some seem to think the polymorphic requirement with the PASS attribute of type-bound procedures incurs some performance penalty and prefer traditional procedure invocations where the dummy argument of the type is not polymorphic (TYPE vs CLASS); I prefer otherwise.
module m implicit none private type, public :: t private integer :: m_i = 42 contains private procedure, nopass, public :: sub procedure, pass(this), public :: i end type t public :: sub public :: i contains subroutine sub() print *, " from sub: hello world!" return end subroutine sub function i(this) result(ival) class(t), intent(in) :: this !.. function result integer :: ival ival = this%m_i return end function i end module m
program p use m, only : t, sub, i implicit none type(t) :: foo call sub() print *, " in main - i(foo) returns ", i(foo) print *, " in main - foo%i() returns ", foo%i() call foo%sub() stop end program p
from sub: hello world! in main - i(foo) returns 42 in main - foo%i() returns 42 from sub: hello world!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'll also comment that Intel Fortran supports what the Fortran standard specifies. We don't go adding features in this area.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve should know what I want to ask about, and I quite understand Steve about not adding extra features in oop.
In Mr. FortranFan's example, sub is a nopass procedure which make it seems to be a static method. What i want to know is how to call sub without a type instant while sub is a public procedure and a private subroutine.
In some situations, we may want to call a static method before a instant is allocated.
take following code as example:
type(t), allocatable :: foo call foo % sub
if set nocheck pointer compile option, above code works well. is it a advisable way?
In some other fortran compiler, it can be write like:
call t % sub
which is not allowed by IVF. So I want to know if there is a safe way to do so, or it is absolutely not adviced to do so in this way in IVF. Of course it does not mean that i trend to encourage IVF to support extra features in addition to fortran standard.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
How about defining a parameter of that type instead of a variable? The parameter could be given a name that makes clear what its purpose in life is and you avoid tricks with compiler options that may actually be very useful for checking the rest of the program.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Actually, I am not certain what you are asking. Please provide a short but complete example that works in some other compiler but not in Intel Fortran. You also mentioned /check:pointer - we have had bugs in that regard so perhaps that's related.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sorry for my poor language ability. perhaps computer language will help to make more clear.
Codes in last article follows FortranFan's example. Here I give a independent version.
In some situations, there may be a reqiure to call procedures before a instant is allocated. Of couse it is not essential, and can be realized by many other ways.
What I want to know is : is it rational in IVF? Or it should be avoided?
module m implicit none type :: typ_Exmp contains procedure, nopass :: static_method procedure, pass :: instance_method end type typ_Exmp contains subroutine static_method (arg) integer :: arg end subroutine subroutine instance_method ( this, arg ) class (typ_Exmp) :: this integer :: arg end subroutine end module program oop_test use m type(typ_exmp), allocatable :: exmp type(typ_exmp) :: exmp_instance integer i call exmp % static_method (i) !it works. But with option check:pointer, get a runtime error. call exmp_instance % instance_method (i) !it works, of course. which is comply with standard call typ_exmp % static_method (i) !compile error, of course it is not supported. !Some compiler extend extra features support that, for example Lahey Fortran. !It does not mean that I trend to appeal IVF to support extra features in addition to standard.
end program
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the example.
The call to exmp%static_method violates the following rule in the standard: "The data-ref in a procedure-designator shall not be an unallocated allocatable variable or a pointer that is not associated." (F2008 12.5.1p2)
The call to typ_exmp%static_method, as you say, is non-standard. Which Lahey Fortran supports this? The old Fujitsu one or the gfortran one? That's an unfortunate extension as one can do this:
type(some_other_type) :: typ_exmp
Now when you call typ_exmp%static_method, which one do you mean?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Since the typ_exmp variable is not polymorphic there is no decision to make. This potential "new feature" would need such a limitation.
It would be nice to have static parameter variables accessible in this way too (asumming it was made legal to declare them).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can have parameters of a derived type and call static methods via them:
module param type myclass integer :: x contains procedure, public, nopass :: check end type type(myclass), parameter :: px = myclass(1) contains subroutine check write(*,*) 'Check' end subroutine check end module param program test_param use param call px%check end program test_param
Unless I misunderstand what you mean ;)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Why not prefix your static methods of a type with the type name
module m implicit none type :: typ_Exmp contains procedure, nopass :: typ_Exmp__static_method procedure, pass :: instance_method end type typ_Exmp contains subroutine typ_Exmp__static_method (arg) integer :: arg end subroutine subroutine instance_method ( this, arg ) class (typ_Exmp) :: this integer :: arg end subroutine end module program oop_test use m type(typ_exmp), allocatable :: exmp type(typ_exmp) :: exmp_instance integer i call exmp % typ_Exmp__static_method (i) !it works. But with option check:pointer, get a runtime error. call exmp_instance % instance_method (i) !it works, of course. which is comply with standard call typ_Exmp__static_method (i) !Some compiler extend extra features support that, for example Lahey Fortran. !It does not mean that I trend to appeal IVF to support extra features in addition to standard.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Or, without the prefix
use m, YourLocalName => static_method
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
An N. wrote:
.. Codes in last article follows FortranFan's example. Here I give a independent version.
In some situations, there may be a reqiure to call procedures before a instant is allocated. Of couse it is not essential, and can be realized by many other ways.
What I want to know is : is it rational in IVF? Or it should be avoided ..
WD 1529-1 J3/10-007r1 (November 2010) document for Fortran 2008 standard says in 2.4.9.2, "An unallocated allocatable variable shall not be referenced or defned." I'm not sure but does the standard leave it up to the processor to decide on the response when such a thing happens. Few might agree with me but I personally would read a statement on line 35 in the code snippet in Message #7 such as "call exmp%static_method(i)" to imply a reference to an unallocated allocatable variable, even though NOPASS attribute might suggest otherwise.
It seems several compilers including Lahey (don't know for sure, but I assume as much from OP's comments), Intel Fortran, and also gfortran allow and execute such code when run-time checks are not brought into play. As to whether this is "rational or to be avoided" is probably a matter of preference. By the way, what would coders expect next!? Could they then also want to be able to do "call exmp%static_method( exmp%i )" where i might be a component of the type with some default initialization?
I personally would avoid such things, but that is just my opinion. Good question though, probably worth discussing at comp.lang.fortran.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
See post #8. The standard is clear on this.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve Lionel (Intel) wrote:
See post #8. The standard is clear on this.
Steve,
In Message #8, you state, "The call to exmp%static_method violates the following rule in the standard: "The data-ref in a procedure-designator shall not be an unallocated allocatable variable or a pointer that is not associated." (F2008 12.5.1p2)." But Intel Fortran and gfortran (and perhaps Lahey compiler too) allow such usage; Intel Fortran only raises an exception at run-time if /check:pointer is in effect. So do you then envision Intel Fortran enforcing the standard on this matter only via /check:pointer option?
module m implicit none private type, public :: t private contains private procedure, nopass, public :: sub end type t contains subroutine sub() print *, " from sub: hello world!" return end subroutine sub end module m
program test use m, only : t type(t), allocatable :: foo call foo%sub() stop end program
from sub: hello world! Press any key to continue . . .
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This is a requirement on the programmer, since it is not a numbered syntax rule or constraint. The standard is full of such things. Run-time behaviors, in particular, are not required to be checked.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for all !
I fully understand it is not supported by standard. May be should be avoided by other realization.
for Steve, I have had used Lahey fortran for windows, and turned to IVF for years.
Such kind of using can be referenced on Lahey's web help:
http://www.lahey.com/docs/lfenthelp/NLMOvUsMethods.htm
http://www.lahey.com/docs/lfenthelp/NLMOvElmethods.htm
As I noticed Lahey extents OOP features much more, It does not mean that I think it is key features.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think the inappropriate mapping of terminology from other languages (and perhaps a requirement to fit in the .NET framework, in Lahey's case) onto Fortran is what initially lead things astray here.
This is more than a bit subjective, but my view is that in the design of standard Fortran, the syntax `object%binding(...)` is principally about runtime dispatch to a particular procedure based on the dynamic type of the object. There are some namespace nicety aspects to that syntax as well, but they are secondary to that dynamic dispatch capability.
That dynamic dispatch capability applies regardless of whether the binding is PASS or NOPASS - those attributes are more just conveniences to arrange the call for the underlying procedure interface.
To do dynamic dispatch based on dynamic type of an object - you need to have a valid object.
The concept "static method of a class" has nothing to do with dynamic dispatch. The subject type is known at compile time, hence the subject procedure is known. Putting accessibility aside for a moment, then to invoke that procedure... you just invoke it by its name.
That `object%binding` is principally about dynamic dispatch also arises with the common question "how do I call the procedure referenced by a binding in the abstract parent of a type - the compiler won't let me do object%parent%binding(...)". Again, the parent type of a particular type is fixed, hence the procedure that the binding of an object of the parent type will reference is fixed, hence there's no need to do dynamic dispatch - accessibility aside you just invoke the procedure by its name.
The `object%binding(...)` syntax can obviously be used in cases where the dispatch can be statically determined (say if the object is not polymorphic), but I think from a conceptual point of view this capability in the language should almost be regarded as inadvertent, rather than the principal design intent of the syntax.
(Practically, if there's a passed object then there will also, typically, be the need to construct a polymorphic descriptor or similar for the passed object too, which may have performance implications as mentioned above. I interpret the inability to avoid the construction of this descriptor, in a language that has performance as an important design criteria, as further evidence around design intent.)
From the point of view of the way the language handles accessibility aspects, accessibility in Fortran is based around modules, not around types. Further, unlike other languages, procedures don't belong to types - procedures are instead referenced by bindings in types. It is quite possible for the one procedure to be referenced by bindings in completely unrelated types.
Consequently, Fortran doesn't have an identical equivalent to a "static method of a class". The closest approximation isn't a NOPASS binding, it is simply an accessible procedure from the same module that defined the type.
The above isn't a justification of the language design, it is just a description of the philosophy and concepts that I interpret, retrospectively, to have informed the design.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page