Extension of abstract types in different modules - oop

In the following piece of code, an abstract type with a private variables (name) and an access function to this variable, which is supposed to be defined by all derived types, is defined in a module:
module baseTypeModule
type, abstract :: baseType
private
character(len=maxLengthCompLabel) :: Name = "" ! Component name
contains
procedure, non_overridable :: getName ! Access functio to Name (read only)
end type baseType
contains
character(len=100) function getName(this)
implicit none
class(baseType), intent(in) :: this
getName = this % Name
end function getName
end module baseTypeModule
As there are many other variables and functions in each derived type, I would like to define each derived types in a different module.
Is there a way in Fortran to tell the compiler that I want that only derived types of baseType would be able to change the variable Name?

No. Accessibility of component names uses the same "by module" model as for other module entities. If the other derived types are in different modules, then they cannot access the Name component.
Bear in mind that derived types don't actually contain procedures - they contain bindings for procedures. Consequently a derived type can't really "do" anything. Also a single procedure could be bound to multiple types.

Related

Relationship between abstract type and generic interface with the same name

Consider the following code.
MODULE a
TYPE:: concrete
END TYPE concrete
INTERFACE concrete
PROCEDURE constructor
END INTERFACE concrete
CONTAINS
SUBROUTINE constructor
END SUBROUTINE constructor
END MODULE a
As far as I understand, in this context the generic interface concrete declares the constructor of type concrete to be the subroutine constructor (and this is the only way I know to declare a constructor). Now consider the following code.
MODULE a
TYPE, ABSTRACT:: abstract
END TYPE abstract
INTERFACE abstract
PROCEDURE what_am_i
END INTERFACE abstract
CONTAINS
SUBROUTINE what_am_i
END SUBROUTINE what_am_i
END MODULE a
Here, I have an abstract type and a generic interface with the same name, but there cannot be a constructor for the abstract type abstract, by definition.
So my question is: is there any relation between an abstract type, a generic interface with the same name, and the procedure inside such interface (in the example, the subroutine what_am_i)? If so, what is it?
There is exactly the same relationship between the type abstract and the generic abstract as there is between the type concrete and the generic concrete.
This relationship is, simply, "they have the same name". Although a generic function with the same name as a type can be viewed as a constructor, it has no real privileged position.
The definition of a derived type implies a default structure constructor with the same name as the derived type, so that
type t
integer i
end type t
type(t) x
x = t(1)
end
gives us an object x of that type with the expected values.
If instead, we have x=t(1) which can be resolved to a specific function f we can call that function f a constructor if it has function result an object of type t.
But there's no reason at all why f must return an object of type t. Consider
module mod
implicit none
type t
end type t
interface t
module procedure f
end interface t
contains
function f()
integer f
f = 1
end function f
end module mod
use mod
implicit none
print *, t()
end
It's hard to call f here a constructor.
That's it: no specific function under the generic abstract can return a constructed abstract object, but each can return something else. Just as a specific function under the generic concrete can return something not of type concrete.

List of ABAP protected type names

Out of curiosity, I tried to create an ABAP interface with name object. The compiler gives the error message "OBJECT" is a protected type name and therefore cannot be used for a user's own type definitions.
While this check is certainly a good idea, I could not find a reference to protected type name in the ABAP Keyword documentation. Are there others?
The naming conventions indicate the possible names additionally to the mandatory naming "convention":
The names of predefined ABAP types or predefined data objects must not be used for data types or data objects.
NB: I tried names of predefined data objects, they are allowed for data types, so I guess "respectively" is to be understood implicitly.
Self-defined data types must not have the name of a built-in ABAP type. This applies to type definitions in the ABAP language and in the ABAP Dictionary.
Concerning the generic types, only those made of one word are forbidden, i.e. HASHED, INDEX, SORTED, and STANDARD are allowed (and also REF):
ANY, C, CLIKE, CSEQUENCE, DATA, DECFLOAT, N, NUMERIC, OBJECT, P, SIMPLE, TABLE, X, XSEQUENCE
Other types are protected like the built-in concrete (i.e. not generic) types (error <XXXX> is a protected type name and therefore cannot be used for a user's own type definitions):
D, DECFLOAT16, DECFLOAT34, F, I, STRING, T, XSTRING
CURSOR
Obsolete types 1 and 2 (their names are also forbidden inside classes and interfaces because the name must start with A-Z, underscore).
Other types may be forbidden (error Type <XXXX> is reserved for future further developments of the ABAP language. Choose another name.) like:
INT, INT1, INT2, INT4, INT8
The list is not exhaustive. I didn't find an official list in the ABAP documentation nor in the SAP support Web site.
NB: tests done in a 7.52 system
The generic data types, which cannot be used for naming:
https://help.sap.com/doc/abapdocu_750_index_htm/7.50/en-US/abenbuilt_in_types_generic.htm
The best way to create all of your object or program or table ect.. is to put the Z or the Y before the name you want to give:
Object have to been Zobject or Yobject or ZY-YZobject
Often, we use the Z and then the module wich it refers: ZSD_OBJECT

Overloading with different interface procedures in Fortran

Say you have two subroutines which have different interfaces and you have two types where each corresponds to one of the procedures.
type, abstract :: base
contains
procedure :: pointer_to_routine
end type base
type, extends(base) :: first_case
contains
procedure :: pointer_to_routine => first_case_routine
end type first_case
type, extends(base) :: second_case
contains
procedure :: pointer_to_routine => first_sec_routine
end type second_case
So this is not valid Fortran code, but it is kind of the idea I want to do. If the routines had similar interfaces I could define an abstract interface and deferred attribute in the base declared type.
But since my two routines have different interfaces, I am not sure how this can work out.
Essentially, one routine needs more inputs than another, so one solution would be to add the remaining inputs as just dummy inputs, although, this could potentially cause a bit confusion, And I am wondering if there is a more convenient solution.
All solutions you can invent for this will be workarounds. The language is simply designed that way that all procedures with the same binding name as in the parent type should have the same interface. Note that other languages have similar problems/features Override method with different signature.
You can use dummy arguments if you know they will be needed in general but not in a specific case. They can be optional arguments. You can also make the input arguments contained in a polymorphic derived type.That will bring new issues though.

Fortran 2003, can data be deferred in an abstract type?

I know it's possible to defer the definition of procedures from an abstract type to its derived types. Is it possible to include 'deferred' data in an abstract type, i.e., data whose type and value is only defined in derived classes?
The closest question I found on stackoverflow was here. It does not address my needs.
If clarification is needed, please ask. Many thanks.
There's no straightforward way to defer the definition of a data component of an (abstract) derived type as there is for procedure components, so no declaration such as
type(magic), deferred :: element
which can be overridden by a concrete declaration in an extended type. I think the easy (?) workaround would be to use class in the declaration. For ultimate flexibility you could use an unlimited polymorphic component, eg
type :: stype
class(*), allocatable :: element
end type style
What you can't then do is specify the type in a concrete extended type with a (re-)declaration something like
type, extends(stype) :: mstype
integer :: element
end type mstype
Instead, if you want to define an extended type which has an integer element you would create the type and write a constructor for it that ensures its element is allocated with type integer.
If your requirements are more modest the 2003 feature of parameterised derived types might satisfy you, but as far as I know only the Cray and IBM XL compilers implement that yet.

Fortran derived type with an abstract type component

In fortran 2003, is it possible to define a derived type which has a component of an abstract type? For example, as below, I want to define a type Sup having a component o_Abst of Abst type.
TYPE, ABSTRACT :: Abst
CONTAINS
PROCEDURE(some_proc), deferred, pass :: some_proc
..
END TYPE Abst
TYPE :: Sup
PRIVATE
CLASS(Abst) :: o_Abst
..
CONTAINS
PROCEDURE :: another_proc
END TYPE Sup
One problem I have already encountered is in writing a constructor for a Sup type object. I can not assign a value to the component o_Abst by intrinsic assignment with = (Intel compiler says, "In an intrinsic assignment statement, variable shall not be polymorphic."). Or can't I write a constructor for a Abst type object because a deferred type-bound procedure can not be properly overridden if an argument other than the passed object dummy argument is of abstract type, as far as I understand.
I would also be happy to hear about a work around that avoids the use of a type like Sup. If it is tempting to define a type with a component of an abstract type, what are alternative strategies in general?
A derived type may have an polymorphic component with abstract declared type. The component must have either the pointer attribute or the allocatable attribute.
Intrinsic assignment to a polymorphic object was not permitted in F2003 (it is permitted in F2008 if the object being assigned to has the allocatable attribute, but ifort 12.1 does not support that). In F2003 an ALLOCATE statement with a SOURCE specifier can be used to achieve more or less the same result.
You can construct objects that have a type that is a non-abstract extension of Abst (it does not make sense for the dynamic type of an object to be abstract, hence no structure constructor exists for Abst itself). There is no restriction on procedures that are bound to a type taking one or more arguments of abstract type.