Remix.run Logo
IAmBroom 5 days ago

What practical difference ever existed, beyond the fact that a subroutine does not return a value? AFAIK variable scope was handled identically. Recursion was likewise identical (forbidden originally).

adrian_b 4 days ago | parent | next [-]

The very important difference is that what are called functions in Fortran are called pure functions in other languages, i.e. functions that do not modify their arguments or global variables and which are idempotent, helping program optimization.

This means that Fortran functions are functions in the mathematical sense. In most early programming languages "functions" were functions in the mathematical sense, while other kinds of subprograms were named procedures or subroutines. The use of the term "function" for any kind of procedure has been popularized mainly by the C language, even if there were earlier languages where all procedures could return a value and even where any program statement was an expression, starting with LISP.

Many C/C++ compilers, e.g. gcc, support language extensions allowing functions to be marked as pure. This is always recommended where applicable, for better program optimization.

This difference is much more important than the fact that subroutines do not return a value.

Many of the "functions" of C/C++ must be written as subroutines in Fortran, with an extra argument for the result, but because they modify some arguments or global variables, not because they were written as "void" functions in C/C++.

semi-extrinsic 5 days ago | parent | prev | next [-]

Functions return a value, subroutines do not. So functions can, at the whim of the compiler, cause an extra copy.

Style wise, many prefer to reserve functions for things that resemble mathematical functions (i.e. only intent(in) and pure). In some sense a little bit similar to how people tend to use lambdas in python.

adrian_b 4 days ago | parent [-]

In a well designed programming language, the compiler should always decide at its whim, whether input or output parameters need an extra copy or not, i.e. if they should be passed by value or by reference.

The programmer must only specify the behavior of the parameters, i.e. if they are input, output or input-output parameters, like in Ada.

The fact that a parameter is the result is just a matter of syntax, not of semantics. Any other output parameters should behave exactly like the result. This means that for any output parameter, like also for the result, the compiler must decide between receiving the output value in a register or passing an extra pointer on input that is the address of a memory area where the function must write the output value.

semi-extrinsic 3 days ago | parent [-]

Functions, the way we use them in mathematical equations, have a particular syntax. The point of functions in Fortran is to mimic this as closely as reasonably possible (consider it is a language with a long history).

Giving the user low-level control of how memory is used can be very useful for writing fast code. The compiler is not omniscient. Providing the choice is not bad language design.

atrettel 5 days ago | parent | prev [-]

They are pretty similar, but they are definitely used differently. For one, you have to "call" a subroutine in one statement, but you can use multiple functions on the same statement (since they can return values). Functions (usually) do not change their arguments, but subroutines often do. In some sense, functions are closer to how mathematical functions work but subroutines are closer to labels for certain procedures.

adastra22 5 days ago | parent [-]

So they are used differently, but there isn’t a language enforced difference (other than return value)?

adrian_b 4 days ago | parent | next [-]

There is a language enforced difference.

Fortran functions correspond to "pure" functions in C/C++ and other languages, i.e. idempotent functions that do not modify arguments or global variables.

If a C/C++ function is converted to Fortran, it must be rewritten as a subroutine, unless it is a pure function.

Not all C/C++ compilers support the language extension of marking functions as pure, and even with such compilers many programmers are lazy, so they forget to mark as pure the functions where this is applicable, even if this is recommended for improving program optimization and verification.

Fortran function were pure functions because this is the mathematical sense of the term "function". The extension of the meaning of the word "function" for any kind of procedure happened decades after the creation of Fortran.

The distinction between a "void" function and other functions has negligible importance. On the other hand the distinction between "functions" in the C language sense and "pure functions" is very important and programmers should better mark as "pure" all the functions for which this is true. This is at least as important for program optimization and for checking program correctness as declaring a variable with the correct type.

pklausler 4 days ago | parent [-]

> Fortran functions correspond to "pure" functions in C/C++ and other languages, i.e. idempotent functions that do not modify arguments or global variables.

This is nonsense. Fortran functions aren't pure. They can have side effects.

HPF/Fortran '95 added the PURE attribute for subprograms, but it's not the default.

pklausler 5 days ago | parent | prev | next [-]

Functions are called only within the context of expression evaluation, and Fortran allows a compiler to perform algebraic transformations on expressions. If you write X=Y*F(Z) and we can determine that Y is zero, the function call can be deleted. So side effects in functions are somewhat risky.

atrettel 4 days ago | parent | prev [-]

The language enforced difference is that only functions can return a value, but other than that, they are quite similar and just called "procedures" generally. In my experience, Fortran programmers use them differently in practice, and that is more of a guideline than something enforced by the language itself.