-
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
Add revised protected components & types proposal #182
base: master
Are you sure you want to change the base?
Conversation
|
||
G. A protected component or a subobject of a protected component can only | ||
be argument associated with INTENT(IN) dummy, even if the referenced | ||
procedure is in the module in which the type is defined. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this is implied by B, but nothing wrong with being explicit.
the target in a pointer assignment outside the module, as that would | ||
lose the protection. | ||
- Here I think it would be valuable to somehow expose an immutable | ||
reference, which could tie into the const-pointer proposals. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good eye, forward thinking. I had a similar thought, but didn't see a reason to bring it up and complicate matters. Worth keeping in mind though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. We'll see what comes of this, but given there's already work on the other feature it would be cool to get both of these working together.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I absolutely agree, a read-only reference would be very handy here.
proposals/protected-components.txt
Outdated
N. Structure constructor outside the module in which the type is allowed if | ||
and only if no value is supplied for any protected component (otherwise | ||
this would subvert the module's control over what values are acceptable | ||
in the protected component). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we actually don't want this. The motivation behind the feature is more about keeping objects internally consistent, and a structure constructor would potentially (probably?) produce an internally inconsistent object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(I think) structure constructors are not modifiable. Of course a type-bound procedure called init
or something like that can do anything, but this would be for the language-defined structure constructor. e.g.:
type :: foo
integer :: a, b, c
integer, private :: d
integer, protected :: e
end type foo
type(foo) :: x
x = foo(a=1, b=2, c=3)
In this case, we can't specify values for d
or e
via the structure constructor. I'm sure some discussion will come up on this point, though, because a private
variable d
cannot be specified here because its name isn't accessible in the scoping unit. The name e
is accessible, so some extra rules will need to be added to the standard to handle this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now I see it. a
, b
, and c
aren't being protected anyways, so getting rid of the structure constructor doesn't buy you any extra protection. Got it.
proposals/protected-components.txt
Outdated
- The function result shall not be a pointer. | ||
- The function result will (hopefully) be finalised after its use. | ||
|
||
N2. Structure constructor outside the module in which the type is allowed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this just be a copy of N?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that I'm thinking about it, we might actually want the opposite: "A structure constructor outside the module in which the type is defined is not allowed".
The original version was concerned with assigning to a protected component, so prohibited intrinsic assignment but basically allowed an exception for structure constructors which did not name those protected components (though this could effectively overwrite existing data in a protected component, if I'm not mistaken). Now that we've separated out the protected components, I'm thinking we don't need the exception and would just forbid structure constructors on protected types (when outside the module where the type is defined).
I think I'll change it to that for now, but I'll defer to the interested parties in the committee for behavior of type protection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The paper looks good.
My major suggestion for improvement would be to add test/example cases of how the feature is used. The only examples are how it is declared, but it would be nice to add examples showing:
- how it can be used
- what usage is allowed
- what usage is not allowed
- how exactly it differs from the previous proposals
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thx. for setting this up! This is all fine, see a few minor comments. My only concern is, that we are now putting two different categories of protected
-nes into one proposal:
- The
protected
component, which is probably not too difficult to implement in compilers and seem to have not too many implications/side effects. - The
protected
type, which seems to be a monster with many-many implications and side-effects.
I fear, that it would put the first one on hold due to numerous discussions on and problems with the second one.
Also, I'd recommend to use a different name for the two features as to me, their puprose is completely different. To me protected
just means 'read-only', in the sense that you need routines of the defining modules to manipulate that value. Note, that also in case of protected
module variables, the same meaning still holds. The only reason, why such variables are also behaving kind of 'persistent', is that modules do not go out of scope. If they would, protected
module variables would "vanish" exactly the same way as all other (private and public) module variables, so they were not persistent. So it is not they protected
-nes which makes they persistent... Therefore, I'd suggest to keep the term protected
for expressing read-only behaviour (of the derived type components), and use something else for defining persistent/undestroyable types (e.g. persistent
).
the target in a pointer assignment outside the module, as that would | ||
lose the protection. | ||
- Here I think it would be valuable to somehow expose an immutable | ||
reference, which could tie into the const-pointer proposals. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I absolutely agree, a read-only reference would be very handy here.
L1. No intrinsic assignment to a protected component or subobject thereof, | ||
outside the module in which the protected component is defined. (cf. | ||
19-135r1) | ||
- This does not prohibit intrinsic assignment to a type containing a | ||
protected component. It is only meant to prevent the protected | ||
component from being modified by name. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this already covered by B anyway?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe it is covered by B. The original paper I built off had both (19-214r1), and I can't say I know why. I'm taking a "change as little as possible" approach compared to what they had.
proposals/protected-components.txt
Outdated
- This presents a loophole which may allow a programmer to write to a | ||
protected component outside the module in which it is defined. | ||
However, subgroup did not like the alternative of disallowing | ||
protected components in extensions of parent types without any | ||
protected component. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens, if the parent type is deallocated? It would basically allow to deallocate protected types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good question, I'll clarify in here. This was something concluded by Malcolm & Van, and I believe the intention is that the protected component would become deallocated & finalized. This is basically a loophole to avoid the other restrictions on deallocation & finalization, but the alternative they had in mind (prohibiting protected components in type extensions) was too strong.
But I'm noticing some holdovers from the old protected component terminology, which here is a protected type. That needs to be fixed.
Thanks @aradi!
This is definitely a valid concern. For our part, I wouldn't be proposing that monster feature at all (I don't see it as extremely useful personally). But when presented with protected components, the committee really wanted something extremely strong, and had lots of work towards that already. These specs derive from the work on those very restrictive protected components. It looks like if we want our more lightweight protected components, we need something strict to go with it. But we'll see as discussions develop, maybe seeing both alongside each other the committee will be willing to drop the heavy one. Hopefully the committee doesn't decide they don't see the value in our lighter protected components, deciding to go ahead with heavy-only, or decide the whole combination is more than they wanted and kill the whole concept.
I like this, and have struggled to come up with an alternative name for "protected type". |
@certik thanks for the suggestion. I added a section on use-cases, which naturally was very detailed on what we want to see in protected components, but lighter for protected types. I tried to faithfully relay the motivation described to me by Van, and I think it ended up being similar to described by Malcolm in 19-135r1. |
Tagging a few others who might be interested: @FortranFan @milancurcic @gklimowicz @tclune @vansnyder I think we got this into pretty good shape during our discussion in September, but I've added a bit more clarifying discussion. I'm planning to show this to the committee for our meeting next week. I think this approach offers enough flexibility to satisfy everyone, but we'll see how it goes. |
On Tue, 2021-06-15 at 15:20 -0700, Zach Jibben wrote:
Tagging a few others who might be interested: @FortranFan
@milancurcic @gklimowicz @tclune @vansnyder
I think we got this into pretty good shape during our discussion in
September, but I've added a bit more clarifying discussion. I'm
planning to show this to the committee for our meeting next week. I
think this approach offers enough flexibility to satisfy everyone,
but we'll see how it goes.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or unsubscribe.
Zach mentions that "persistent" types disable intrinsic assignment,
allocation, deallocation, and automatic finalization.
I assume this disabling does not apply in the scoping unit where the
type is defined.
In Ada '83, the "limited" attribute for a type did this. I don't
remember in which level of requirements this was first introduced. It
was definitely in "Steelman." I first proposed it in 97-114.
|
Hi Van, thanks for looking at this!
This is correct, specification L3 allows for intrinsic assignment inside the module which defines the protected type. |
@zjibben wrote 15 June 2021, 6:19 PM EDT:
Great paper, Zach. I read your revised version closely just now and you've covered everything that I can think of, especially with formal specifications toward the protected components feature that is of particular importance in many codes in my experience. My only change will be on line 113: 'inadvertently'. I feel strongly this will be an excellent addition to Fortran 202X. The discussion at the plenary on this paper will be of great interest, hope no technical surprises arise then. |
Good luck! Let's hope, this time the proposal gets further as last time. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @zjibben. This feature would be a useful addition. Good luck!
P1. Protected components are inherited through type extension. | ||
- In this regard, PROTECTED is like PUBLIC, not PRIVATE. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In all other rules, PROTECTED behaves as PRIVATE, except for its readable behavior. Should it not be the case for this rule too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My reasoning here is PROTECTED components are part of an API, something a client can see and read. PRIVATE components are completely invisible outside the type, hence it's safe not to inherit them. But if a client has a class(parent)
with a protected component, the dynamic type type(child)
ought to share the parent's API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great proposal and useful potential addition, thank you for pushing it.
proposals/protected-components.txt
Outdated
A: I believe the answer here is yes. Specification K allows modification of | ||
the components of a protected type; i.e. the protection of a type really | ||
only restricts what can be done to the type as a whole. This is up for | ||
discussion, though, and could be changed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems reasonable to me.
combination of more than one of these attributes. | ||
|
||
|
||
3.2 Protected Types |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can a protected type be extended? If yes, would the extending type also be protected? It seems to me that it would have to be, otherwise it would be easy to "unprotect" a protected type. This should be spelled out in the spec.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I see P2.
Co-authored-by: Milan Curcic <[email protected]>
Thank you everyone! The paper has been submitted: https://j3-fortran.org/doc/year/21/21-148.txt |
Here is a revised version of the protected components proposal (#156). The next committee meeting is 3 weeks away (Oct 12) so I wanted to make sure we had time to discuss beforehand.
To recap, last time it became clear there were competing interests. I and others here and at LANL wanted an access specifier roughly in between
private
andpublic
. Other committee members want something far more restrictive, something really unlike an access specifier and more analogous to the existingprotected
attribute for module data. This would act to really protect the data from virtually any modifications outside the module where the type was defined, and was far too restrictive to be useful for those of us who wanted an access specifier.The best way forward seemed to be to tease apart these separate needs and provide tools to manage both. That way we all get what we want. This paper has specifications & syntax for protected components and protected types based on our withdrawn 20-121. If we're happy with it, I can either submit it as a paper or as a work item for the DATA subgroup.