Line continuation without implicit assumptions

Hello everyone,

Line continuations without & would be extremely useful for many things in Fortran.

  1. Declaring arrays, and calling large methods.

code

  1. Declaring associate blocks, without accidental mistakes.

codex

And many … many different things.

Although, I slightly disagree with how others are proposing to solve this.

Many well respected Fortran community members propose an “implicit” method of solving this issue, where line continuation would be implicitly assumed, for special cases, such as arrays, function statements etc.

Such a proposal is this: Implicit line continuation · Issue #130 · j3-fortran/fortran_proposals · GitHub

I slightly disagree with this, because it is a specific solution, to a specific problem of line continuation for arrays, where as we need a general solution that works for every line continuation issue that might occur, in older and future Fortran standards.

We need an explicit multi-line continuation command.

A simple example of an explicit multi-line continuation command would be to use &* and *& similar to how C/C++ uses /* and */ for declaring multi-line comments.

x = [ &*
1, 2,

3, 4, 5,
6, 7,

8] *&
associate ( &*
  cells => mesh%cells,
  nodes => mesh%nodes,
  nc => mesh%num_cells,
  nn => mesh%num_nodes ) *&

Since this is an explicit multi-line continuation command, this will work forever for all future Fortran standards, and with very minimal complexity for compiler developers.

This is just a basic idea, and I don’t have any strong opinions on the syntax of &* *&, so if other Fortran devs have an alternative syntax in their mind, I would humbly request them to share their ideas.

Thanks!

5 Likes

It’s clever, concise and general purpose. I kind of like it. Now the question of whether it’s worth the effort of getting in to the standard, I think it wouldn’t be that high on my priority list.

1 Like

@everythingfunctional Thanks! :slight_smile:

I think high priority should be given to generic data-structures and algorithms.

This line continuation feature should be medium priority, as it will fix a lot of issues regarding Fortran, which may not seem evident to us right now.

Implementing this should be easier than implementing the implicit method.

I’ve thought about this over the years. There are really three choice

  1. Indentation, white space : eg python
  2. Cont markers : eg fortran
  3. Scope delimiters. : eg c, c++. This is basically the op proposal

It comes down to style preference. The arg to make Fortran like another language convention is not a strong one. Each choice has advantages and pitfalls.

2 Likes

I like your idea. Maybe we’ll have it in 212Y :wink:

Meanwhile, I think editors should support something what I like to do manually myself:

associate(                   &
  cells => mesh%cells,       &
  nodes => mesh%nodes,       &
  nc => mesh%num_cells,      &
  nn => mesh%num_nodes )

I kind of like the way it looks when the line continuation symbols are neatly aligned and some space is left between the actual text.

Does anyone know some editors/plugins that do it? Specifically I would be interested in a Neovim plugin.

Edit. What I find annoying in the manual approach is the reorganization of those when something is changed.

  1. Infinite lines. Not really desirable but in other languages.

The example given by the op wouldn’t need the extra markup because they already have delimiters. So c style continuation would work. Ie read lines till close is found. “Fixes lots of problems “is mentioned but no examples are given.

Every method has issues. Wrong indentation, losing track of closing braces, readability, language consistency- do u you keep end if and end do or just allow c style scope delimiters.

I use a vim macro that gets the original left margin and then runs it through the GNU command
“column -t” and then indents it back to the original left margin; and afterwords I have sometimes hit a key that runs the file through a formatter like findent for consistency every though I do not like some of the formatting style (findent with my favorite options comes closest to what I do like by far, but that is somewhat a matter of taste). You have to watch where you put whitespace for column -t to be very appealing but if you know ahead of time you will run it through columnt that gets to be a natural habit. Probably have to be in a ULS (Unix-Like System) to have the column command, not sure if there is a Micro equivalent (?).

1 Like

Thanks for the idea! Any chance you could share your macro?

I will give a shot at extracting it. My vim setup has evolved from vi(1) macros to vim(1) highlighting and smartindent and autoformatting and functions so a quick try did not work.
Before all that I used a bash shell… Not sure you have bash but if you put this in a file in your path that is executable called “cl.vi” and add the function key definitions to $HOME/.exrc you can go to the top and enter “,a” and the bottom line and enter “,b” and then enter “,t” and it will run the filter on the marked region. It assumes you entered the text with the idea you would run it through the script so it assumes white space was used only as a column delimiter. Usually works. The macros are a bit smarter about it but at the cost of being a bit too complex. If I get the time it might be easier to put all the stuff into a github site for using Fortran with vim(1).

bash script
#!/bin/bash
################################################################################
#@(#) cl.vi - guess at column formatting Fortran assuming white space separates columns
#
# caveats: lines with quoted multi-word strings or containing @ character
#          assumes whitespace was made with running through this filter was planned 
################################################################################
# copy stdin to a scratch file
trap 'exit_status=$?; rm -f "$scratch" && exit $exit_status' EXIT
scratch=/tmp/vim-$(uuidgen)
####
# just change to as-is
#sed -e 's/[,;&=]/ & /g' > $scratch
cat >$scratch
####
#
# get attributes from first line
IFS='@' read LINE <$scratch
#echo "LINE=[$LINE]" 1>&2
# get number of columns ignoring inline comments
set $(echo "$LINE"|sed -e 's/!.*//')
colcount=$#
# get leading whitespace
indent=$(echo "$LINE"|sed -e 's/[^ ].*//')
#echo "indent=[$indent]" 1>&2
#
# format assuming all lines have same number of columns
# and anything past that should be left as-is as an inline comment
# and reindent
column -t -l $colcount $scratch|sed -e "s/^/$indent/"
exit
################################################################################
Add to .exrc file:
"===============================================================================
"|commands act only on the marked region from mark a to mark b
"|,a : Set ABOVE marks A and B so range for move, copy and delete is current line
"|,b : Set BELOW mark B
"|,t EXECUTE cl.vi using marked region as input and replace region with output
"|,e EXECUTE command using marked region as input and replace region with output
"    filter text thru commands like tr,pr,cb,asa,nasa,fold and such.
"===============================================================================
" Now to execute "function key a" you can enter ",a" (or still use "#a").
map , #
map #K mcHmdMme
map #a mamb
map #b mb
map #e #K'a!'b
" note literal ctrl-M at end of line. Use ctrl-v ctrl-m in insert mode to do that
map #t #K'a!'bcl.vi
1 Like

What do you mean here by “without accidental mistakes”? In my experience, implicit (or multi-line continuation) is much more error-prone and can be harder to diagnose. The errors (if they are caught at all), rather than being a local syntax error, can show up in a completely different part of the file.

Fortran Standards Committee preserves backwards compatibility and does not remove features.

So, if a user feels more comfortable with using single line continuation with &, then they can do that in all future standards.

Users who want to use multi-line continuation, will use the new feature.

Regardless the exact syntax I like the idea. That said, I don’t think the current line continuation rule is that bad. To me it’s quite readable:

associate ( cells => mesh%cells, &
            nodes => mesh%nodes, &
            nc => mesh%num_cells, &
            nn => mesh%num_nodes )

and not cumbersome to write (what can be cumbersome is manually aligning all the “&”).

In my experience the most frequent error is forgetting the “&” on some lines, so yes multi-line continuation would help. However what I would prefer is a mandatory continuation marker on the next line, rather than on the previous line, that is:

associate ( cells => mesh%cells,
&           nodes => mesh%nodes, 
&           nc => mesh%num_cells, 
&           nn => mesh%num_nodes )

This would have been easy to type and even more readable. I know that both can be used, but the mandatory one is on the previous line. I don’t know why this choice had been made… maybe because it’s easier to parse?

The first one makes more syntactic sense. Same reason it make less more sense to have the comma on the line being continued. Or an operator. It indicates the intention to continue and is easier to debug because the compiler will tell you there UA something missing after the comma or operator.

Note that in legacy fixed format, the continuation symbol was on the next line.