- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Link Copied
- « Previous
-
- 1
- 2
- Next »
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
may.ka wrote:
As an example, the automatic allocation in f08 is handy, but who knows what the compiler does if an array is copied into another array which has the attribute "allocatable" but has been allocated some zillion lines way. Maybe the compiler will just newly allocate it. In some applications this may induce a slow down which renders the program unusable. In some application one may lose pointer association status.
"Automatic allocation" was introduced in Fortran 2003.
Reallocation only happens when the right hand value does not match the shape, length parameters or dynamic type of the left handle side variable being assigned to. Code that relied on such an assignment with mismatching left and right sides working without reallocation, had a rather serious bug. It may have run faster (if it didn't crash), but it also would have been wrong.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
may.ka wrote:
.. The code snippet below implements a matrix class with two sibs, a class of squared symmetric matrices and a class of factors of squared symmetric matrices. Both are direct offspring of the parent class This is because both have different arguments for their initialization thus making the factor a child of the squared_symmetric doesn't work (without inventing procedure name extensions).
In the current implementation every type sits in its own module. This would not compile ..
Your case, as shown though, looks more like an OO design issue rather than any Fortran-specific limitations. Studying design patterns that have been used reliably in numerical modeling might help deconvolute the interdependencies with your symmetric matrix subclasses and aid in writing more stream-lined structures.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@fortranfan
please be reminded that this is just a mickey-mouse example made for your specific request from which it is impossible to make inference about the larger frame within the example is operating. Code every now and then is use to reflect real life problems, and in real life situations were y=f(x,z) and z=f(x,y) are very common. You may give an example how to handle such case in the 1 Type 1 Module world.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Reallocation only happens when the right hand value does not match the shape, length parameters or dynamic type of the left handle side variable being assigned to. Code that relied on such an assignment with mismatching left and right sides working without reallocation, had a rather serious bug. It may have run faster (if it didn't crash), but it also would have been wrong.
Thanks IanH for the clarification. Your last two sentence are written in past tense. Do you refer to pre 2003 code??
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Martin wrote:
When looking at submodules from this perspective it seems that this is a rather lame solution to these kind of problems.
Submodules are a step in the right direction. The problem is that the interface definition still has to sit in the module which can make modules very long. A nice inheritance tree can actually encompass all types/classes in a library. Thus all would have to sit in one single very very long module file (if they wanna know each other).
You mentioned the problem of "overengineering" inheritance trees, which I understand as a new subclass for every single new feature one adds to the class. This is indeed a problem because --from my current understanding-- initializers have to address all features of class not just a few. So if one would like to use them one is forced to engineer subclasses for every single new feature. Combined with the lack of multiple inheritance it is a feature which may be enjoyed by progammers with extended creativity in class naming.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
may.ka wrote:
You mentioned the problem of "overengineering" inheritance trees, which I understand as a new subclass for every single new feature one adds to the class. This is indeed a problem because --from my current understanding-- initializers have to address all features of class not just a few.
I might completely misunderstand you. But you can always call the initialiser of the parent class, even if overloaded (like call x%type_parent%init(...)). A notable exception is if type_parent is abstract, but implements init, in which case the initialiser routine needs to have a different name and overloading is not possible (for whatever reason the committee had to forbid this...). So a derived class needs to initialise only what it adds to the parent class??
Otherwise I was just generally refering to the fact that often components are more flexible and cleaner than inheritance and also the SOA vs AOS, which often forbids to abstract small units like grid points in FDM or cells in mesh based methods (e.g. to distinguish boundary and interior points/cells).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Martin wrote:
I might completely misunderstand you. But you can always call the initialiser of the parent class, even if overloaded (like call x%type_parent%init(...)). A notable exception is if type_parent is abstract, but implements init, in which case the initialiser routine needs to have a different name and overloading is not possible (for whatever reason the committee had to forbid this...). So a derived class needs to initialise only what it adds to the parent class??
Otherwise I was just generally refering to the fact that often components are more flexible and cleaner than inheritance and also the SOA vs AOS, which often forbids to abstract small units like grid points in FDM or cells in mesh based methods (e.g. to distinguish boundary and interior points/cells).
What I was referring to was some thing like scenario A:
Module TestAA Implicit None Type parent Integer :: i,j End type parent End Module TestAA Program Test use Testaa type(parent) :: a a=parent(i=1) end Program Test
which does not work. To use an initializer one would have to do either
a=parent(i=1,j=1)
or extend the class hierarchy putting feature j into a new subclass
Module TestAA Implicit None Type parent Integer :: i End type parent Type, extends(parent) :: child integer :: j End type child End Module TestAA Program Test use Testaa type(parent) :: a type(child) :: b a=parent(i=1) b=child(i=1,y=1) end Program Test
and then decide whether one wants to use parent or child.
......................... However, thanks to IanH (https://stackoverflow.com/questions/32876256/how-to-initialize-fortran-derived-type-parameter-variable-containing-an-allocata) I just found that one can use the Null() function to omit a component from the initialisation.
a=parent(i=1,j=Null())
While this is a useful feature classes may have several dozen components of which many are set by calculating values from other (e.g. in the first of the above example j might always be calculated from i). From my current understanding I then have to put a null() value into the initializer call for every single component which seems a bit tedious.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
may.ka wrote:
.. What I was referring to was some thing like scenario A: ..
which does not work. To use an initializer one would have to do either
a=parent(i=1,j=1)..
Fortran does come across as somewhat limited in the concept of 'object instantiation' compared to other leading languages in use in scientific/technical computing with the OO paradigm, particularly when it comes to derived types. Hopefully that will change circa year 2035 with Fortran 202X standard revision allowing for ~10 years for reasonably usable compiler implementations) or year 204X with the standard update thereafter.
In the mean time, you can make use of component initialization and/or the facility to provide a generic interface with the same name as the derived type to help with setting structure construction.
type parent integer :: i=0, j=1 end type parent
And/or
type parent integer :: i=0, j=1 end type parent interface parant module procedure construct_parent end interface contains function construct_parent( i, j ) result ( r ) integer, intent(in), optional :: i integer, intent(in), optional :: j type(parent) :: r .. ! instructions elided end function
And with abstract types, as Martin indicated, a type-bound procedure that can be invoked by extensions as ..%<abstract parent>%init_xx(..).
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page
- « Previous
-
- 1
- 2
- Next »