Access component of function result

Access component of function result

Hi,

If I understood correctly, accessing the components of the result of a user-defined type-valued function, like

constructor( param ) % component

is not permitted according to the Fortran 2008 standard. What is the rationale behind this?

Best regards,

Sergio

18 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

As it happens I'm at the standards meeting so I asked the other members. There are many features proposed that don't make it as "work items" due to insufficient interest or alternative ways of accomplishing the same thing in the language. This one never rose, apparrently, to the point of serious discussion, if it was ever proposed at all. Offhand, nobody had  a ready answer as to why it couldn't be done, but that's true for lots of things. There is always a cost to adding new syntax and sometimes it's not immediately obvious.

Retired 12/31/2016

Well, please consider bringing it up! It is a common feature of many object-oriented language. This would allow for on-the-fly generation of one-use complex subprocedures. For instance, something like:

interpolated_values=Interpolator(original_points)%interpolate(interpolation_points)

This would become even more important for chaining these operation, for objects with type-bound procedures that return objects with type-bound procedures which... As long as adequate final procedures are defined, this should be perfectly safe.

In my probably short-sighted opinion. the only extension to syntax would to allow % after function calls, besides after object names. It feels like a very natural extension of the language. Of course, I know this is complicated and there might be nasty implications... But I think it's worth having a look.

Thanks again for the reply, Dr. Fortran :)

Perhaps it has other flaws, but consider what you can do with user defined operators.

 

But aren't we in the same situation? The standard would not allow for stuff like:

(obj1 .op. obj2) %method()

or

(.op. obj1) %method()

would it?

The intention was to change method() into an operator.  For your original example:

interpolated_values = Interpolator(original_points) .interpolate. interpolation_points

There's a philosophy that function references are primarily for use in expressions.  Use of operator syntax is consistent with that philosophy.

Aaaaah, sorry, now I see what you mean!

Well, that actually makes a lot of sense. Operators are something I hardly use, now I have an excuse to change it.

Thanks a lot for the insight.

Best Reply

The way you seem to want this feature to work, each occurrence of a constructor( param ) % <component> would constitute a separate function invocation. However saying "the standard doesn't support this concept" is still not fully true. Since Fortran 2003, there exists the ASSOCIATE block construct that allows you to effectively do this as follows:

associate (my_func_res => constructor( param ) )

! now access any type component of the function result

... = my_func_res%component1

... = my_func_res%component2

end associate

Note that

  • only one function call is performed
  • the associate name inherits most properties from the the associated entity (including type, rank, shape); if an entity with the same name exists outside the associate block, it can of course not be accessed inside the block
  • due to the expression character of the associated entity the associate name "my_func_res" can't appear in a definition context
  • an associate block can contain multiple associations in form of a comma-separated list

Hope this helps

Reinhold

Citação:

reinhold-bader escreveu:

The way you seem to want this feature to work, each occurrence of a constructor( param ) % <component> would constitute a separate function invocation. However saying "the standard doesn't support this concept" is still not fully true. Since Fortran 2003, there exists the ASSOCIATE block construct that allows you to effectively do this as follows:

associate (my_func_res => constructor( param ) )

! now access any type component of the function result

... = my_func_res%component1

... = my_func_res%component2

end associate

Note that

  • only one function call is performed
  • the associate name inherits most properties from the the associated entity (including type, rank, shape); if an entity with the same name exists outside the associate block, it can of course not be accessed inside the block
  • due to the expression character of the associated entity the associate name "my_func_res" can't appear in a definition context
  • an associate block can contain multiple associations in form of a comma-separated list

Hope this helps

Reinhold

Reinhold,

Thank you very much for pointing this out.  I now use ASSOCIATE construct extensively, but I'd completely missed out on this aspect of it.  I just tested it out and it works!  Should come in handy on quite a few occasions.

Cheers,

I can't remember the issue number off hand, but be wary with associate and optimization flags. I was seeing some very bad behavior with -O2 and above (wrong results). It is very possible that this has been fixed in the most recent release, but if not, I want to save you the headache I endured locating the problem. For the time being I avoid associate constructs to prevent this issue. Sorry I don't have time to dig up the issue number and check on its status.

Citação:

Izaak Beekman escreveu:

I can't remember the issue number off hand, but be wary with associate and optimization flags. I was seeing some very bad behavior with -O2 and above (wrong results). It is very possible that this has been fixed in the most recent release, but if not, I want to save you the headache I endured locating the problem. For the time being I avoid associate constructs to prevent this issue. Sorry I don't have time to dig up the issue number and check on its status.

Hmmm.. I'd encourage you to "dig up" your issue, if you can sometime, and bring to Intel's (including Steve's) attention.  I've a selfish interest (:-)) because I've been using ASSOCIATE construct extensively of late (it's so convenient and useful).

A couple of legacy libraries that I recreated with "modern Fortran" and heavy ASSOCIATE usage have optimization flags of -O2 and -O3 respectively in Release mode (Windows platform).  In my tests, I've not noticed any "bad behavior" yet; admittedly a lot more testing of these libraries is still pending.  But I was also worried about "performance penalty" with possible use of pointers by the compiler internally in connection with ASSOCIATE constructs.  But I'm not noticing degradation on this account either, that is in CPU timing studies compared to the previous FORTRAN (IV thru' 77 and extensions) version.

The only open bug I can see in our records related to ASSOCIATE has to do with putting an OpenMP PARALLEL region inside a construct, not likely to be an issue here.

Retired 12/31/2016

Issue ID was DPD200247629, from this thread here (scroll allllll the way to the bottom, took some time to localize and create the reproducer, etc.): http://software.intel.com/en-us/forums/topic/405706

The issue was finally localized and reproducer submitted in August of last year and I enquired about its status January 31, but it must have gotten lost among other postings.

EDIT: The difference between the two codes is a simple search and replace, swapping out n for this%n. Ultimately my work around was to just do search and replaces or creating a new local variable everywhere I had added an associate construct in my code, since I was only using it for creating a shorthand/alias for derived type components. This solved all my problems.

That got fixed in Update 2. Sorry I missed your question.

Retired 12/31/2016

No worries Steve, I think the forums were quite busy around then, and I was busy too. Glad to hear that it's fixed.

Reinhold,

Thank you very much for your reply, I had no idea about this feature!

(Still, I think the standard should allow directly using a function result without assignment...)

Sorry for not noticing the reply in so many days, I'd say the forums don't have the best interface to keep in touch... :-/

Citação:

Sergio escreveu:

.. I'd say the forums don't have the best interface to keep in touch... :-/

I disagree completely as far as Intel Developer Zone (IDZ) forums are concerned.  You may want to check your profile setup at software.intel.com.  My profile is setup with an e-mail account I check regularly and I get prompt updates automatically whenever any comments are posted on topics I create; I also get notified right away on updates to forums I subscribe to.  So I find it very easy to keep in touch with IDZ forum discussions.

Well, one issue is that I receive a ton of email from IDZ. Most of them start with "New comment for Intel® Fortran Compiler for Linux*..." and that is as far as my email client previews, and it is not practical to check all emails. Just now I noticed that what I want to pay attention to is "New activity in your forum topic". There seems to be at least four types of notification: "New comment for", "Update for Forum topic", "****: Forum topic Activity Notification", "New activity on your Forum topic".  Sometimes one action triggers two or three of these. It doesn't look obvious.

And the rest of the interface is not trivial. When I click on Dashboard, I would expect to quickly see replies to my posts, topics with a hot activity, etc. I read "My Messages.Check forum activity, new comments, subscriptions, messages and more." I click there,and it is completely empty. "My content", maybe? Nope. I have to click on my user name in the belt area, and then click on "User's contributions".

I guess this is not the place to post this and I didn't want to start a rant, anyway. Although I did :P

Leave a Comment

Please sign in to add a comment. Not a member? Join today