Syntax of interactive Fortran

Isn’t this supported by the standard? If not, I think that would diverge somewhat from working syntax.

If it is not supported, is it because it conflicts with anything in the language?

Milan already sort of answered my question.

I don’t know if it would conflict with anything or not. I think on the declaration side the extension seems natural and would not conflict with anything:

function eig(A) result(lam, c)
real(dp), intent(in) :: A(:,:)
real(dp) :: lam
real(dp) :: c(size(A,1))
...
end function

at the calls site you just put more variables on the LHS separated by comma:

lam, c = eig(A)

But I don’t know if it would conflict with anything.

1 Like

Yes, I thought about that. There are experiments with this in Python:

LFortran I think could reliably figure out the cell dependencies to rerun them. I would have to investigate how Pluto does that. I think we definitely want to try to implement it and experiment with it.

Another aspect are interactive widgets that Jupyter allows and we definitely want those working with Fortran also.

1 Like

It would be nice to be able to save a workspace (the variables declared and their values in the main program, module variables, values of any saved variables in procedures, procedure definitions, etc.) and then resume work by loading the workspace. R has this feature, and there appear to be ways to do this in Python.

1 Like

Great idea. At the very least, just printing the current workspace should be easy, the FortranEvaluator class in LFortran maintains a set of symbol tables for each cell, so we can print them.

To save and resume, we just need to serialize and deserialize and as long as we use pure Fortran, that should work. An issue will be things like open files (and C file descriptors). Given that in pure Fortran one accesses files using the builtin open/read/write/close, when things get serialized, one can save the file name and where it was in the file etc., and then just reopen when resuming. There might be other such issues to resolve. For example if you use some C library via iso_c_binding, the save/resume might not work, because how do we do that for some C code that we do not have access to?

Once this thread concludes, I need to create issues for each idea here.

1 Like

Not “a smaller language”, but a different language - once on that path, one can give it another fancy name at any stage even at the onset, other than Fortran that is - CCreole any one?

Yes, it looks like it will be called LFortran. :slight_smile:

1 Like

Maybe itran, where the “i” stands for interactive. I thought of iftran, but that is a structured extension of Fortran from the early 1970’s, and ifort collides with the command to invoke Intel’s “classic” Fortran compiler.

If LFortran gets the ability to save a transcript of the user’s input, a raw transcript that has non-Fortran such as bare expressions should not be saved in a file with a .f90 or .f suffix, to avoid confusion. If the quasi-Fortran (would that be a good pejorative name?) can be converted by LFortran to standard Fortran, only then would a .f90 suffix be appropriate.

I am a little surprised at your opposition to explore features to make Fortran easier to use interactively. Usually you are the one pushing for features to make Fortran easier to use. The good news is that even you agree on allowing statements at the global scope, which is the main thing to make Fortran interactive. I am hoping to convince you that also allowing expressions is a good thing, but I am also happy to provide a compiler option to disallow that, and you can just use that option. The expressions bring it on par with Python and Julia, it becomes functionally equivalent as far as I am concerned. The rest are differences in the language itself: syntax, semantics and features are a bit different / non-equivalent. But the way you use it interactively becomes equivalent.

Going beyond that is in my opinion equivalent of adding new features to Fortran, so we can follow the same approach, that is, we create a prototype, we try it, if we like it, we can pursue it further, if we do not like it, we do not need to pursue it further.

1 Like

One thing you might want to consider is whether it is at all possible to make an expression only version of fortran (I think the type system might not be powerful enough though). One of the reasons Julia feels as consistent as it does is that everything is an expression (there are no statements). There are many advantages to this, including easier introspection, more language consistency, and it’s just simpler.

1 Like

Maybe the design of the REPL interface can help to make interactive Fortran standard conforming yet comfortable to use. As far as I see it, one needs three tabs:

  1. declarations (including use of modules)
  2. the actual main program
  3. definition of functions (everything after contains)

The actual main program (2) would be the real REPL while (1) and (3) are more like an IDE. I actually use python (Ipython + a text editor) like that. I can imagine that it gives a very convenient workflow. Exporting to a valid source is also trivial, just concatenate the tabs. Some logic could even be used to remove unused statements in 2).

1 Like

@MarDie thanks for the comment. In the context of my comment Syntax of interactive Fortran - #13 by certik, what you proposed is the level 1 interactive Fortran, i.e. just a regular Fortran. You can use any Fortran compiler to work like that. One can even write a Jupyter kernel to make it work within Jupyter. The “interactivity” then means you have to rerun the cell with main program, the kernel would concatenate all the cells and run it through a Fortran compiler and run the binary and report results back.

However, it is not interactive in the sense of the word as I understand it, because the program runs “non-interactively”, i.e. you cannot access a variable from a running program and inspect it by printing it, or call some function from your program on that variable and then decide (as a person) what else to run from your program based on what gets printed (=interactivity). You can only modify things and then run them from start to finish. I don’t think there is a way to make it interactive at the Level 1, because the only way you can execute is to run the main program. To make it interactive, you need to be able to execute individual statements, which is Level 2 in my above comment.

I meant it a little bit differently. The main program (tab 2) runs interactively. Every statement (or series of statements in a cell) is executed immediately. This is similar to the python or julia REPL. The difference is in handling use statements + variable definitions (in normal Fortran at the top) and function/subroutine definitions (in normal Fortran at the bottom). These definitions reside in extra tabs to comply with the rigid Fortran layout.
Technically, this is equivalent to level 2 or 3, the user just has to switch tabs instead of typing everything into a single series of cells.
Re-running the whole main program is required if the type of a variable or function changes. That is a consequence of static and strong typing.

1 Like

In an interactive LFortran session, the user may create several double precision arrays of 1 or 2 (and sometimes higher) dimensions. There are many functions in Julia, Matlab, Octave, or Python with NumPy, TensorFlow, PyTorch that you may want to call with such array arguments, and ideally you could map Fortran arrays to arrays in those languages. It would be nice if you could type something like

!%R cor(x)

to call R cor and have the array x(:,:) from the LFortran passed to R, which computes and prints the correlation matrix of the columns of x, with similar functionality for other languages that have been installed. A deeper level of interoperation where you pass Fortran arguments to R and get back a Fortran derived type with the stored results of the R function needs to be done manually, but maybe shallow interoperation where the results of the function called in the “foreign” language are just printed is possible.

1 Like

Yes, that is planned. Here are the corresponding issues:

Applied to your example, it would be:

use, external(R) :: stats, only: cor
print *, cor(x)

This is all valid Fortran syntax, and the external part would be LFortran extension. LFortran would know from the way you call cor(x) what the exact function signature must be and from the use statement which language and which module it is in, and call R appropriately. (I updated this example code based on the comment below that cor is in the stats package.)

2 Likes

Cor is in the R stats package, but that is one of the few packages that always ships with base R – the user does not need to install it separately. It will be great if one can seamlessly call other languages from LFortran. In some cases one would be calling Fortran codes wrapped by R, Python or Octave, which is a bit inefficient, but other projects you and others are working on, such as stdlib or minpack, address the modernization of FORTRAN codes so that you can easily call them from Fortran.

1 Like