fortran-lang.org icon indicating copy to clipboard operation
fortran-lang.org copied to clipboard

Should fortran-lang.org provide reference to intrinsic modules?

Open milancurcic opened this issue 4 years ago • 12 comments

See PR #344 in ford, and specifically this comment by @ZedThree:

The Fortran wiki is probably still the best place for the intrinsic modules. fortran-lang.org looks shinier, but it doesn't seem to have all the info the wiki does.

It seems that there is a visual appeal to fortran-lang.org, and it has higher search ranking than any other Fortran website. Though FortranWiki provides nice references, they're outdated. at least iso_fortran_env and iso_c_binding that I looked at are.

Should we provide references to these modules under https://fortran-lang.org/learn?

CC @certik @LKedward @awvwgk @jrblevin

milancurcic avatar Jul 18 '21 15:07 milancurcic

Perhaps a new section Reference would be more suitable than Learn?

I've always missed something similar to https://en.cppreference.com/w/ or https://docs.python.org/3/. I've looked at their pages and setup before but unfortunately I lack the time or webpage skills to get something started.

Starting with the intrinsic modules would be a great way to get the ball rolling.

ivan-pi avatar Jul 18 '21 17:07 ivan-pi

I imagined Reference would be a mini-book under Learn, but a separate page would work as well.

milancurcic avatar Jul 18 '21 17:07 milancurcic

Yes, fortran-lang.org/reference would be perfect. An "official" (=community approved) reference to all intrinsic functions and language constructs in a searchable form. We definitely need that.

certik avatar Jul 18 '21 20:07 certik

Fortran badly needs an equivalent to cppreference, including their compiler support page. There's something similar on Fortranwiki, but it uses data from the Fortran Forum which is "does the latest version of compiler support feature", as opposed to cppref's "in what version did compiler first support feature".

It might be useful to note that cppref is a wiki, but with a curated/managed structure.

ZedThree avatar Jul 19 '21 09:07 ZedThree

@urbanjost has the full reference as man pages:

milancurcic avatar Jul 20 '21 20:07 milancurcic

Actually, I moved the fpm plugin to plugins. The link above still works, but I deleted that repository a while ago, and last I remember that means it will actually vanish at some point. I had several things including the platform-independent plugin I wanted to try (particularly useful on MSWIndows which does not typically have the man(1) command unless installed via Cygwin or some form of Linux) and wanted to make a Fortran version of txt2man and so on, and was thinking that putting a group of the man-pages by category out each month on Fortran Discourse or Learn (or ...?) for group comment/editing might be useful; have been planning on some time of migration to fortran-lang for something like a year and never quite had the time. If what I have is a useful seed I am open to ideas on how to leverage it for this purpose. The way I have it now lets me just edit plain text and automatically convert it to the M_intrinsics module for use by the plugin and actual man-pages via txt2man(1) which are things I want and have set up (in a very singular way) as a push-button operation, including extracting and building all the example programs in the man pages and I did not want to loose that, but I think having at least the intrinsic descriptions sans vendor extensions (or explicitly marking them as such) is worth pursing and some of this shouldl be usable for that purpose.

urbanjost avatar Jul 21 '21 01:07 urbanjost

Is this something I could help with? We need all this information online in a nice modern-looking format with syntax highlighting, links, maybe even diagrams if necessary. So, for that we'd have to abandon the man format. I could take a crack at converting it to markdown.

Note: FortranWiki and also the Gfortran docs are both GPL (GFDL) I believe. Is that something we want to avoid? Otherwise, we could incorporate some of that as well.

jacobwilliams avatar Sep 05 '21 21:09 jacobwilliams

Oh I see now that @urbanjost's content is already GFDL since it is already based on those pages.

jacobwilliams avatar Sep 05 '21 21:09 jacobwilliams

This is absolutely worth pursuing.

Regarding the license, I strongly recommend using BSD or MIT for the documentation also. The GFDL has number of issues:

  • https://en.wikipedia.org/wiki/GNU_Free_Documentation_License#Criticism.
  • https://wiki.debian.org/DFSGLicenses#GNU_Free_Documentation_License_.28GFDL.29

I would like to be able to include such documentation either with LFortran, or (even better) with our (future) VSCode extension where you point your cursor at an intrinsic, hit a button, and it will load documentation for it (locally, so that it can work offline).

certik avatar Sep 06 '21 00:09 certik

The two main approaches would appear to be to make the documentation as nice as possible on the fortran-lang site and then see how to use it from a CLI environment, or to make it useable in a CLI environment and then place it as best as you can on fortran-lang.

In this case the approach was primarily the second. The man-page format is a good one regardless for describing intrinsics, but not the best for providing a description of Fortran in general. But the structure of a man-page is good for describing procedures so this was treated as a special case. Some of the considerations were

Each vendor supplies a browser-based www description of their intrinsics, but with the descriptions often conflated with their own extensions and/or not including functions they have not implemented yet. So there is room for a complete standard-based description of intrinsics on the web, but there are the mentioned alternatives, and they do include descriptions of extensions, which can be valuable even at the cost of portability.

The standard itself is the ultimate description, but is not easily available in a CLI environment and is written to be definitive at the cost of being clear and concise and it is a bit unclear on whether even the last draft can be reused without licensing issues.

All of the above rarely contain completely functioning example code.

manpages are still in extensive use and still heavily used by C developers, as well as by many other languages. So since the route I took making M_intrinsics and the associated files deserves some explanation, here is some background:

manpages are already integrated into a good number of CLI tools; such as vim(1). For example, if editing Fortran code you can place your cursor on a word and hit a capital K and you will be taken to a man-page for that word.

*roff is still the language used to create a man-page (why on earth the man(1) command does not also support HTML is beyond me).

An ideal description could be included as block text in program comments, produce readable output for Ford and Doxygen, be used to generate a man page, be easily converted to HTML, be a simple flat-text or simple markup language that virtually anyone can write without learning *roff or LaTex and be accessible in any Fortran environment, and require little or no additional software installed to be used, and support whatever documentation standard emerges for describing fpm packages and stdlib.

The closest to flat text of any markup language is that provided by txt2man, so that man-pages literally look like flat text. That format is relatively compatible with Ford/Doxygen just be adding a few comments. So the prep(1) preprocessor allows you to create plain blocks of text that can be written to a file for processing via txt2man(1). Simultaneously it can convert the text to Fortran comments to document the code, and the comments can be massaged to work with Ford/Doxygen (prep(1) still needs some work along those lines). Although not of the best quality, man-pages can be converted easily to HTML (and many other formats) and served on web servers via several commonly available packages. man-pages can be used on all GNU/Linux and Unix platforms as well as CygWIn. Since info(1) can read man-pages and automatically produce cross-links to references like sin(1), and the HTML pages generated from man-pages can be used lynx/links/w3m in other CLI environments or by any browser that covers a lot of group.

The intrinsic man-pages can then be written as txt2man input files for easy maintenance and then converted to manpages and bundled. For environments without man(1) or info(1) (note mingw64 contains info(1) but not man(1). Not sure if info(1) can read man-pages if man(1) is not on the platform, but that was the original hope). In addition, since txt2man(1) markup is a matter of context and indenting and whitespace and not special characters it can be used as flat text for a simple utility to display the text on any platform. Along those lines, to create such a utility that requires no other files the markdown files are converted to a format accessible from a Fortran program automatically -- (see the M_intrinsics module, available as an fpm(1) module). An fpm(1) plugin utility (originally designed to be called directly by fpm(1), actually) called fpm-man(1) can then be used to easily access the man-pages from ANY Fortran environment, albeit not (currently) with hyperlinks or color). As long as a certain convention is followed that program can also extract the demo programs in the man-pages.

So:

  1. the documents can be written in a nearly flat-text style.
  2. This style can easily be learned and included in Fortran code using a preprocessor. prep(1) already supports this, and it seems it would be easy to add to fypp(1) as well.
  3. the documents can automatically be converted to man-pages; which is still the closest to a standard procedure and command description utility GNU/Linux and Unix has, and the current runner-up is info(1) which can display man-pages
  4. tools such as vim(1) hook into man-pages
  5. almost any GNU/Linux box or Unix box can automatically convert man-pages to HTML or PDF, albeit not of create quality; and HTML is the closest to a lingua-franca that I know of.
  6. a program has been created to allow for displaying the flat-text versions in any Fortran environment, and incorporates an a plug-in to fpm(1).

So the main goals decided on where

There is a stronger need for documentation being available on a per-intrinsic basis in CLI environments than as a web document, but there is room for both.

There should be a basic CLI interface available in any environment that depends on little or no infrastructure that hooks into fpm(1) as a plug-in.

The man-page format is a good one for intrinsics that many people are familiar with even outside of the context of the man(1) command itself.

And of course, this format was already built into my own build process as a way to document my code (essentially everything I write has text blocks in them for documentation purposes (sometimes HTML or LaTex, but mostly txt2man input) that is run through prep(1) or it's big brothers, and I wanted to minimize the effort it would take me!

urbanjost avatar Sep 07 '21 04:09 urbanjost

So I have my own programming environment, but this would let you roughly simulate it on a GNU/Linux box. Assuming you have a directory called "github" off your home directory and that the default directory $HOME/.local/ for your fpm(1) prefix is OK and that you have the directory $HOME/.local/pdq in your path, you can create a file anywhere with a Fortran code in it that optionally goes through the prep(1) pre-processor if ending in the ".ff" suffix that has a manpage in it and uses your favorite fpm(1) packages (as arbitrarily listed in the script, which would need customized) you can just say "ff filename.ff" and you have comments in your code, and a txt2man(1) input file in $HOME/github/man that a simple script processes and creates a manpage and HTML document from. So your code is documented, you have a manpage for the code, and an HTML version of the manpage built, and your code is built and installed in the test directory in your search path using your favorite fpm(1) dependencies.

This was the shortest I could find quickly. So I can write a program with a simple manpage in it as a plain text block, make calls to most POSIX routines via ISO_C_BINDING interfaces, and call a command-line argument parser and build and install my program in my path using fpm(1) like all of that was a standard part of Fortran with a single command. At some point I would like us to add something like that via an fpm(1) plugin where stdlib supplies a lot of functions like that, but we need to standardize on how to call different preprocessors, use fpm(1) as a package that has an API to the backend engine, and so on. The "ff" script shown here is a kluge that needs customized by each user but is just for demonstration purposes. I know it is all possible because I have something similiar (ccall(1)) that I have used for years like it; and I can write a little utility in Fortran faster than I can in python or bash using it.

program demo_system_gethostname
use  M_kracken, only : kracken, lget
use M_system, only : system_gethostname
implicit none
character(len=:),allocatable :: name
integer                      :: ierr
   call kracken('hostname','-help .F. -version .F.')
   call help_usage(lget('hostname_help'))
   call help_version(lget('hostname_version'))
   call system_gethostname(name,ierr)
   write(*,'(a)')name
contains
$BLOCK HELP -file _hostname.1.man
NAME
    _hostname(1f) - [FUNIX] display hostname
    (LICENSE:PD)
SYNTAX
    _hostname [ -help|-version]
DESCRIPTION
    Calls system_gethostname(3f), which calls get_hostname(3c) to determine
    the current host name.
OPTIONS
       --help     display this help and exit
       --version  output version information and exit
EXAMPLE
   Sample execution:

    >_hostname
    >buzz
$BLOCK END
$!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
$BLOCK VERSION
PRODUCT:        GPF (General Purpose Fortran) utilities and examples
PROGRAM:        _hostname(1f)
DESCRIPTION:    print hostname
VERSION:        1.0, 2016-12-01
AUTHOR:         John S. Urban
REPORTING BUGS: http://www.urbanjost.altervista.org/
HOME PAGE:      http://www.urbanjost.altervista.org/index.html
LICENSE:        Public Domain. This is free software: you are free to change and redistribute it.
                There is NO WARRANTY, to the extent permitted by law.
$BLOCK END
end program demo_system_gethostname
#!/bin/bash 
#@(#) given a source file for a program build it with preprocessing via prep(1) default list of packages and install

###############################################################################
export FF_DIR=$HOME/github/ff_cache
export PREFIX=$HOME/.local
export BINDIR=pdq
export PREP_DOCUMENT_DIR=${PREP_DOCUMENT_DIR:-$HOME/github}
#export PREP_COMMENT_STYLE=ford
###############################################################################
SHORT(){
case "${1}" in
 *.f90) SHORTNAME=$(basename $1 .f90) ;;
 *.ff)  SHORTNAME=$(basename $1 .ff)  ;;
 *.FF)  SHORTNAME=$(basename $1 .FF)  ;;
 *.F90) SHORTNAME=$(basename $1 .F90) ;;
 *.c)   SHORTNAME=$(basename $1 .c)   ;;
 *)     SHORTNAME=$(basename $1) ;;
esac
}
###############################################################################
NEWTOML(){
cat >$FF_DIR/fpm.toml <<EOF
# TOML file for fpm as described at https://github.com/fortran-lang/fpm/blob/master/manifest-reference.md
name = "fpm_cache"
version = "0.1.0"
license = "MIT"
author = "John S. Urban"
maintainer = "[email protected]"
copyright = "2020 John S. Urban"
description = "compiled by fpm(1)"
categories = ["General Purpose Fortran"]
keywords = ["fortran", "fpm" ]
homepage = "https://github.com/urbanjost"

[install]
#library="false"
library=false

# this is used because changing the package name causes a rebuild of dependencies
# and editing or replacement of the build/cache.toml file
[[executable]]
name="$SHORTNAME"
source-dir="app"
main="$MAIN"

[dependencies]
M_args        =  {  git  =  "https://github.com/urbanjost/M_args.git"        }
M_CLI2        =  {  git  =  "https://github.com/urbanjost/M_CLI2.git"        }
M_CLI         =  {  git  =  "https://github.com/urbanjost/M_CLI.git"         }
M_kracken95   =  {  git  =  "https://github.com/urbanjost/M_kracken95.git"   }
M_kracken     =  {  git  =  "https://github.com/urbanjost/M_kracken.git"     }

M_draw        =  {  git  =  "https://github.com/urbanjost/M_draw.git"        }
M_history     =  {  git  =  "https://github.com/urbanjost/M_history.git"     }
#M_intrinsics  =  {  git  =  "https://github.com/urbanjost/M_intrinsics.git"  }
M_io          =  {  git  =  "https://github.com/urbanjost/M_io.git"          }
M_LA          =  {  git  =  "https://github.com/urbanjost/M_LA.git"          }
M_list        =  {  git  =  "https://github.com/urbanjost/M_list.git"        }
M_msg         =  {  git  =  "https://github.com/urbanjost/M_msg.git"         }
M_process     =  {  git  =  "https://github.com/urbanjost/M_process.git"     }
M_sort        =  {  git  =  "https://github.com/urbanjost/M_sort.git"        }
M_strings     =  {  git  =  "https://github.com/urbanjost/M_strings.git"     }
M_system      =  {  git  =  "https://github.com/urbanjost/M_system.git"      }
M_time        =  {  git  =  "https://github.com/urbanjost/M_time.git"        }

#M_messages    =  {  git  =  "https://github.com/urbanjost/M_messages.git"    }
#M_stopwatch   =  {  git  =  "https://github.com/urbanjost/M_stopwatch.git"   }
#M_random      =  {  git  =  "https://github.com/urbanjost/M_random.git"      }
#M_math        =  {  git  =  "https://github.com/urbanjost/M_math.git"        }
#M_regex       =  {  git  =  "https://github.com/urbanjost/M_regex.git"       }
EOF
}
################################################################################
DISPLAY(){
cat <<EOF
================================================================================
   NAME       $NAME
   SHORTNAME  $SHORTNAME
   MAIN       $MAIN
   TOML       $(grep $SHORTNAME $FF_DIR/fpm.toml|xargs)
   INSTALL    fpm install $OPTS --prefix $PREFIX --bindir $BINDIR --verbose
   OPTS       $OPTS
================================================================================
tree $FF_DIR
#read PAWS
EOF
}
################################################################################
DISPLAY(){
cat <<EOF
================================================================================
   NAME       $NAME
   INSTALL    fpm install $OPTS --prefix $PREFIX --bindir $BINDIR --verbose
================================================================================
tree $FF_DIR
#read PAWS
EOF
}
################################################################################
NAMES=''
OPTS=''
for NAME in $*
do
if [ -e $NAME ] 
then
   NAMES="$NAME $NAMES"
else
   OPTS="$OPTS $NAME"
fi
################################################################################
done
case "$OPTS" in
*-profile*);;
*) OPTS="$OPTS --profile release" ;;
esac
################################################################################
for NAME in $NAMES
do
   SHORT $NAME
   if [ ! -d $FF_DIR ]
   then
      fpm new -app $FF_DIR
      rm $FF_DIR/app/main.f90
   fi
   case "$NAME" in
   *.ff)  MAIN=$SHORTNAME.f90;prep -D TESTPRG90 -i $NAME -o $FF_DIR/app/$MAIN;;
   *.FF)  MAIN=$SHORTNAME.F90;prep -D TESTPRG90 -i $NAME -o $FF_DIR/app/$MAIN -system;;
   *.F90) MAIN=$SHORTNAME.F90;cp $NAME $FF_DIR/app/$MAIN;;
   *.f90) MAIN=$SHORTNAME.f90;cp $NAME $FF_DIR/app/$MAIN;;
   *.c)   MAIN=$SHORTNAME.c;cp $NAME $FF_DIR/app/$MAIN;;
   esac
   if  test ! -f "$FF_DIR/app/$MAIN"
   then
      echo file "<ERROR> $FF_DIR/app/$MAIN is not a file"
   fi
   if  test ! -s "$FF_DIR/app/$MAIN"
   then
      echo file "<ERROR> $FF_DIR/app/$MAIN has no length"
   fi
   NEWTOML
   DISPLAY
   (
      cd $FF_DIR
      fpm install $OPTS --prefix $PREFIX --bindir $BINDIR --verbose
      rm $FF_DIR/app/$MAIN
      rm -f $FF_DIR/app/*
   )
done
################################################################################
exit
################################################################################

urbanjost avatar Sep 07 '21 05:09 urbanjost

This has been resolved with the intrinsic documentation in the learn section

awvwgk avatar Aug 06 '22 09:08 awvwgk