3
votes

Say I am programming a card game in fortran. I have a card object, with a type-bound procedure "getsuit" and a deck object (consisting of an array of cards) with a type-bound procedure "getcard".

What I'd like is to be able to do something of the form:

deck%getcard%getsuit

When I do this, however, my compiler informs me that "a function reference cannot be used as the leftmost part-ref of a structure component," even if the function is of type "card." On the other hand, doing this:

card = deck%getcard
card%getsuit

works fine. It seems obnoxious to have to use two lines and an extra variable to accomplish this; is there any way around it?

2
You may find an example here, where it was solved by introducing a special operator for the given type.Bálint Aradi

2 Answers

2
votes

Depending a little on what your functions do (here assuming that they are more or less pure) you can use user defined operators.

the_suit = .SuitOf. (.CardFrom. deck)
2
votes

ISO/IEC 1539-1:2010 a.k.a Fortran 2008 says in section 6.4.2

R611 data-ref is part-ref [ % part-ref ] ...
R612 part-ref is part-name [ ( section-subscript-list ) ] [ image-selector ]
C609 (R611) Each part-name except the rightmost shall be of derived type
C610 (R611) Each part-name except the leftmost shall be the name of a component of the declared type of the preceding part-name

What this means is that each component of a structure reference must be a data member of the preceding component. The allowance for () in the part-name is to allow indexing into array members and does not allow for functions. That a function returns a derived type does not meet the specification of part-ref and so is not valid Fortran and it is right for your compiler to complain.

You can however do this:

deck%card(i)%suit 

assuming card is in array of cards belonging to deck and suit is a type belonging to card.