Can we define a Read/Write-like function in Fortran?

Current, all the subroutine or functions, say, give it a name super_read, it has to take in the arguments, and set the value to x as below,

x = super_read( argument 1, argument 2, argument 3, ...)

or

call super_read( argument 1, argument 2, argument 3, ..., x)

However the intrinsic read function for example, has the structure like below

read(5,*) x

You know it just take the arguments 5 and *, and operate on x. You know the x is outside the ().

Now, can we also define function, say super_read, and it works like below, you know similar with the intrinsic read?

super_read( argument 1, argument 2, argument 3, ...)   x

You know you give super_read all the arguments, then it operate on x. The x is outside the ().

I mean, if I do not like the intrinsic read function, I can define my own super_read function like above.

Note that READ is a statement, not a function or a subroutine. So, no, you can not do that as you can not define new statements.
Apart from that, what use do you see in such a super_read or super_write?

1 Like

I see, thanks. So we cannot define a statement :rofl:

Usage, for example, if I want to read a specific file AAA.txt and store the content into an object x,

type :: superman
real :: height
real :: weight
real :: age
character :: planet
more complicated information ...
end type

type(superman) :: x

! define super_read
! use super_read
super_read("AAA.txt") x

But of course you can argue that, can just define super_read as a subroutine. But I am just curious to see if we can define a read-like statement super_read.
I mean in the extreme case, if I feel the intrinsic read is not powerful enough, I can define a better super_read statement which can do all what read can do, and do more, and it can be used just like read. This may be a usage.

I guess is just a matter of coding style, but for derived types I have taken the practice of having a “load” and a “dump” procedure, using functions instead of subroutines to be consistent with a call such as:

err = MyCoolType%load( ‘my_file_name.my_format’)
…
err = MyCoolType%dump( ‘my_file_name.my_format’)

And catch problems with the error integer ‘err’

The catch here is that one should not define directly the function as
function load ()
but have an intermediate private function
function load_superman ()
and within the type

type :: superman
...
contains
...
procedure :: load => load_superman
end type

to avoid compile-time conflicts with other types having the same internal function declaration

1 Like

Happy birthday, @CRquantum! Make them 100 (popular birthday wish in my culture, it means something like “may you celebrate your 100-years birthday”.) :slightly_smiling_face:

Yes, you can’t define your own statements. If you really want x in your example to be outside the parentheses (and you want to avoid a function), I guess you can make something with a user-defined operator, say .superRead. However operators require functions, not subroutines, so It won’t be a statement like read but rather a masqueraded function, still in the form of x=.., for example x = .superRead. "(i2)" instead of read "(i2)",x.
Honestly though, I don’t see a reason to go that way, other than curiosity - which, admittedly, is a good reason by itself.

2 Likes

Have a look at user defined i/o eg. https://www.intel.com/content/www/us/en/develop/documentation/fortran-compiler-oneapi-dev-guide-and-reference/top/language-reference/data-transfer-i-o-statements/user-defined-derived-type-i-o/examples-of-user-defined-derived-type-i-o.html

5 Likes