# Add a CONFORM function to check that argument dimensions match?

It is possible to check whether an optional argument has the right dimensions without using a nested loop, as shown in subroutine `twice`.

``````module m_mod
implicit none
contains
function first_false(tf) result(ipos)
logical, intent(in) :: tf(:)
integer             :: ipos
ipos = findloc(tf,.false.,dim=1)
end function first_false
!
subroutine twice(i,j,ierr)
integer, intent(in)            :: i(:,:)
integer, intent(out), optional :: j(:,:)
integer, intent(out)           :: ierr
ierr = 0
if (present(j)) ierr = first_false(shape(i)==shape(j)) ! test that optional argument j conforms with i
if (ierr == 0 .and. present(j)) j = 2*i
end subroutine twice

subroutine thrice(i,j,ierr) ! more verbose
integer, intent(in)            :: i(:,:)
integer, intent(out), optional :: j(:,:)
integer, intent(out)           :: ierr
ierr = 0
if (present(j)) then
if (size(i,1) /= size(j,1)) then
ierr = 1
else if (size(i,2) /= size(j,2)) then
ierr = 2
end if
if (ierr /= 0) return
j = 3*i
end if
end subroutine thrice
end module m_mod
!
program main
use m_mod, only: twice
implicit none
integer :: i(2,3),j(2,2),k(2,3),ierr
i = 5
call twice(i,j,ierr)
print*,"ierr=",ierr
call twice(i,ierr=ierr)
print*,"ierr=",ierr
call twice(i,k,ierr)
print*,"ierr=",ierr
print*,"k=",k
end program main
``````

Running this gives

`````` ierr=           2
ierr=           0
ierr=           0
k=          10          10          10          10          10          10``````
1 Like

I discovered this post thanks to @awvwgk (from type(*): token type '*' is unexpected here (#439) · Issues · lfortran / lfortran · GitLab). What does `type(*)` mean? For example in:

``````function conform(mold, val, dim)
type(*), intent(in) :: mold(..)
type(*), intent(in), optional :: val(..)
integer, intent(in), optional :: dim
logical :: conform
...
end function
``````

how can one use the `mold` variable? What if I want to read the first element of this array, and check if it is an integer and equal to 1. How do I do that?

@certik, you will recall `type(*)` is the other `unlimited polymorphic` option introduced starting Fortran 2018 that facilitates certain scenarios involving `void *` during interoperability with C.

You can see this comment upthread, there are very limited instructions one can perform with `type(*)` dummy arguments in Fortran.

Standard conformance would imply one cannot “read the first element of this array, and check if it is an integer and equal to 1”

1 Like

Thanks @FortranFan ! I was actually going to propose to implement `type(*)` as an extension in LFortran to make it easier to write generic interfaces, such as the intrinsic `size` function:

``````interface
integer function size(x)
type(*), intent(in) :: x(..)
end function
end interface
``````

And I now realized this is already in standard Fortran!

Why not to extend this natural syntax to actually make it useful and be able to do stuff with it somehow, such as read the first element?

The pushback you’ll receive with that is the language already has `class(*)` the other unlimited polymorphic option for such situations.

Looking at `type(*)`, it would appear it’s geared for semantics of a pass-through address in procedure references, an opaque `void *` pointer i.e., a typeless entity for which, say, an implementation won’t need to cough up any descriptors. With such a design already in place in the language standard with Fortran 2018, it seems rather difficult to do much with it but I could be wrong.

1 Like