[J3] Elemental and optional arguments

John Reid John.Reid at stfc.ac.uk
Sun Jun 27 10:17:26 UTC 2021


José,

José Rui Faustino de Sousa via J3 wrote:
> Dear All,
>
> I would be very much obliged if anyone could kindly answer a few 
> questions about the correct interpretation of the standard.
>
> I am confused by the interplay of optional arguments and elemental 
> procedures specially under the definition of presence in 15.5.2.12.
>
> Even more so by the possibility that a function will return an array 
> or a scalar depending on an argument, which is graphically present, 
> being considered absent under 15.5.2.12.

The standard has no concept of  "graphically present".  15.5.2.12 
defines the meaning of "present" and uses it.

> I think my confusion is mostly caused by my difficulty in 
> understanding the purpose of the restrictions placed by the standard 
> on references to elemental procedures and without understanding 
> purpose rules just seem arbitrary and hard to follow.
>
> From what I could understand I wrote this list of, possibly wrong, 
> assumptions:
>
> First of all I am assuming that all the issues raised by elemental 
> procedures must be resolved at compile time, except for the extents 
> which may only be known at runtime. Although I don't think this is 
> explicitly stated in the standard it is a core characteristic of the 
> language.

No, we can get runtime errors here.
>
> Second I am assuming that there are two perspectives to actual 
> argument presence, in the sense of 15.5.2.12. The perspective from the 
> procedure which has an optional argument, which cannot know why an 
> argument is not present, and the perspective from the subprogram which 
> makes the procedure reference, which knows if the argument is 
> graphically present or not.
>
> (I understand 15.5.2.12.3 (6) to apply only in the first perspective.)

I do not recognize your idea of "perspective". Whether a dummy argument 
is present is defined by 12.5.2.12. 15.5.2.12.3 (6) refers to an 
optional argument of the procedure that is calling the elemental procedure.
>
> A corollary of these two assumptions would be that shape conformance 
> of graphically present actual arguments is mandatory, without regard 
> to presence in the sense of 15.5.2.12, and reduces to rank matching.

No.
>
> Third, although AFAIK this is not stated anywhere, I am assuming that 
> what the standard is trying to enforce is that, at compile time, it 
> must be possible to know if a reference to an elemental procedure will 
> be an elemental reference, which will need scalarization, or a 
> "normal" scalar procedure reference.

Yes. If an array argument is absent, another array argument must be 
present, see  15.5.2.12.3 (6).
>
> Forth I am assuming that it is possible and legal to define elemental 
> procedures that obey all the rules stated in 15.9.1, but that 
> afterwords cannot be elementally referenced, at least under some 
> circumstances.

Yes, as illustrated by the program you sent.
>
> Fifth, in the case of functions, I am assuming that the LHS of the 
> function assignment does not play any role on deciding if a reference 
> to an elemental function is an elemental reference or not.

Agreed.
>
> (This makes techniques like return value optimization hard to apply.)
>
> Sixth, in the case of functions and although AFAIK this is not stated 
> anywhere, I am assuming that in a reference to an elemental function 
> which is not an elemental reference, even if the LHS is an array, the 
> function should only be evaluated once.

I don't see why you need any words for this case. We have a scalar 
expression and an array lhs.

>
> Are these assumptions correct?
>
> As an illustration I add a small program:
>
> program emess_p
>
>   implicit none
>
>   integer            :: i
>   integer, parameter :: n = 11
>   integer, parameter :: u(*) = [(i, i=1,n)]
>
>   integer, allocatable :: a(:)
>   integer              :: b(n)
>   integer              :: cnt
>
>   cnt = 0
>   b = efun()
>   if(any(b/=1)) stop 1
>   if(cnt/=1) stop 2
>   cnt = 0
>   ! In principle it is only possible to know if a is present at runtime,
>   ! so this is most likely illegal. Although I don't know why has I
>   ! don't think 15.5.2.12.3 (6) applies here.
>   b = efun(a)

You have a runtime error here because a is not allocated and therefore 
regarded as absent.

> if(any(b/=1)) stop 3
>   if(cnt/=1) stop 4
>   allocate(a, source=u)
>   cnt = 0
>   b = efun(a)
>   if(any(b/=u)) stop 5
>   if(cnt/=n) stop 6
>   stop
>
> contains
>
>   impure elemental function efun(a) result(b)
>     integer, optional, intent(in) :: a
>
>     integer :: b
>
>     cnt = cnt + 1
>     if(present(a))then
>       b = a
>     else
>       b = 1
>     end if
>     return
>   end function efun
>
> end program emess_p
>
> Thank very much for your time.
>
> Best regards,
> José Rui


I hope this helps.

John.


More information about the J3 mailing list