j3-fortran / fortran_proposals

Proposals for the Fortran Standard Committee
178 stars 15 forks source link

Pros and Cons of making keywords reserved #167

Open certik opened 4 years ago

certik commented 4 years ago

Currently Fortran has non-reserved keywords: words like begin, end, subroutine, result can be freely used as variable names, but they also have semantic meaning in the right context.

Here is a full list of the non-reserved keywords:

abstract, all, allocatable, allocate, assignment, associate, asynchronous,
backspace, bind, block, call, case, character, class, close, codimension, 
common, complex, concurrent, contains, contiguous, continue, critical, cycle,
data, deallocate, default, deferred, dimension, do, dowhile, double, elemental,
else, end, endif, end, enddo, end, endwhere, entry, enum, enumerator,
equivalence, errmsg, error, exit, extends, external, file, final, flush, 
forall, format, formatted, function, generic, go, if, implicit, import, impure,
in, include, inout, inquire, integer, intent, interface, intrinsic, is, kind,
len, local, local_init, logical, module, mold, name, namelist, nopass,
non_intrinsic, non_overridable, non_recursive, none, nullify, only, open,
operator, optional, out, parameter, pass, pointer, precision, print, private,
procedure, program, protected, public, pure, quiet, rank, read, real, 
recursive, result, return, rewind, save, select, sequence, shared, source,     
stat, stop, submodule, subroutine, target, team, team_number, then, to, type,
unformatted, use, value, volatile, where, while, write

The advantage of these being non-reserved keywords is that the standard can add new keywords in the future and they will not invalidate current code, because users can still use them as variable (or function, module, etc.) names.

The disadvantages are:

Furthermore, in my own codes and other codes, I recommend not to use these non-reserved keywords as variable names anyway. For example, one should not write code like this, even though it's strictly speaking valid:

integer function end(return,&
integer)result(function);;;;&
integer integer,return;;;;;;&
;;function=return;if(return>&
integer)return;;;;;function=&
integer;;end function end;;;;

I opened this issue so that we can brainstorm what can be done about this. Here is an idea:

certik commented 4 years ago

(I failed to find the definition now of "semi-reserved keywords". When I researched this about a year ago, I thought that's exactly what Fortran does. But perhaps the term means something else. Either way, that does not change the details of the above issue.)

FortranFan commented 4 years ago

@certik wrote:

.. I opened this issue so that we can brainstorm what can be done about this. Here is an idea: ..

I've wondered about this as well. Keeping in mind Fortran does not have a concept of NAMESPACEs but the language standard does have a concept of a scoping unit, a thought I have had for a while is whether a prefix-spec (a la PURE for procedures) can be introduced into the language which signals to the processor a scoping unit will not use any of the language keyword as a name for any of the entities (derived type names, named constants, variables, dummy arguments, etc.) in that scoping unit and also in any nested scoping units in that scope!

Possible names for this new prefix-spec are PURE, or SIMPLE, or CLEAN, or NEAT, etc.

For example, MODULEs and SUBMODULEs are scoping units as is a main program, or an external subprogram, or an interface body, a derived type definition, a BLOCK construct, etc.

Say the language allowed

PURE module foo_m  !<-- Suggested new prefix-spec
   use ..
   ..
   <some_type>, parameter :: ..
   type :: t
     ..
   end type
   interface ..
     ..
   end interface
   ..
contains
   subroutine ..
      ..
   end subroutine ..
   ..
   function ..
      ..
   end function ..
   ..
end module ..

And this were to inform the processor the above scoping unit cannot have a name clash in any entity in that scope with any of the keywords in the language, as listed by @certik above, then I think it provides a way to enforce a good coding practice (GCP) while also enabling better/faster tooling with such "clean" codes in Fortran.

Just a thought,

certik commented 4 years ago

@FortranFan good point, I haven't thought of that.

I really like the #83 approach, so there would simply be edition 202Y, which would enforce that keywords are not clashing. Existing code would stay with edition 202X, which allows keywords to clash, so existing code would continue to run unmodified forever. But if you want to upgrade to 202Y, one might need to ensure that keywords are not clashing.

sblionel commented 4 years ago

I disagree that there are ANY reserved or "semi-reserved" words in Fortran. At most there are syntax rules prohibiting statements that look like END but aren't. I've worked on Fortran parsers, so I think I would know if any kind of reserved words existed. A Fortran parser doesn't know about any reserved words.

@certik , please indicate why you think some words are "semi-reserved". Examples would be helpful.

[Edited to be more constructive.]

zjibben commented 4 years ago

@sblionel this comment comes off a tad aggressive. Please keep in mind our Code of Conduct, in particular we would like to create a welcoming environment for everyone here. Respectful disagreement is always encouraged!

sblionel commented 4 years ago

I thought I was respectfully disagreeing. If you think otherwise, please shoot me an email and explain.

certik commented 4 years ago

I edited the issue description and changed "semi-reserved" to "non-reserved". As I mentioned above, I was not sure about the terminology.

Since Steve asked, here is an example that Intel Fortran rejects, because it uses a keyword:

      parameterx = parameterx
      end

You have to compile in fixed-form mode (ifort -c a.f -o a.o). If one changes parameterx to parametex, then it compiles. One can probably find other such examples.

Finally, I should mention that people have asked me why we cannot make keywords reserved in Fortran that it would simplify a lot of things. So this is not some academic exercise. The community asked us, and I see it as our job to have a good answer plus associated discussion why this cannot be done (if that is the case).

sblionel commented 4 years ago

That example fails because, in fixed form, it uses a non-standard feature, the "typeless PARAMETER" statement. This had been part of FORTRAN 77 right up until the final version, where it was changed to the form in the standard today with parentheses and a typed value.

D:\Projects>type t.f
      parameterx = parameterx
      end
D:\Projects>ifort /stand t.f
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 19.1.0.166 Build 20191121
Copyright (C) 1985-2019 Intel Corporation.  All rights reserved.

t.f(1): warning #7373: Fixed form source is an obsolescent feature in Fortran 2008.
      parameterx = parameterx
^
t.f(1): warning #6474: Fortran 2008 does not allow this form of the PARAMETER statement.
      parameterx = parameterx
^
t.f(1): error #6592: This symbol must be a defined parameter, an enumerator, or an argument of an inquiry function that evaluates to a compile-time constant.   [PARAMETERX]
      parameterx = parameterx
-------------------^

DEC Fortran went ahead and implemented the typeless form because they thought it would become standard. Then they had to support both. This experience resulted in the DEC team (now Intel) refusing to implement features before they become published (either in a standard or a TS.)

A compiler without this extension would not have this problem. The example you presented does not reflect the standard.

certik commented 4 years ago

Indeed, I verified that gfortran compiles this without a problem.

tclune commented 3 years ago

Coming across this thread from a different context, but I do sometimes allow myself to use some of the words in the words in the Ondrej's list. In particular, to emulate STL containers, I allow myself to have type-bound procedures named begin and end. (And it was not that many years ago that gFortran would break when doing this sort of thing.) Other than highlighting, I don't find such limited usage confusing. But I agree with the general rule to avoid such things.