-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Naming Conventions, which one? #5
Comments
For quite a few years I have personally preferred the style used in the Fortran standards - reserved Fortran words in all uppercase, variables lower-case, underscores for multi-word variables, camelCase for procedure names, for example: TYPE :: datetime
INTEGER :: year = 1 ! Year [1-HUGE(year)]
INTEGER :: month = 1 ! Month in year [1-12]
INTEGER :: day = 1 ! Day in month [1-31]
INTEGER :: hour = 0 ! Hour in day [0-23]
INTEGER :: minute = 0 ! Minute in hour [0-59]
INTEGER :: second = 0 ! Second in minute [0-59]
INTEGER :: millisecond = 0 ! Milliseconds in second [0-999]
REAL(KIND=real_dp) :: tz = 0 ! Timezone offset from UTC [hours]
CONTAINS
PROCEDURE :: addMilliseconds
PROCEDURE :: addSeconds
PROCEDURE :: addMinutes
PROCEDURE :: addHours
PROCEDURE :: addDays
PROCEDURE :: isocalendar
PROCEDURE :: isoformat
PROCEDURE :: isValid
PROCEDURE :: now
PROCEDURE :: secondsSinceEpoch
PROCEDURE :: strftime
PROCEDURE :: tm
PROCEDURE :: tzOffset
PROCEDURE :: utc
PROCEDURE :: weekday
PROCEDURE :: weekdayLong
PROCEDURE :: weekdayShort
PROCEDURE :: yearday
ENDTYPE datetime I thought this one was quite nice because it is easy to distinguish Fortran constructs from variables, making them overall more visible to the eye. However, over the past year or two during which I've been reading a lot of other people's code written mostly in lower-case, my eyes and brain got re-trained to read lowercase more easily, and I have found myself writing mostly lowercase for Fortran constructs and variables, while still employing camelCase where appropriate. For the same reason I do not prefer all uppercase code, I also do not prefer exclusively lowercase code. Fortran syntax is not case-sensitive, and by intelligently employing uppercase characters we can improve the readability of the code. |
I started out with upper case for keywords, but eventually concluded that (1) It’s unnecessary if one is using an editor or IDE with syntax-aware coloring. I get great coloring of keywords in vim and different types of keywords have different colors so there is more information than in the binary choice of lower versus upper case. And all the colors are pleasing to my eyes. :) I think many people will find underscores more quickly readable than mixed case. I therefore prefer add_milliseconds over addMilliseconds. I use mixed case in situations where underscores are not allowed, e.g., in defined operators: type foo and of course I use mixed case in the “name=“ field of bind(C) procedures when applicable. Otherwise, lower case + underscores mostly serves my needs and has some readability benefits. Damian Rouson, Ph.D., P.E.
|
I don’t think longer is inherently a bad thing and in fact I’d say longer is usually good if it adds meaning. Local shortening is often possible with the ASSOCIATE construct. (The one place where I often use all caps is in emails because I don’t know of an email client that does syntax-aware coloring.) Damian |
Thank you Damian for all the great input. An example in which I believe a different style for procedures and variables may be helpful is when a reader does not know whether something like: lb = field % lower_bound(n) is a function call or a reference to an array element, due to these two operations having the same syntax. Of course, we could encapsulate all the derived-type data and then it would have to be a function call! :) |
@milancurcic I agree with Damian about uppercase convention: from the time I have an editor with syntax highlighting (obviously VIM, what else? 😄 ) I preferred to avoid uppercase. Indeed, my motivations are different from the Damian's one: I am quite lazy, thus if I can avoid to press shift or caps lock I follow this energy saving way. Anyhow, I am going to update the first post of this issue with your suggestion. |
Wonderful example! From google group CLF there should be some suggestions on that, I will try to dig into it. |
My two cents (knowing that I would appear to have been over-ruled in at On 12/01/16 08:57, Stefano Zaghi wrote:
Chris MacMackin |
Hi all, I was reading the comments of this issue and I'm going to write my opinion in the following lines. Hope to be helpful. (Sorry in advance for my english) I'm agree with the previous post of @milancurcic , for me, camelCase for procedures is preferable. If I use underscore I finally have procedure names like: subroutine perform_an_action_with_this_variable_of_type_XXX_while_this_context
end subroutine Instead of: subroutine PerformAnActionWithThisVariableOfTypeXXXWhileThisContext
end subroutine Sometimes, to save a single character is enough to get a more expressive procedure name and avoid the following error: Error: Name at (1) is too long I also think that a good practice using TBP's is to put the name of the derived data type as a prefix of the procedure, it allows move code from a file to a different file without changing the procedure names, refactoring/renaming, copy/paste, etc. in an easy way. type :: my_object
contains
procedure :: action => my_object_perform_an_action_with_this_variable_of_Type_XXX_while_this_context
end type
subroutine my_object_perform_an_action_with_this_variable_of_Type_XXX_while_this_context
end subroutine Instead of: type :: my_object
contains
procedure :: action => my_object_PerformAnActionWithThisVariableOfTypeXXXWhileThisContext
end type
subroutine my_object_PerformAnActionWithThisVariableOfTypeXXXWhileThisContext
end subroutine I think that both ways are readable, but underscore doesn't add any meaning to procedure names and ... I need every character! 😆 |
I agree with @victorsndvg that it is really important to ensure that the procedures that TBPs resolve to have very descriptive and informative names, although I think there is some movement towards smarter IDEs/editors knowing about TBPs. I think @rosenbrockc has done some work in this area, at least for Emacs. I will just weigh in with my personal preference, from what I can remember/think of off the top of my head
Also, I just want to say, that I am not locked into these conventions, and would be more than happy to adapt to a sane alternative. While I have strong feelings (currently) that naming things following the convention I outlined above is doing it "the right way"™️ I am not so stubborn as to not be willing to change my mind or adopt a common practice for the sake of collaboration. |
Hi, I don't believe there can be any definitive true naming convention for Fortran. Consistency within a project is more important. My 2 cents:
I do not like any suffixes for module names. One could argue about their usefulness for derived type names. The reason is again the case insensitivity. While in Java and C++ the correct way is:
in Fortran
won't work. For this reason I can imagine using the |
I’ve decided to keep CamelCase for module names and type names. At the very least this limited the amount of file renaming that I had to do to go with the style change, but it also has a certain logic. Type names are “proper nouns” in the language, and as such, I at least one to capitalize them. I find that CamelCase helps to accentuate this when the noun is multiple words. But more importantly it often solves another issue that is mentioned down below.
type (SphereShape) :: sphere_shape ! or just sphere Of course I often find that if I want my variable name to have the same name as the type (class), then I may not have given enough thought to how one or the other ought to actually be named. They are different categories of entities after all. But it seems largely unavoidable in short examples and such.
Thomas Clune, Ph. D. [email protected] |
The guidelines I wrote up that @szaghi quoted above seem to be the common denominator. As @LadaF, @tclune and others stressed, one should use lower case. That implies underscores, except short names of perhaps 2 words. The exception are mathematical symbols, perhaps an array variable The |
I would add that it it seems natural for result names to have noun in them as in the following: function construct_foo_from_nothing() result(new_foo)
Damian |
I meant to add earlier in this thread, that I too used to use the “t” suffix. Also flirted a bit with prefix “t”. I’ve ultimately found them superfluous, though I admit that for short type names it does help disambiguate from a variable name. (So avoid short names …) I do however want my module to have the same name as the derived type that is defined in the module. My usual pattern is to define one “class” per Fortran module. But the language does not allow the module to have the same name as the type it provides. Here is the solution I currently use: module pkg_SphereShape_mod The prefix “pkg_” is used for all modules in the package. This helps to prevent namespace collisions when the package is brought into another project. I find it unnecessary to burden the type name itself with the pkg. Unfortunately I’ve not yet back propagated this approach to pFUnit where it would probably help there more than most packages. But it is on my todo list. I could probably drop the “_mod” suffix now that I’ve adopted the pkg prefix conventon. But I’ve used “_mod” for so long that I just don’t feel much pressure to make the change.
Thomas Clune, Ph. D. [email protected] |
On the issue of needing to distinguish module names from the names of other entities (notably types), wider access to submodule support recently inspired me to adopt a convention of appending FYI, for anyone who hasn't tried them yet, I highly recommend working submodules into your coding. The Fortran world is long overdue in addressing compilation cascades. Because mentioning bleeding edge features invariably leads to discussions of availability and because I believe most people are unaware of how widely available some of the newest features are, I'll summarize the state of compilers here from memory. Please feel free to ignore the rest of this post if the status of compilers is not of interest. I'm pretty certain that submodules are supported by recent versions of the following compilers:
And just for completeness, each of the above compilers supports the Fortran 2015 features for further interoperability with C and the Cray and GNU compilers support several Fortran 2015 additional parallelism features. If anyone is interested in free access to submodules, but doesn't want to deal with the hassle of building gfortran 6.0.0 from source, it should in general be possible to download the OpenCoarrays build script, make it executable, and simply type ./build gcc trunk or ./build gcc trunk /your/desired/installation/path If you go with the latter approach, you will later be prompted for a password if the chosen path requires administrator privileges. Damian *parameterized derived types |
Dear all, I would like just to say thank you for your great help, it is very appreciated. Maybe it was not clear, but I am trying to summarize all the best being into you into my leading post: as you insert your suggestions/opinions, I update my original thread summary. Thus, please check my summary and in the (probable) case I have made mistakes, advice me. Cheers. P.S. @rouson your post on compilers & co. is very appreciated, it will be grabbed and inserted into a dedicated issue as the other on CAF. |
As a follow up to my last post, I'm going to go way out on a limb here and make a statement that is intentionally provocative: I feel sufficiently strongly about submodules that I would include it as a requirement for any new Fortran development project to be considered "modern". Of course, I'm not suggesting that big, existing projects must be refactored, but everyone knows I'm big of design patterns and one of the two central mantras in the book that launched the field of object-oriented design patterns was "Program to an interface, not an implementation." There a several ways to follow that advice, but one way is to put only public interface information in the module and then put all private implementation details in submodules. I can't think of many strong reasons not to make the above practice universal in new projects except possibly compiler support, but I would venture a wild guess that one or more of the four aforementioned compilers is the production compiler for 80% of Fortran programmers. Most of the remaining 20% are probably using the Portland Group compiler for its support of CUDA Fortran, especially on platforms such as Titan. If that's the case, I say speak loudly to Portland Group about working on Fortran 2008 support. They haven't been hearing much demand from users even though I'm certain there are many people who want Fortran 2008 features. With that said, we could use a few compiler folks in this discussion. |
I agree that it is good guideline. However, I like to dedicate a separated thread to it, here I prefer to discuss on naming convention. By the way feel free to open any new issue you (meaning all of you, this English ambiguity puzzles me) like to discuss. But, just because you mentioned it 😄 , I would like to say that the reasons why I have not yet adopted it as a mantra are
You (meaning Damian...) solved the latter, I have to study to solve the first. |
Damian, Could you post a demagogical submodule example for those of us that would rather learn that way than by reading a book?
Thomas Clune, Ph. D. [email protected] |
@szaghi Possibly I should have made more clear how this relates to the naming convention. I believe that many of us have grappled with how to name our modules to distinguish them from entities inside the module. Submodules inspired a naming convention that eliminates this dilemma. I'm no longer tempted to write
because there is no longer a one-to-one relationship between the type and the scope that encapsulates the type. Now the type definition (which is part of the type's public interface) is in one scope (the module), whereas the type implementation is in another so there no longer remains a temptation to name the module something that the language doesn't allow. I hope this makes the connection to this thread more clear. |
@rouson 👍 wow, I does not consider this point of view! |
@rouson sorry, you now confuse me... type definition/implrmentation where? Please, consider to add at least a very small example 🙏 |
The following works with gfortran 6.0.0:
The naming convention makes clear that it's possible to change the implementation without having to recompile the main program because the main program only depends on the interface. This is what prevents compilation cascades where changing the internals of a procedure forces the recompilation of everything that depends on that procedure even if such recompilation is unnecessary because the only thin the dependent procedure really cares about is the interface information (for linking purposes), which might not have changed. For many moons, I have been meaning to write a blog. I think I should make this the first one, given that I'm proposing that this become a ubiquitous practice. |
@rouson thanks a lot! Two things:
|
Ok I think I am wrong about compilation cascade... it should be
|
I'm not sure I understand your notation. Let's say "=>" means "explicitly references". Then program => module The program explicitly references the module and needs to be recompiled only if the module changes. Let's take an example. I believe it communicates more to the reader to explicit state the unit number rather than an asterisk so now I'll edit the subroutine implementation to read the following:
Because I have not changed the corresponding interface body (which is inside the interface block inside the module), I don't need to recompile the main program because it doesn't explicitly reference the submodule. The main program only references the module. I should say there is also an implicit assumption that the module and its submodule(s) are in separate files. At least if one is using the make utility to build code, there would be no way of avoiding passing both the module and submodule to the compiler if they are in the same file. And I doubt a compiler exists that would figure out that the module doesn't need to be recompiled (e.g., by checking the corresponding .mod file) if the module and submodule are in the same file. The module and submodule will need to be in separate files to avoid unnecessary recompilation. |
@rouson I'd just like to mention that PGI is today the dedicated Fortran compiler with Nvidia GPU support - both for CUDA Fortran and OpenACC there is AFAIK still no viable alternative. It could become even more widespread now that it is free to use on one node and can be downloaded directly from Nvidia. My point is, I'd advocate against using language features for now that are not supported by relatively widespread compilers that cannot be replaced for their usecase. IMO we should work toward Fortran code being as portable as possible on today's common HPC architectures, and GPUs are one of them. I fully agree that Fortran 2008 features should be demanded more from PGI and I will address this in their support forum so it gets on their radar. |
@muellermichel Thanks for your input and especially thanks for agreeing to address this in their support forum. It would be great if other PGI users would do the same. The Fortran community is a very quiet community in some respects -- compiler vendors frequently comment to me that they aren't hearing request for the new standard features and yet I know from the classes that I teach that people are very interested in the new features (although I'm sure there's a self-selection process wherein those who are interested in the new features take my classes). |
@rouson Would it make sense to update the following table: http://fortranwiki.org/fortran/show/Fortran+2008+status ? It shows submodule support only for Cray. |
I just opened this thread on the PGI forum. |
@muellermichel Yes. In fact, it would be very helpful to the community if this could be updated. In a proposal written last year, my collaborators and I encountered a reviewer who seemed unaware of the progress gfortran has made and it negatively impacted the review because it seemed the we were talking about features that weren't yet available even though they actually were. The listed gfortran version 4.8 is now roughly 2.5 years old and lots of great things have happened since then. I won't have time to scrutinize the list but I recommend checking out the gfortran Fortran 2003 status and Fortran 2008 status pages. I think this pages are pretty up-to-date, but you might also email the gfortran developers mailing list at [email protected]. For other compilers, I recommend consulting the aforementioned survey that Ian Chivers and Jane Sleightholme publish in nearly every issue of ACM Fortran Forum. The latest version was just published last month. If you don't have access to ACM Fortran Forum, I recommend contacting Ian and Jane. I think they can be reached via the email address listed on the FortranPlus web site. |
@muellermichel, you rock! |
@rouson Thanks, please also see the response by Mat Colgrove and my reply. I think it would make sense if you and maybe others could chime in with your opinions on this, i.e. why this feature is important to you. |
This discussion is moving way too fast for me to keep up with it, let alone contribute in a timely manner. But there is one thing that caught my eye that I feel compelled to push back on, and that is the suggestion that gfortran is pretty close to being a full 2008 compiler. It may look like that if you read their 2003/2008 status pages, but the reality is that some of the newer features are plagued with significant bugs. Top of my list, and the thing that keeps me from using gfortran at all, is deferred length allocatable character variables -- arguable one on the most useful features of 2003 (maybe that's a bit of an overstatement :-). Support for that feature is claimed starting in 4.9 I think, but in fact it has never worked at all except in the most trivial uses. That's still the case with the current 6.0 trunk as of a couple weeks ago. Bugs with finalization is another serious issue for me. I don't mean to dis the people working on gfortran; I applaud their efforts and would love to see a solid free Fortran 2008 compiler. I just think we need to be realistic and honest about what its current state really is. |
@nncarlson, These are excellent points and a welcome perspective. As @tclune pointed out to me, one's view of compiler is often heavily influenced by the frequency with which one uses it and (inevitably if it's a Fortran compiler) the frequency with which one reports bugs. My experience of gfortran (including my experience of its deferred-length character support) is heavily influenced by the fact that I've contributed a lot of bug reports and have been fortunate to come up with some funding to cover some of my most important bug fixes and feature requests. Probably for that reason, much of what I want is supported. As an aside, the first time I funded gfortran development was when I was at Sandia National Laboratories and @tclune has authorized some NASA funding for targeted bug fixes on occasion. Where there is a will, there is a way. It's unfortunate, however, that most organizations will cover the costs of a commercial compiler license but don't have a mechanism to cover any of the maintenance and development cost of an open-source compiler. I think most gfortran developers prefer to work as volunteers, but I'm certain that some of them would also accept funding and would target the features and bug fixes that the funding supports. With all that said, the good news is that gfortran has made very recent strides on deferred-length character support, including fixes for a bevy of bugs just three days ago. I encourage you to build the current gfortran development trunk (see my earlier post for a script that automates the checkout, build, and installation process) and report any bugs you find. As much as I love deferred-length characters, I personally wouldn't describe them as a major feature of Fortran 2008, but this is just my own definition of "major" and I have no hard, objective, or quantitative definition of the word so I'd still say that the only two major Fortran 2008 features that gfortarn is missing are PDT's and DTIO. |
@muellermichel, I don't see a post by Mat Cosgrove. |
@rouson I mean on the PGI thread. Screenname mkcolg. He's the main supporter for that compiler. |
@rouson, I'll have to check out the development trunk again with fingers crossed that this long-standing issue has finally been fixed. In my defense I will say that my difficulties with gfortran are not for lack of reporting bugs. I've reported many bugs over the years with substantial effort invested in providing tiny minimal reproducers. (This is something that I encourage all my developers to do with any compiler -- things won't improve if problems aren't reported.) But my experience with gfortran has been different than yours (though I've never included $). Reports either sit ignored, or are immediately marked as duplicates of other reports with no serious examination and the reproducers effectively ignored. Why do I find deferred length characters so damn useful? (I didn't say "major") I have a character component of a derived type, or a character variable to pass to a subroutine to receive a message. How long should I declare them to be? 8, 16, 100, 1000? How long is long enough? Now I have data to stuff into such a variable. What do I do if it's not long enough? Silently truncate, raise an error? This has been a thorn in my side for as long as I've been coding in Fortran (a long time). The answer to "how long" is deferred-length -- they are exactly as long as they need to be. All kinds of issues with fixed length characters immediately vanish. Having experienced the joy of this feature, I'm not giving it up :-) |
@muellermichel, I see. I have a PGI license but don't have a login for the support forum and might not have time to create one in the short term plus all the compiler teams are used to hearing from me so adding my voice wouldn't matter much. I hope you'll mention to them that four other compilers support submodules so waiting "several years" will be put them extremely far behind the pack and their slowness hurts the whole Fortran community for the reasons you state. I think Cray has been Fortarn 2008 compliant since at least 2014 and even gfortran's (pre-release) submodule support is approaching six months old (the first commit was in early August). It can take months to add a significant new feature so if PGI hasn't even started on preliminary support for the feature, then the time it will take them to finally catch up is substantial. I hope others will chime in, but it's a chicken-and-egg problem. Most people won't adopt a feature until there is widespread support, but the vendors don't see a market demand that justifies support until more people force their hand -- hence Mat's question to yo regarding how important the feature is to you. It's so frustrating and depressing... |
Please note: AFAIK anyone can create a PGI Forum user, no license needed. |
@nncarlson, I hear you and feel your pain. I'm really glad to hear you've reported bugs. I started the Ad Hoc project to catalog the bugs that matter most to me and to those with whom I collaborate. I'd definitely put deferred-length characters high on my wish list so a contribution of a bug reproducer in the form of a pull request for Ad Hoc would be welcome. I've experienced both ends of the spectrum: some of my gfortran bug reports have languished for years and many others have been fixed in 24-48 hours. Averaging it out across all bug reports I've submitted on six different compilers, NAG and gfortran have had the fasted average turnaround time, but the average is probably skewed by the funding in a fraction of the cases for gfortran. |
@rouson @nncarlson FYI I am going to report my first possible bug on GNU gfortran. I have already a minimal working example, can I put under you eyes before submitting (it is highly probable that it is not a bug, but my mistakes)? |
I also agree with the usefulness of submodules, but there is still a huge sector of computers where it is tricky to install new versions of compilers on your own. Especially the middle class of supercomputers is tricky. The largest ones have very good support and not the latest, but recent enough compilers (no way gcc 6, but at least Cray and Intel 15 or 16). But those medium ones in smaller institutions often have less professional support and old compilers. Now you can install your own, but that is not the end of the story. You also need to compile the MPI library for the new compiler. For that you need the drivers and headers for the local Infiniband or other interconnect and the headers for the queue system integration. Because of the not so professional support, it is sometimes pretty difficult to get these. Sometimes you can get away with just somehow recompiling the Fortran MPI library modules and use the old version otherwise, but it is risky. |
@LadaF we are in the same boat! |
The other issue I see around submodules is that they dramatically On 13/01/16 12:36, Stefano Zaghi wrote:
Chris MacMackin |
@cmacmackin Good point. I am going to try to make a compromise summary of all the above opinions: I will place many of them into a consider also that... subsection, while the main naming convention guideline should be very neutral, merging all our maximum common denominators. I hope the resulting guideline will be neutral, but comprehensive (via subsection considerations) and sill concise: I am an incurable optimistic person. |
How about this convention: Never use variable name |
@milancurcic oh, yes wonderful! Feel free (all of you) to modify my incomplete and ugly draft! |
Just a thought which occurred to me: while in general I agree that procedures should contain action verbs, I can think of two exceptions where this might not be necessary:
type :: example
integer, private :: component_
contains
procedure :: component => get_component
end type
|
@milancurcic Why that one? The sequence is quite natural |
@LadaF I think that in not so far old days, |
Damian |
Dear all, due this was an horrible working day, I have only found the time to upload the summary I wrote last night... no way to check what I have written: consider to trashing it without hesitation. Anyway, there should be all the above suggestions (in an almost incomprehensible form): please, check/correct/delete my English-spaghetti sentences as you like. See you soon, I hope. |
This is probably one of the most personal guideline.
I have to admit that I have not yet found yhe one that I love so I often change my mind resulting into somehow disorder style (that really hurts my soul).
I read about many nice idea. I will try to report them here (I need some times, but do not wait me, start suggestiong your convention) in order to promote our discussion.
From Richard Maine (stated here)
From one of the @cmacmackin guides
From @certik best practices
From @milancurcic best practices
From @rouson best practices
From @victorsndvg best practices
From @zbeekman best practices
From @LadaF best practices
From @tclune best practices
The text was updated successfully, but these errors were encountered: