-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improved control of type bound procedure accessibility #127
Comments
@nncarlson is it the same thing as |
@certik After visiting SO (my C++ is weak) I think it is the same in spirit but there are some differences due to Fortran's additional module scope. As it pertains to type bound procedures:
So perhaps what I'd propose is a new attribute
Perhaps a |
Correct me if I'm wrong but I'm pretty sure it's possible to override a
private type-bound procedure even from another module (although not to call
it). Pretty sure this is done in the Abstract Calculus pattern.
…On Fri, 3 Jan 2020, 21:29 Neil Carlson, ***@***.***> wrote:
@certik <https://github.com/certik> After visiting SO (my C++ is weak) I
think it is the same in spirit but there are some differences due to
Fortran's additional module scope. As it pertains to type bound procedures:
- Fortran public == C++ public
- Fortran private => inaccessible outside module, but still accessible
and overridable within the module.
So perhaps what I'd propose is a new attribute protected for type bound
procedure declarations with this effect:
- Within the module scope: protected functionally the same as private
(or public)
- Outside of module scope: protected parent procedure would be
accessible (and overloadable) within code defining/implementing a child
type, but otherwise as private
- protected is incompatible either non_overridable or private
Perhaps a protected attribute makes sense for data components of a
derived type too.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#127?email_source=notifications&email_token=AB6ESPJSCZGUJ4KBKVR2M7LQ36U23A5CNFSM4KCRNFVKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEICD7FI#issuecomment-570703765>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AB6ESPNCUSWOXJORJ37MWXLQ36U23ANCNFSM4KCRNFVA>
.
|
Be advised: the keyword Maybe it would suffice to define an exception to |
@cmacmackin, interestingly enough in fact you can (I was surprised), but it's not exactly overriding the procedure. The parent class doesn't see it as being overridden as the following example shows (but this behavior could be exactly what one wants -- just not in the NVI-type use cases I'm usually encountering). But the one case this definitely doesn't work at all is with an abstract base class and deferred procedure, because Here's the example: module parent_type
private
type, public :: parent
contains
procedure, private :: private_sub
procedure :: public_sub
end type
contains
subroutine private_sub(this)
class(parent) :: this
print *, 'parent:private_sub'
end subroutine
subroutine public_sub(this)
class(parent) :: this
call this%private_sub
end subroutine
end module
module child_type
use parent_type
private
type, extends(parent), public :: child
contains
procedure :: private_sub
end type
contains
subroutine private_sub(this)
class(child) :: this
print *, 'child:private_sub'
end subroutine
end module
use parent_type
use child_type
type(parent) :: p
type(child) :: c
call p%public_sub ! prints parent:private_sub
call c%public_sub ! prints parent:private_sub
end |
@klausler I forgot that |
Yes, that would too. And if one didn't want that exception the procedure could be |
@nncarlson wrote:
@nncarlson and all interested, Please take a look at this discussion thread on essentially the same user need as here from Intel Fortran Forum several years ago: https://software.intel.com/en-us/forums/intel-fortran-compiler/topic/681705. In this Intel Fortran forum thread, please look at the comments by IanH, a brilliant mind when it comes to programming languages as well as the Fortran standard: IanH makes some excellent points e.g., "The result of the interp results in a capability gap for authors when they want a binding that can be overriden but not invoked - which is what I guess was the intent of the code in Fortran Fan's example. It would be nice to see the language address this in the future." and who provides other use cases later in the thread involving designing of libraries using Fortran. I'll check but my recollection is a similar need has been expressed on other forums (comp-fortran-90 mailing list or even J3 itself) re: derived type (or "classes") and type-bound procedures vis-a-vis the current accessibility statements with PUBLIC/PRIVATE that work at the MODULE level in Fortran. So my thought was to consider the concept of EXTENSIBLE MODULEs as I had mentioned in the Intel forum link above which, if combined suitably with the concept of PACKAGEs and/or NAMESPACEs, can prove quite handy, I believe.
module, overridable :: b_m
! NOTICE the keyword above implying this module is EXTENSIBLE
! By default, modules are to be NON_OVERRIDABLE
implicit none
private
type, abstract, public :: b_t
contains
private
procedure(Ip), pass(this), deferred :: p
end type b_t
abstract interface
subroutine Ip( this)
import :: b_t
class(b_t), intent(inout) :: this
end subroutine Ip
end interface
end module b_m module, extends(b_m) e_m
! NOTICE extends keyword above
implicit none
private
type, extends(b_t), public :: e_t
contains
procedure, pass(this) :: p => e_p
end type e_t
contains
subroutine e_p( this)
class(e_t), intent(inout) :: this
end subroutine e_p
end module e_m
|
No, it is not. Issue #16 and PR #31 aim for allowing read-only access to variables in derived types (similarly, how you can do it for module variables with the |
Here is a problem I regularly encounter: I have a class with a type bound procedure that (a) should not be publicly accessible (for invoking); but (b) I want to allow an extension of the class to override the procedure. In many cases the class is an abstract type and the procedure is deferred. This appears in the non-virtual interface (NVI) pattern, for example. Because of (a) I want to declare the procedure private, but due to (b) I have to let it be public (the two type declarations are in separate modules).
I wish there was another type bound procedure accessibility attribute between
public
andprivate
with the effect that the procedure would not be accessible for invoking, but would be accessible when declaring an extension of the type.The text was updated successfully, but these errors were encountered: