Intrinsic descriptions

On Twitter @FortranTip some of what I tweet is how one or more intrinsics work, for example

Fortran has similar MODULO and MOD functions.
MODULO (MOD) takes the sign of the 2nd (1st) argument.

print*,modulo([-1,0,1],2) ! 1 0 1
print*,mod([-1,0,1],2) ! -1 0 1
print*,modulo([-1,0,1],-2) ! -1 0 -1
print*,mod([-1,0,1],-2) ! -1 0 1
end

If an automated @FortranFunc channel were created, tweeting a description of an intrinsic function per day, with an image containing demonstration code, maybe some people would subscribe. It could loop over the functions and statements such READ and WRITE and repeat every year or so. When people tired of it they would unsubscribe, but hopefully there would be new Fortran programmers who find the service useful. @FortranTip was inspired by @SciPyTip, which has 132K followers and tweets such as

np.nanmin() returns the minimum of an array ignoring nan values.

2 Likes

I do not think the intrinsic documents as constructed here would often be too long, but tips like modulo versus mod (I always have to look them up or try them when not using all positive values, as MOD truncates towards zero and the other does a FLOOR, and the formulas result in
(as you mentioned) getting the sign of A when the signs differ, and the other the sign of B for the same case … but I think your Fortran Tips is a good forum for that (it is usually MODULO I want when it matters, but I always have this doubt till I try it :blush:).

Quick summaries, maybe with a link to the intrinsics documentation would be nice; but what might be more interesting because it would often be new might be stdlib routines and descriptions of resources like on your list of Fortran resources? hopefully the intrinsics documents will cover the descriptions of the intrinsics well enough that it will be mostly tips about them that will be of interest, and Fortran Tips is covering that already; so I like the idea but I think the missing piece is advertising resources that are out there, although your list, the Fortran Wiki, and the fpm repository and lists on fortran-lang.org and other pages cover that more and more.

1 Like

In C, the intrinsics are functions such as printf (although technically they are part of the standard library). Fortran classifies as statements READ, WRITE, OPEN, INQUIRE, ALLOCATE etc. INQUIRE has specifiers, but one can think of it as a subroutine with intent(in) and intent(out) arguments.

I think the intrinsic descriptions project should eventually cover the statements of the language. The coverage may have to be incomplete, since book chapters have been written about READ and WRITE.

1 Like

Yes, I agree; but the intrinsics themselves seemed lacking good coverage and are more straight-forward. The function-like statements (READ, WRITE, ALLOCATE, STOP, …) that can be suitably described in something like a man-page format were partially covered and being worked on in the predecessor (fpm-man) and hopefully will be introduced; but a lot of material needs covered in a book or tutorial format that I didn’t envision being covered in this collection. I am picturing this as being more like a dictionary is to a language rather than a book; particularly since these are often glossed over in books that do provide in-depth discussions of programming topics. Hopefully some minibooks on those topics will emerge too. But definitely agree, many statements can be thought of as procedures or functions and should ultimately at least be syntactically covered here. I lot of them were WIPs, but did have a few started, but not included here yet

1423  data (7fortran)      - [FORTRAN] DATA statement
  1428  use (7fortran)       - [FORTRAN] gives a program unit access to public entities in a module.
  1429  include (7fortran)   - [FORTRAN] including source text
  1433  iso_c_binding (7fortran) - [FORTRAN] standard intrinsic module which defines named constants, types, and procedures for C interoperability
  1434  iso_fortran_env (7fortran) - [FORTRAN] standard intrinsic module provides public entities related to the Fortran environment
  1436  where (7fortran)     - [FORTRAN:ASSIGNMENT] masked array assignment
  1437  associate (7fortran) - [FORTRAN:EXECUTION CONTROL] associate construct (LICENSE:PD)
  1438  block (7fortran)     - [FORTRAN:EXECUTION CONTROL] construct (LICENSE:PD)
  1439  case (7fortran)      - [FORTRAN:EXECUTION CONTROL] select a block based on the value of an expression (a case)
  1440  continue (7fortran)  - [FORTRAN:EXECUTION CONTROL] construct (LICENSE:PD) 
  1441  cycle (7fortran)     - [FORTRAN:EXECUTION CONTROL] construct (LICENSE:PD)
  1442  do (7fortran)        - [FORTRAN:EXECUTION CONTROL] construct (LICENSE:PD)
  1443  endselect (7fortran) - [FORTRAN:EXECUTION CONTROL] select a block based on the value of an expression (a case)
  1444  exit (7fortran)      - [FORTRAN:EXECUTION CONTROL] statement (LICENSE:PD)
  1445  if (7fortran)        - [FORTRAN:EXECUTION CONTROL] selects a block based on a sequence of logical expressions.
  1446  select (7fortran)    - [FORTRAN:EXECUTION CONTROL] select a block based on the value of an expression (a case)
  1447  select_type (7fortran) - [FORTRAN:EXECUTION_CONTROL] select_type
  1449  inquire (7fortran)   - [FORTRAN:FILE_INQUIRE] File inquiry statement
  1450  backspace (7fortran) - [FORTRAN:FILE_POSITIONING] - backspace one record on specified I/O unit
  1451  rewind (7fortran)    - [FORTRAN:FILE_POSITIONING] rewind specified sequential access I/O unit
  1452  format (7fortran)    - [FORTRAN:INTRINSIC:I/O] Format statement
  1453  common (7fortran)    - [FORTRAN:INTRINSICS] specifies blocks of variables that can be accessed by any scoping unit in the program
  1454  equivalence (7fortran) - [FORTRAN:INTRINSICS] used to specify the sharing of storage units by two or more objects in a storage unit
  1455  flush (7fortran)     - [FORTRAN:IO] flush I/O buffers of specified files
  1456  open (7fortran)      - [FORTRAN:IO] Initiates or modifies a connection between an external file and a specified unit.
  1458  read (7fortran)      - [FORTRAN:IO] read data
  1459  wait (7fortran)      - [FORTRAN:IO] statement performs a wait operation for specified pending asynchronous data transfer operations
  1460  close (7fortran)     - [FORTRAN:IO] terminate the connection of a specified unit to an external file.
  1464  deallocate (7fortran) - [FORTRAN:STATEMENT] causes allocated variables and targets to be deallocated
  1465  nullify (7fortran)   - [FORTRAN:STATEMENT] causes pointers to be disassociated from a target
  1466  return (7fortran)    - [FORTRAN:STATEMENT] completes execution of the instance of the subprogram in which it appears
  1467  stop (7fortran)      - [FORTRAN:STATEMENT] initiates termination of execution
  1468  implicit (7fortran)  - [FORTRAN:STATEMENT] specify default type (if any) associated to a starting letter
  1469  namelist (7fortran)  - [FORTRAN:STATEMENT] specify a group of data to be referred to by a single name in data input/output
1 Like

There is a minor problem with the description of exp(cx) when cx is of type complex. The expression uses cmplx(cos(im),sin(im)), which is always of default kind. The correct description should be something like cmplx(cos(im),sin(im),KIND(cx)). Of course, this is because the cmplx() instrinsic is screwed up due to backwards compatibility, and it does not work in the expected/obvious way.

The example is default kind, but I agree that because cmplx(), to be backwards compatible, always defaults to the default real kind (UGH) the kind should be specified. Ironically that is a “gotcha” topic on an old FAQ collection of mine and I recommend always specifying the KIND there, so I changed the example accordingly to match your suggestion. I need to find a free moment and I will check all the documentation for the same. the issues with REAL and CMPLX really beg creating new intrinsics; or maybe re-invigorating FLOAT and DBLE.

I suggest that they be included in a minimal way. For each compiler it would be nice to have a two-column list where the left column has the extension and the right column the standard near-equivalent. The extension would have a link to vendor documentation. For gfortran, two examples are

system vs. execute_command_line
etime vs. cpu_time

Is there a list of non-standard functions and subroutines provided by gfortran? I don’t see them at Extensions implemented in GNU Fortran (The GNU Fortran Compiler).

info node for gfortran gives Part II → Extensions → Extensions implemented in GNU Fortran
E.g. on Ubuntu 20.04, the package gfortran-10-doc shows the following items in that menu:

  • Old-style kind specifications::
  • Old-style variable initialization::
  • Extensions to namelist::
  • X format descriptor without count field::
  • Commas in FORMAT specifications::
  • Missing period in FORMAT specifications::
  • Default widths for F, G and I format descriptors::
  • I/O item lists::
  • Q exponent-letter::
  • BOZ literal constants::
  • Real array indices::
  • Unary operators::
  • Implicitly convert LOGICAL and INTEGER values::
  • Hollerith constants support::
  • Character conversion::
  • Cray pointers::
  • CONVERT specifier::
  • OpenMP::
  • OpenACC::
  • Argument list functions::
  • Read/Write after EOF marker::
  • STRUCTURE and RECORD::
  • UNION and MAP::
  • Type variants for integer intrinsics::
  • AUTOMATIC and STATIC attributes::
  • Extended math intrinsics::
  • Form feed as whitespace::
  • TYPE as an alias for PRINT::
  • %LOC as an rvalue::
  • .XOR. operator::
  • Bitwise logical operators::
  • Extended I/O specifiers::
  • Legacy PARAMETER statements::
  • Default exponents::

It could be interesting to indicate in the Wikipedia pages of those functions that they are available in Fortran, with the standard version and a link toward the description of the intrinsic. For example, on the erf(x) page, we see at the bottom that it can be available in C in math.h:

Concerning erf(x) and erfc(x), I have done it in the French page.

3 Likes