[
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and maintainers pledge to make participation in our project and\nour community a harassment-free experience for everyone, regardless of age,\nbody size, disability, ethnicity, gender identity and expression, level of\nexperience, nationality, personal appearance, race, religion, or sexual\nidentity and orientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment\ninclude:\n\n* Using welcoming and inclusive language\n* Being respectful of differing viewpoints and experiences\n* Gracefully accepting constructive criticism\n* Focusing on what is best for the community\n* Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery and unwelcome sexual attention or\nadvances\n* Trolling, insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or electronic\n  address, without explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable\nbehavior and are expected to take appropriate and fair corrective action in\nresponse to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or\nreject comments, commits, code, wiki edits, issues, and other contributions\nthat are not aligned to this Code of Conduct, or to ban temporarily or\npermanently any contributor for other behaviors that they deem inappropriate,\nthreatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces\nwhen an individual is representing the project or its community. Examples of\nrepresenting a project or community include using an official project e-mail\naddress, posting via an official social media account or acting as an appointed\nrepresentative at an online or offline event. Representation of a project may\nbe further defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing or otherwise unacceptable behavior may be\nreported by contacting one of the project maintainers at ondrej@certik.us or\nzjibben@lanl.gov. All complaints will be reviewed and investigated and will\nresult in a response that is deemed necessary and appropriate to the\ncircumstances. The project team is obligated to maintain confidentiality with\nregard to the reporter of an incident. Further details of specific enforcement\npolicies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good\nfaith may face temporary or permanent repercussions as determined by other\nmembers of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,\navailable at [https://contributor-covenant.org/version/1/4][version]\n\n[homepage]: https://contributor-covenant.org\n[version]: https://contributor-covenant.org/version/1/4/\n"
  },
  {
    "path": "README.md",
    "content": "# Fortran Proposals\n\nThis repository contains proposals for the Fortran Standard Committee in the [Issues](https://github.com/j3-fortran/fortran_proposals/issues) section. The idea for this repository is to act as a public facing discussion tool to collaborate with the user community to gather proposals for the Fortran language and systematically track all discussions for each proposal.\n\n## Workflow\n\n1. Open a new issue with a new addition that you would like to see eventually included in the Fortran standard.\n\n2. The issue gets discussed.\n\n3. Start drafting a formal proposal to be submitted into [Documents](https://j3-fortran.org/doc/meeting) for the US committee. One has to find an advocate at the committee to advocate for the proposal.\n\n4. If the draft proposal receives negative feedback from the committee, then we will close the issue and we will have documented reasons why the idea got rejected. One can open a new issue, reference the closed issue and advocate why it should be revisited.\n\n5. Getting the proposal through the Committee is a long process, with multiple approvals, formal requirements, specifications, edits to the standard, etc. We will document this step in more detail. During this process, we can document the latest status at the issue.\n\n### Proposal Format\n\nProposals should be text files, using [proposal-template.txt](proposal-template.txt) as a template. The reference line is optional, and is used reference previous J3 papers (e.g. 12-345r6, not a full link). The top line should not be modified--the XX-XXX is automatically modified when uploaded. Proposals are limited to 75 characters per line, and are generally around 50 - 350 lines of text. Proposals benefit from minimal code examples and use cases. While J3 will accept PDF proposals, such detailed documents are usually be better suited as a reference, so the proposal itself can be concise.\n\n## Plan For This Repository\n\nCurrently this repository is maintained by\n[Ondřej Čertík](https://github.com/certik),\n[Zach Jibben](https://github.com/zjibben) and\n[Gary Klimowicz](https://github.com/gklimowicz)\n(all members of the Fortran Committee). We plan to maintain this repository,\nkeep it up to date with what the committee is doing and use it to collaborate\non ideas and proposals with the Fortran community.\n\n## Code of Conduct\n\nPlease note that all participants of this project are expected to follow our\nCode of Conduct. By participating in this project you agree to abide by its\nterms. See [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md).\n\n## Links\n\n* [US Fortran Standards Committee](https://j3-fortran.org/)\n* [International Fortran Standard Committee](https://wg5-fortran.org/)\n"
  },
  {
    "path": "augmented_assignment/augmented_assignment.txt",
    "content": "To: J3                                                     J3/XX-XXX\nFrom: Leonard Reuter \nSubject: Augmented Assignment Operators\nDate: 2022-July-11\n\nProposal for Fortran Standard: 202y\n\n\n1. Introduction\n\nThe proposal is to introduce augmented assignment operators. Example:\n\n    i +.= 1\n\nHere, `i` is incremented by 1.\n\nIn the same manner, the operators `-.=`, `*.=`, `/.=`, `**.=` are proposed\nto be defined as well as the operator `.op.=` for a user-defined operator\n`.op.`.\n\nThe intrinsic interpretation of e.g. '+.=' can not be overridden but should\nalways call 'operator(+)' and 'assignment(=)'.\n\nThis proposal originated at the J3 GitHub repository at [1]. The proposed\nsyntax originated from a comment by Reinhold Bader in the J3 mail list [2].\n\n2. Motivation\n\nAugmented assignment operators improve the readability of code in making\nimmediately clear to the reader, that the new value of the variable\ndepends on the old one.\n\nFurthermore, if a function is called during the evaluation of the\nleft-hand side, the augmented assignment operators show, that this\nfunction is only called once:\n\n    real :: A(n)\n    ...\n    A(get_index()) +.= x\n\nIf the above example were to be written without augmented assigment, how\noften `get_index` is called would depend on the compiler.\n\nThe dot is added between the operator and `=`, since `/=` is already in\nuse as an alias to the '.ne.' relational operator.\n\n3. Discussing Objections\n\n3.1. Conflict with '/=' [4]\n\nThis is circumvented by introducing the dot, i.e. '/.='\n\n3.2. The compiler can optimize 'a = a + b*c' better than 'a +.= b*c' [5]\n\n\"What happens to 'a += b * c' is often optimized to an FMA if the compiler\nflags or defaults allow ISO/IEEE violation\" [6].\n\n3.3. Instead of augmented assignment, an additional symbol can be\n     introduced to replace the LHS [7,8]\n\nIf this symbol were '.LHS.', it would allow for further simplification:\n\n    real :: a\n    ...\n    a = LOG(a)\n\ncould be replaced with\n\n    real :: a\n    ...\n    a = LOG(.LHS.)\n\nWhile discussing this may prove worthwhile, it lacks the intuitivity of\nsimple augmented assignment and should be discussed independent of it.\n\n3.4 Cognitive load [9]\n\nMost programmers are used to augmented assignment from other languages,\nit is more cognitive load to remember, that this is not possible in \nFortran than to actually use it.\n\n4. References\n\n[1] https://github.com/j3-fortran/fortran_proposals/issues/113\n[2] https://mailman.j3-fortran.org/pipermail/j3/2021-August/013261.html\n[3] https://mailman.j3-fortran.org/pipermail/j3/2021-August/013251.html\n[4] https://mailman.j3-fortran.org/pipermail/j3/2021-August/013254.html\n[5] https://mailman.j3-fortran.org/pipermail/j3/2021-August/013262.html\n[6] https://mailman.j3-fortran.org/pipermail/j3/2021-August/013279.html\n[7] https://mailman.j3-fortran.org/pipermail/j3/2021-August/013287.html\n[8] https://wg5-fortran.org/N1951-N2000/N1972.pdf\n[9] https://mailman.j3-fortran.org/pipermail/j3/2021-August/013277.html\n"
  },
  {
    "path": "proposal-template.txt",
    "content": "To: J3                                                     J3/XX-XXX\nFrom: \nSubject: \nDate: \n#Reference:\n"
  },
  {
    "path": "proposals/assert/design_by_contract.txt",
    "content": "To: J3                                                     J3/XX-XXX\nFrom: William B. Clodius\nSubject: Facilitate design by contract\nDate: August 1, 2020\n#Reference: 04-142.txt, 04-143.txt, 04-144.txt, 04-212.txt,\n04-219.txt, 04-376.txt, 04-414.txt\n\n\nProposal for Fortran Standard: 202y (NOT 202x)\n\n\n1. Introduction\n\nThis paper contains a proposal to allow programmers to use \"Design by\nContract\". Inspired by languages such as C++, Java, and Ada, Fortran\nis considering incorporating exception handling into the language. In\ncontrast, C++'s standard committees have decided that its users have\nbeen overusing exception handling, and has been seeking to incorporate\nother, simpler, error handing systems.[1] One approach, that has been\nincorporated into C++ 2020, is design by contract.[2,3] I believe\nFortran would benefit by incorporating design by contract into the\nlanguage, at a cost much less than would be incurred by incorporating\nexception handling.\n\nDesign by contract (DbC) is intended to address programmer errors and\nonly those errors. The idea is to specify: first the logical\npreconditions the inputs to a procedure are required to satisfy for\nits correct operation; second, the conditions the code is asserted to\nsatisfy at various stages of its logic if the code logic is correct,\nand finally, the post-conditions the code ensures it will satisfy if\nthe pre-conditions are met. To implement these checks, C++ 2020 has\ndefined the attributes: expects, assert, and ensures,\nrespectively. During the debugging phase of development these serve to\ndetect when the conditions are not satisfied, stop processing when\nthey are not satisfied, and report errors in a consistent format. In\ncode deployment the expects attribute documents the pre-conditions the\ncalling code must satisfy, and the ensures attribute documents the\npost-conditions the calling code can expect will be satisfied,\nproviding a \"contract\" between the calling code and the\ncallee. Normally the processor provides flags such that the logical\ntests can be active during testing, and inactive on deployment.\n\nDbC can be met with a minimum of one new statement, for testing\nanywhere in the code body, say ASSERT, but ideally there would be\nthree new statements: one the equivalent of ASSERT, one to be used at\nthe start of the procedure to test pre-conditions, say REQUIRE, and\none to be used immediately before the procedure's return to test\npost-conditions, say ENSURE. All three statements would be simple in\nform and have simple semantics. \n\n\n2. Problem\n\nCurrently a programmer typically tests for user errors using one of:\n\n    1. Hardcoding the tests for errors using IF or SELECT CASE blocks;\n    2. Writing the equivalent of an ASSERT subroutine: or\n    3. Writing the equivalent of an ASSERT macro.\n\nThe first is the most natural for single checks, but requires care to\ngive a consistent response to the user, and adds an overhead in\ndeployment unless commented or edited out. The second allows a\nconsistent response to the user, but has a larger overhead than the\nfirst, that can only be removed by being commented or edited out. The\nthird allows a consistent response to the user that can be clearer\nabout the problem location, and can have zero overhead on deployment\nwith appropriate pre-processor flags, but does require a dependence\non a preprocessor. None document for the user the pre and post\nconditions the user can expect for properly working code.\n\n\n3. Use cases\n\nA simple function that requires non-negative integer arguments.\n\n  REAL FUNCTION FACTORIAL( n )\n    INTEGER, INTENT(IN) :: N\n    INTEGER :: I\n    REQUIRE( N >= 0 )\n    FACTORIAL = 1\n    DO I=1, N\n      FACTORIAL = FACTORIAL * I\n    END DO\n    ENSURE (FACTORIAL >= N )\n    RETURN\n  END FUNCTION FACTORIAL\n\nA simple subroutine that swaps targets.\n\n  SUBROUTINE TARGET_SWAP( A, B )\n    TYPE(EXAMPLE), POINTER, INTENT(INOUT) :: A, B\n    TYPE(EXAMPLE), POINTER :: C\n    REQUIRE( ASSOCIATED(A) )  ! Requires pointer status of A be\n                              ! defined \n    REQUIRE( ASSOCIATED(B) )  ! Requires pointer status of B be\n                              ! defined\n    C => A\n    A => B\n    B => C\n    ENSURE( ASSOCIATED(A) )\n    ENSURE( ASSOCIATED(B) )\n    RETURN\n  END SUBROUTINE TARGET_SWAP\n\nA procedure that requires one optional argument to be present if the\nother optional argument is present.\n\n  SUBROUTINE OPTIONALS( A, B )\n    TYPE(EXAMPLE), OPTIONAL, INTENT(IN) :: A, B\n    REQUIRE( PRESENT(A) .EQV. PRESENT(B) )\n    ...\n    RETURN\n  END SUBROUTINE OPTIONALS\n\nA test of a problematic procedure call\n\n  SUBROUTINE PROBLEM_CALL ( ..., A, ... )\n    ...\n    TYPE(EXAMPLE), POINTER :: A\n    ...\n    CALL PROBLEM( A )\n    ASSERT( ASSOCIATED( A ) )\n    ...\n    RETURN\n  END SUBROUTINE PROBLEM_CALL\n\n\n4. Prior art\n\nThe term design by contract as applied to programming languages has\nits origins in the language Eiffel.[4,5] Since then, in addition to\nC++ it has been adopted by Ada,[6] D,[7] and Fortress. The C standard\nlibrary comes with the assert macro so C can be said to partially\nsupport DbC. To our knowledge no Fortran compiler has implemented\nanything to support DbC. Many users implement their own equivalent of\nan ASSERT subroutine or macro so there is some demand for these\ncapabilities.\n\n\n5. Specification\n\nAll three statements will have similar behavior. All three will take\nas their arguments a list of scalar logical expressions, that if all\n.TRUE. does nothing, and if one is .FALSE. writes output to the\nERROR_UNIT of ISO_FORTRAN_ENV and stops as if ERROR STOP was\ninvoked. The writes will all indicate the location of the executed\nstatement: either the procedure name with the name of the enclosing\nmodule, or the name of the file including the statement and the line\nnumber of the statement, or both. All three will write out the text of\nthe logical expression that failed, with a prefix. The prefix will\ndiffer between the three statements. Example prefixes for the REQUIRE\nstatement is \"PRE-CONDITION FAILED: \", for the ASSERT statement is\n\"ASSERTION FAILED: \". and for the ENSURE statement is \"POST-CONDITION\nFAILED: \".\n\nThe semantics of all three statements are similar. They all should\nrespond the same to compiler flags that invoke different behavior in\ndevelopment versus in deployment. In development, they each perform a\nlogical test with the .FALSE. branch writing to ERROR_UNIT, and then\nstopping with an stop code, and the other branch a null operation\nthat continues processing. In deployment they are as if they were\ncommented out. These semantics are similar to a logical test with one\nbranch invoking ERROR STOP and the other branch continuing\nprocessing. They should have restrictions similar to those of ERROR\nSTOP, being allowed in PURE procedures, but not in ELEMENTAL\nprocedures.\n\n\n4. Syntactic options\n\nThe syntax for the statements depend on whether they should be\nconsidered executable statements, and should go in the executable\npart, or attributes of the sub-programs, and should go in the\nspecification part. It is difficult to think of ASSERT as any thing\nother than an executable statement. For ASSERT I think the following\nsyntax is appropriate \n\n  assert-stmt is ASSERT( assertion-list )\n\nwhere\n\n  assertion is logical-expr\n\nREQUIRE and ENSURE can be thought of as either sub-program attributes\nor executable statements. If treated as sub-program attributes then\nthe syntax could be something like\n\n  requires-stmt is REQUIRES :: requires-expr-list\n  ensures-stmt is ENSURES :: ensures-expr-list\n\n  requires-expr is logical-expr\n  ensures-expr is logical-expr\n\nConstraint: requires-expr shall be a restricted expression. \n\nIf thought of as run time expressions then the appropriate syntax may\nbe\n\n  require-stmt is REQUIRE( require-expr-list )\n  ensure-stmt is ENSURE( ensure-expr-list )\n\nIn all of the syntactical forms each item in the effective\nlogical-expr-list shall be tested in sequence, and a error message\nwill be generated for the first item in the list that tests as\n.FALSE. that shows the logical expression that failed the test.\n\n\n5. Backward compatibility\n\nThe three proposed statements do not match statements implemented by\nany processor that I am aware of, and so their addition should not\nchange the meaning of any directly supported application. It is\nlikely, however, that some users already have an ASSERT macro, that\napproximates the ASSERT statement's semantics. I suspect they will\nwelcome the new ASSERT, but cannot be certain. This problem could be\nminimized by using a name other than ASSERT, say CHECK.\n\n\n6. Impact on the standard\n\nMy guess is that describing each statement will take about half a page\nof main text, plus a half page note describing for all three\nstatements the semantics of a quality of implementation, plus a few\nsentences to describe changes from the previous standard and define\nterms. Maybe three pages total.\n\n\nReferences\n\n[1] Herb Sutter, \"Zero-overhead deterministic exceptions: Throwing\nvalues\",\nhttp://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0709r4.pdf\n[2] G. Dos Reis, J. D. Garcia, J. Lakos, A. Meredith, N. Myers,\nand B. Stroustrup, \"A Contract Design\"\nhttp://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0380r1.pdf\n[3] G. Dos Reis, J. D. Garcia, J. Lakos, A. Meredith, N. Myers, and\nB. Stroustrup, \"Support for contract based programming in C++\"\nhttp://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0542r5.html\n[4] B. Meyer, \"Eiffel: The Language,\" Prentice Hall, second printing,\n1992.\n[5] B. Meyer, \"Applying 'Design by Contract',\" in Computer (IEEE) 25,\npp. 40-51, Oct. 1992.\nhttp://se.ethz.ch/~meyer/publications/computer/contract.pdf\n[6] R. Dewar, \"Ada 2012: Ada with Contracts\", Dr. Dobb's, Apr. 9,\n2013. https://www.drdobbs.com/architecture-and-design/ada-2012-ada-with-contracts/240150569\n[7] W. Bright, \"D Programming Language, Contract Programming\", Digital\nMars. https://dlang.org/spec/contracts.html\n"
  },
  {
    "path": "proposals/c23_interop/26-112.txt",
    "content": "To: J3                                                     J3/26-112\nFrom: Patrick Fasano\nSubject: Edits for updating references from C17 to C23\nDate: 2026-January-14\n\nReferences:\n      ISO/IEC 9899:2024 Programming languages -- C (\"C23\")\n      25-203r1 US05: Edits for C interchange and extended floating types\n      ISO/IEC 9899:2018 Programming languages -- C (\"C17\")\n      25-007r1 Fortran 2028 Working Draft\n\n1 Background\n============\n\nThe ISO C23 specification (ISO/IEC 9899:2024) is the latest revision of\nthe standard for the C language. At meeting #238 in January 2026, J3\npassed paper 25-203r1 with edits to add support to Fortran 202Y for\ninteroperability with new floating-point types added in C23. As such,\n25-203r1 introduced references to the C23 specification.\n\nThis paper provides edits to update and replace references to the ISO\nC17 specification (ISO/IEC 9899:2018) with references to the ISO C23\nspecification (ISO/IEC 9899:2024). The edits in this paper complement\nthose presented in 25-203r1 for work item US05.\n\n2 Edits (relative to 25-007r1)\n==============================\n\n[2:6] Replace the line:\n\n      ISO/IEC 9899:2018, Programming languages -- C\n\nwith the line\n\n      ISO/IEC 9899:2024, Programming languages -- C\n\nNote to editor: This edit is the same as that in 25-203r1.\n\n------------------------------------------------------------------------\n\n[7:22] Replace\n\n    ISO/IEC 9899:2018\n\nwith\n\n    ISO/IEC 9899:2024\n\n------------------------------------------------------------------------\n\n[50:36] Replace\n\n    ISO/IEC 9899:2018, 5.1.2.2.3 and 7.22.4.4\n\nwith\n\n    ISO/IEC 9899:2024, 5.2.2.3.4 and 7.24.5.4\n\n------------------------------------------------------------------------\n\n[50:39] Replace\n\n    ISO/IEC 9899:2018, 7.22.4.4\n\nwith\n\n    ISO/IEC 9899:2024, 7.24.5.4\n\n------------------------------------------------------------------------\n\n[57:note] In the first paragraph, replace\n\n    ISO/IEC 9899:2018\n\nwith\n\n    ISO/IEC 9899:2024\n\nand in the second paragraph, replace\n\n    ISO/IEC 9899:2018, 6.7.6.3\n\nwith\n\n    ISO/IEC 9899:2024, 6.7.7.4\n\n------------------------------------------------------------------------\n\n[102:27] Replace\n\n    ISO/IEC 9899:2018, 6.7.2.2\n\nwith\n\n    ISO/IEC 9899:2024, 6.7.3.3\n\n------------------------------------------------------------------------\n\n[103:note 2] Replace\n\n    ISO/IEC 9899:2018\n\nwith\n\n    ISO/IEC 9899:2024\n\nand replace\n\n    ISO/IEC 9899:2018, 6.7.2.2\n\nwith\n\n    ISO/IEC 9899:2024, 6.7.3.3\n\nNote to J3/editor: ISO/IEC 9899:2024 does not actually guarantee that\nenumeration constants fit in a C int. This will be addressed by\nrewriting or removing this Note in a forthcoming edit paper.\n\n------------------------------------------------------------------------\n\n[103:note 3] Replace\n\n    ISO/IEC 9899:2018\n\nwith\n\n    ISO/IEC 9899:2024\n\n------------------------------------------------------------------------\n\n[115:note] Replace\n\n    ISO/IEC 9899:2018\n\nwith\n\n    ISO/IEC 9899:2024\n\nand replace\n\n    ISO/IEC 9899:2018, 6.4.3\n\nwith\n\n    ISO/IEC 9899:2024, 6.4.4\n\n------------------------------------------------------------------------\n\n[252:19] Replace\n\n    ISO/IEC 9899:2018, 7.21.2\n\nwith\n\n    ISO/IEC 9899:2024, 7.23.2\n\n------------------------------------------------------------------------\n\n[538:4] Replace\n\n    ISO/IEC 9899:2018, 6.7.6.3\n\nwith\n\n    ISO/IEC 9899:2024, 6.7.7.4\n\n------------------------------------------------------------------------\n\n[538:8] Replace\n\n    ISO/IEC 9899:2018, 6.2.2\n\nwith\n\n    ISO/IEC 9899:2024, 6.2.2\n\n------------------------------------------------------------------------\n\n[538:30] Replace two instances of:\n\n      (_Bool)\n\nwith:\n\n      (bool)\n\nNote to editor: This edit is the same as that in 25-203r1.\n\n------------------------------------------------------------------------\n\n[539:23] Replace\n\n    ISO/IEC 9899:2018, 5.2.1 and 5.2.2\n\nwith\n\n    ISO/IEC 9899:2024, 5.3.1 and 5.3.3\n\n------------------------------------------------------------------------\n\n[540:16-17] Replace\n\n    ISO/IEC 9899:2018, 6.3.2.3 and 6.5.9\n\nwith\n\n    ISO/IEC 9899:2024, 6.3.3.3 and 6.5.10\n\n------------------------------------------------------------------------\n\n[543:note] Replace\n\n    ISO/IEC 9899:2018, 6.2.5\n\nwith\n\n    ISO/IEC 9899:2024, 6.2.5\n\n------------------------------------------------------------------------\n\n[545:26] Replace\n\n    ISO/IEC 9899:2018, 6.5.3.2\n\nwith\n\n    ISO/IEC 9899:2024, 6.5.4.3\n\n------------------------------------------------------------------------\n\n[546:note] Replace\n\n    ISO/IEC 9899:2018, 6.5.3.2\n\nwith\n\n    ISO/IEC 9899:2024, 6.5.4.3\n\n------------------------------------------------------------------------\n\n[546:10] Replace\n\n    ISO/IEC 9899:2018, 6.5.3.4\n\nwith\n\n    ISO/IEC 9899:2024, 6.5.4.5\n\n------------------------------------------------------------------------\n\n[547:13] Replace the line\n\n      The C types mentioned in Table 18.2 are defined in ISO/IEC\n      9899:2018, 6.2.5, 7.19, and 7.20.1.\n\nwith the line\n\n      The C types mentioned in Table 18.2 are defined in ISO/IEC\n      9899:2024, 6.2.5, 7.21, 7.22, and H.2.\n\nNote to editor: This edit is corrected relative to the one that appears\nin 25-203r1.\n\n------------------------------------------------------------------------\n\n[548:table 18.2] Replace the following:\n\n      _Bool\n\nwith:\n\n      bool\n\nNote to editor: This edit is the same as that in 25-203r1.\n\n------------------------------------------------------------------------\n\n[548:note] Replace\n\n    ISO/IEC 9899:2018\n\nwith\n\n    ISO/IEC 9899:2024\n\n------------------------------------------------------------------------\n\n[548:note 1] Replace\n\n    ISO/IEC 9899:2018\n\nwith\n\n    ISO/IEC 9899:2024\n\n------------------------------------------------------------------------\n\n[549:note 4] Replace\n\n    ISO/IEC 9899:2018\n\nwith\n\n    ISO/IEC 9899:2024\n\nand replace\n\n    ISO/IEC 9899:2018, 6.2.7\n\nwith\n\n    ISO/IEC 9899:2024, 6.2.7\n\n------------------------------------------------------------------------\n\n[551:16-17] Delete\n\n    (ISO/IEC 9899:2018, 6.2.5, 7.19, and 7.20.1)\n\n[551:note 1] After \"The referenced type of a C pointer type\", insert:\n\n    (ISO/IEC 9899:2024, 6.2.5)\n\nsuch that the note reads:\n\n    <<NOTE 1>>\n    The <<referenced type>> of a C pointer type (ISO/IEC 9899:2024,\n    6.2.5) is the C type of the object that the C pointer type points\n    to. For example, the referenced type of the pointer type\n    \\texttt{int *} is \\texttt{int}.\n\n------------------------------------------------------------------------\n\n[551:note 2] Replace\n\n    ISO/IEC 9899:2018, 7.16\n\nwith\n\n    ISO/IEC 9899:2024, 7.16\n\n------------------------------------------------------------------------\n\n[557:table 18.4] Replace the following:\n\n      +---------------+-------+\n      | CFI_type_Bool | _Bool |\n      +---------------+-------+\n\nwith:\n\n      +---------------+------+\n      | CFI_type_Bool | bool |\n      | CFI_type_bool | bool |\n      +---------------+------+\n\nNote to editor: This edit is the same as that in 25-203r1.\n\n------------------------------------------------------------------------\n\n[561:8-9] Replace\n\n    ISO/IEC 9899:2018, 3.2\n\nwith\n\n    ISO/IEC 9899:2024, 3.2\n\n------------------------------------------------------------------------\n\n[564:18-19] Replace\n\n    ISO/IEC 9899:2018, 3.2\n\nwith\n\n    ISO/IEC 9899:2024, 3.2\n\n------------------------------------------------------------------------\n\n[566:26] Replace\n\n    ISO/IEC 9899:2018, 3.4.3\n\nwith\n\n    ISO/IEC 9899:2024, 3.5.3\n\n------------------------------------------------------------------------\n\n[566:31-32] Replace\n\n    ISO/IEC 9899:2018, 6.2.4\n\nwith\n\n    ISO/IEC 9899:2024, 6.2.4\n\n------------------------------------------------------------------------\n\n[568:20] Replace\n\n    ISO/IEC 9899:2018, 6.2.2\n\nwith\n\n    ISO/IEC 9899:2024, 6.2.2\n\n------------------------------------------------------------------------\n\n[568:23] Replace\n\n    ISO/IEC 9899:2018\n\nwith\n\n    ISO/IEC 9899:2024\n\n------------------------------------------------------------------------\n\n[569:4] Replace\n\n    ISO/IEC 9899:2018, 7.13\n\nwith\n\n    ISO/IEC 9899:2024, 7.13\n\n------------------------------------------------------------------------\n\n[569:7] Replace\n\n    ISO/IEC 9899:2018, 7.14.1\n\nwith\n\n    ISO/IEC 9899:2024, 7.14.1\n\n------------------------------------------------------------------------\n\n[569:note] Replace\n\n    ISO/IEC 9899:2018\n\nwith\n\n    ISO/IEC 9899:2024\n\n------------------------------------------------------------------------\n\n[569:25] Replace\n\n    ISO/IEC 9899:2018, 7.14.1\n\nwith\n\n    ISO/IEC 9899:2024, 7.14.1\n\n===END===\n"
  },
  {
    "path": "proposals/c23_interop/26-122.txt",
    "content": "To: J3                                                     J3/26-122\nFrom: Patrick Fasano & HPC\nSubject: Reqs/specs for interoperability with C23 enumerations\nDate: 2026-February-23\nReference: ISO/IEC-9899:2018 ! Programming languages -- C (\"C17\")\nReference: ISO/IEC-9899:2024 ! Programming languages -- C (\"C23\")\nReference: WG5/N2212  ! The new features of Fortran 2023\nReference: WG14/N3029 ! Improved Normal Enumerations\nReference: WG14/N3030 ! Enhanced Enumerations\nReference: 24-007     ! Fortran 2023\nReference: 26-112     ! Edits for updating references from C17 to C23\n\n1 Background\n============\n\nbg01. The ISO C23 specification (ISO/IEC 9899:2024) introduced changes\n      to enumerations that create an incompatibility with the current\n      specification of Fortran interoperable enumerations and enum\n      types. Specifically, WG14 adopted two proposals affecting\n      enumerations in C23:\n      * N3029: \"Improved Normal Enumerations\", which allows enumeration\n        values greater than INT_MAX and smaller than INT_MIN.\n      * N3030: \"Enhanced Enumerations\", which allows specifying an\n        underlying type for enumerations.\n\nbg02. WG14/N3029 \"Improved Normal Enumerations\" changes the rules for\n      the types of enumeration constants and the underlying type of the\n      enumeration. In C17, all enumeration constants were required to be\n      representable as an int. In C23, enumeration constants may have\n      values that are not representable as an int; the compiler\n      determines an underlying integer type that can represent all the\n      values defined in the enumeration.\n\nbg03. WG14/N3030 \"Enhanced Enumerations\" adds the ability to specify the\n      underlying type of an enumeration. In C17, the underlying type of\n      an enumeration was implementation-defined (subject to being able\n      to represent all the values). In C23, the underlying type can be\n      explicitly specified in the enum declaration (e.g., `enum x : long\n      long { ... }`).\n\nbg04. The current Fortran specification (24-007, subclause 7.6.1)\n      relies on the assumption that C enumeration constants fit within a\n      C int. This assumption is explicitly stated in Note 2 of the\n      subclause: \"ISO/IEC 9899:2018 guarantees the enumeration constants\n      fit in a C int (ISO/IEC 9899:2018, 6.7.2.2). Therefore, the\n      Fortran processor can evaluate all enumerator values using the\n      integer type with kind parameter C_INT, and then determine the\n      kind parameter of the integer type that is interoperable with the\n      corresponding C enumerated type.\" With the adoption of WG14/N3029\n      in C23, this guarantee no longer holds. C enumerations may now\n      have values that cannot be represented in a C int.\n\nbg06. The edits in paper 26-112 adopted by J3 at meeting #238 in January\n      2026 replaced references to C17 with C23 in the Fortran\n      specification. That introduced a factually incorrect statement\n      regarding C enumerations in Note 2 of subclause 7.6.1, which was\n      not addressed in that paper. This paper addresses this issue by\n      proposing options for resolving the incompatibility and providing\n      specifications for each option.\n\n\n2 Requirements\n==============\n\nrq01. The Fortran standard should be updated to address the\n      incompatibility between Fortran interoperable enumerations and C23\n      enumerations.\n\n\n3 Straw polls\n=============\n\nStraw poll\n----------\nHow should the incompatibility with C23 enumerations be resolved?\n\n\nOPTION A: Restrict interoperability to C enums compatible with C_INT.\n\n          Add a precondition that says interoperability requires that\n          the C enum have a type that fits within an INTEGER(C_INT).\n\n\nOPTION B: Implicitly determine KIND via new C23 rules.\n\n          Remove the incorrect note and implicitly require that the\n          Fortran processor determine the KIND of the enumerators via\n          the new C23 rules; do not allow explicitly declaring the KIND.\n          Optionally, add a new note on how the Fortran processor\n          evaluates the enumerator values to determine the interoperable\n          KIND parameter.\n\n\nOPTION C: Implicitly determine KIND via new C23 rules and add explicit\n          KIND parameter to ENUM.\n\n          Require that the Fortran processor\n          determine the KIND of the enumerators via the new C23 rules;\n          add an explicit (optional) KIND parameter to ENUM declarations\n          which override any implicit determination.\n\n\nThe subgroup recommends OPTION A.\n\n\nStraw poll analysis\n-------------------\n\nPROS OPTION A:\nAP01. Minimizes expected implementation burden: no syntax change, no\n      runtime change.\nAP02. Implicitly fixes the problem with Note 2 (making it true by\n      restriction, after some minor rephrasing).\nAP03. Should not require any Fortran compiler backend changes, just\n      spec wording.\n\nCONS OPTION A:\nAC01. Does not allow interoperability with C's new \"wider\" (64-bit)\n      enum types, or even explicitly \"narrower\" enum types (e.g. 8-bit).\nAC02. Must add spec constraint to restrict allowable enumerators.\nAC03. Compiler changes to check the new constraint are required.\n\nPROS OPTION B:\nBP01. No syntax change.\nBP02. Maintains interoperability with the implicit behavior of C enums.\nBP03. No normative standard changes required.\nBP04. Compatible with C paper WG14/N3029.\n\nCONS OPTION B:\nBC01. Likely requires some compiler changes to accommodate new\n      wider enums.\nBC02. Does not provide full interoperability with all C enums, because\n      it cannot express all enums that are possible in C23 (specifically\n      those with specified underlying types defined in WG14/N3030).\n\nPROS OPTION C:\nCP01. Maintains full interoperability with all C enums.\n\nCONS OPTION C:\nCC01. Requires introducing new syntax.\nCC02. Requires compiler parsing and backend changes (hence might be\n      considered a new feature).\n\n4 Specifications\n================\n\n4.1 Specifications for Option A\n-------------------------------\n\nsa01. The definition of \"interoperable enumerator\" should be constrained\n      to require the values of the enumerators be representable in the\n      integer type with kind parameter C_INT.\n\nsa02. Update or remove Note 2 in subclause 7.6.1 to reflect that\n      interoperability is restricted to enumerations where constants fit\n      in a C int.\n\n4.2 Specifications for Option B\n-------------------------------\n\nsb01. Remove Note 2 in subclause 7.6.1 which incorrectly states that C\n      enumeration constants are guaranteed to fit in a C int.\n\nsb02. The Fortran processor shall determine the interoperable kind of\n      the enumerators based on the type chosen by the companion\n      processor for the corresponding C enumerated type, which may be\n      wider than C_INT.\n\nsb03. Optionally, add a replacement Note to subclause 7.6.1 to explain\n      that C23 allows enumeration constants that do not fit in a C int,\n      and that the Fortran processor may need to evaluate all enumerator\n      values using an integer type with wider range than the integer\n      type with kind parameter C_INT, before determining the kind\n      parameter that is interoperable with the C enumerated type.\n\n4.3 Specifications for Option C\n-------------------------------\n\nsc01. Extend the syntax of the ENUM statement to allow an optional KIND\n      parameter to specify the underlying integer type. One possible\n      syntax (shown only for illustrative purposes):\n\n      ENUM[(KIND=scalar-int-constant-expr)], BIND(C) [:: enum-type-name]\n\n      Thus, for a C23 enumerator declared as this:\n\n         enum my_long_enum : long {\n            red = 4,\n            blue = 9,\n            yellow\n         };\n\n      a corresponding Fortran interoperable enumeration could be\n      declared as:\n\n         ENUM(KIND=C_LONG), BIND(C) :: my_long_enum\n            ENUMERATOR :: RED = 4, BLUE = 9\n            ENUMERATOR YELLOW\n         END ENUM\n\nsc02. If the KIND parameter is present, the kind type parameter of the\n      enumerators is the value specified by the KIND parameter. The\n      corresponding interoperable C enumerated type is one that uses a\n      compatible underlying type (in addition to the other requirements\n      specified in 24-007, sec 7.6.1 para 2).\n\nsc03. If the KIND parameter is absent, the Fortran processor shall\n      determine the interoperable kind of the enumerators based on the\n      type chosen by the companion processor for the corresponding C\n      enumerated type, which may be wider than C_INT.\n\nsc04. Add a Note to subclause 7.6.1 to explain that C23 allows\n      enumeration constants that do not fit in a C int, and that the\n      Fortran processor may need to evaluate all enumerator values using\n      an integer type with wider range than the integer type with kind\n      parameter C_INT, before determining the kind parameter that is\n      interoperable with the C enumerated type.\n\n==END==\n"
  },
  {
    "path": "proposals/cmplx-real-pointers.txt",
    "content": "To: J3                                                     J3/24-129\nFrom: Pierre Hugonnet\nSubject: allow complex pointer to reals and vice versa\nDate: 2024-June-10\n#Reference:\n\n1. Introduction\n\nThe proposal is to allow a complex pointer to be associated to a real\narray, and similarly to allow a real pointer to be associated to a\ncomplex scalar or array.\n\n\n2. Motivation\n\nIn short, the motivation is to save memory and cpu-memory bandwidth\nin some HPC contexts, typically when dealing with very large or huge\ndata volumes.\n\nWhen working in the Fourier domain, it is common to use in-place real\nto complex Fourier transforms. Before the forward transform one\ngenerally stores data in a real array, and the transform outputs\ncomplex numbers in the same real array, with interleaved real and\nimaginary parts. Once in the Fourier domain the complex type is more\nappropriate to perform computations, but this requires either:\n- duplicating the data into a complex array after the transform,\n  thus cancelling the advantage of the in-place transform. Note that in\n  HPC, and particularly when dealing with large data volumes,\n  duplicating the data is really something that we want to avoid\n  whenever possible.\n- or using various non-standard tricks that rely on the fact that\n  virtually all compilers store a complex number by the sequence\n  real part / imaginary part.\n\nFor instance, consider a code that performs a FFT based convolution\nat some point:\n\n    program foo\n    real, allocatable :: r1(:), r2(:), r3(:)\n    integer, parameter :: n = 100000\n    ! ...\n    allocate( r1(n), r2(n), r3(n) )\n    ! ... some computations on r1(:) and r2(:) as reals\n    call rfft(r1) ; call rfft(r2)\n    call fftconvol(r1,r2,r3,n/2)   ! called without any interface,\n                                   ! hence type mismatchs\n    call irfft(r3)\n    ! ... some computations on r3(:) as real\n    end program\n\n    ! dangling routine (not contained and not in a module)\n    subroutine fftconvol(c1,c2,c3,n)\n    integer, intent(in) :: n\n    complex, intent(in)  :: c1(n), c2(n)\n    complex, intent(out) :: c3(n)\n    c3(:) = c1(:) * c2(:)\n    end subroutine\n\nWith modern Fortran another trick has got quite popular, by using the\nC interoperability features. Nonetheless the trick is non standard:\n\n    program foo\n    use iso_c_binding\n    real, allocatable :: r1(:), r2(:), r3(:)\n    integer, parameter :: n = 100000\n    complex, pointer :: c1(:), c2(:), c3(:)\n    ! ...\n    allocate( r1(n), r2(n), r3(n) )\n    ! ... some computations on r1(:) and r2(:) as reals\n    call rfft(r1) ; call rfft(r2)\n    ! non-standard trick\n    call c_f_pointer( c_loc(r1), c1, [n/2] )\n    call c_f_pointer( c_loc(r2), c2, [n/2] )\n    call c_f_pointer( c_loc(r3), c3, [n/2] )\n\n    c3(:) = c1(:) * c2(:)\n\n    call irfft(r3)\n    ! ... some computations on r3(:) as real\n    end program\n\nThe `c_f_pointer()` trick is even mentioned in the official\ndocumentation of FFTW, which is one of the most popular FFT\nlibrary [1].\n\nMore generally, this is a recurrent topic on forums or on\nStackOverflow [2]\n\n\n3. Proposed solution\n\nThe proposal essentially aims at standardizing the usual practice\nabove, by allowing a real array to be viewed as a complex array and\nvice-versa. The above code would become:\n\n    program foo\n    real, allocatable, target :: r1(:), r2(:), r3(:)\n    integer, parameter :: n = 100000\n    complex, pointer :: c1(:), c2(:), c3(:)\n    ! ...\n    allocate( r1(n), r2(n), r3(n) )\n    ! ... some computations on r1(:) and r2(:) as reals\n    call rfft(r1) ; call rfft(r2)\n    c1 => r1 ; c2 => r2 ; c3 => r3\n    c3(:) = c1(:) * c2(:)\n    call irfft(r3)\n    ! ... some computations on r3(:) as real\n    end program\n\n3.1. Syntax\n\nNo new syntax need to be created, the usual pointer association can be\nused, with additional rules and restrictions:\n\n`c => r`\n\n- `r` shall be a  *contiguous* real array, which has either the target\n  or the pointer attribute\n- `c` shall be a complex array pointer of the same kind as `r`, and of\n  the same rank by default (but pointer rank remapping can be used)\n  - `c` could also be a complex scalar pointer, in the case r is a\n    rank-1 array of size 2\n- the size of the first dimension of `r` shall be even\n- `c%re` shall refer to the same storage as `r(1::2)` (rank-1), or\n  `r(1::2,:)` (rank-2), etc...\n- `c%im` shall refer to the same storage as `r(2::2)` (rank-1), or\n  `r(2::2,:)` (rank-2), etc...\n\n`r => c`\n\n- the exact opposite\n- `c` shall be a *contiguous* complex array or a complex scalar, which\n  has either the target or the pointer attribute\n- `r` shall be a real array pointer of the same kind as `c`, and of the\n  same rank by default (but pointer rank remapping can be used)\n  - if `c` is a scalar, then `r` shall be a rank-1 pointer of size 2\n- same other rules as above\n\n3.2 Alternative syntaxes\n\nIf one wants to make the association between two different types more\nexplicit and more type-safe, a new syntax may be introduced:\n\nAlternative syntax 1 (kind of pointer casting):\n```\nc => complex :: r\nr => real :: c\n```\n\nAlternative syntax 2:\n```\nc => complex_pointer(r)\nr => real_pointer(c)\n```\n\nAlternative syntax 3 (similar to the c_f_pointer() subroutine):\n```\ncall complex_pointer(r,c[,shape][,lower])\ncall real_pointer(c,r[,shape][,lower])\n```\n\nAlternative syntax 4 (more generic, in case other inter-type\nassociations would be allowed in future versions of the standard):\n```\ncall storage_associate(r,c[,shape][,lower])\ncall storage_associate(r,c[,shape][,lower])\n```\n\n3.3 Intermediate representation\n\nDuring the discussions it has been proposed tu use an intermediate\nrepresentation between the real and complex view, which would be a real\nview with an augmented rank and first dimension of size 2. Instead of\ngoing directly from `r(n)` to `c(n/2)` one would define by rank\nremapping:\n`r2(1:2,1:n/2) => r(1:n)`, then `c => r2`\nAnd the other way:\n`r2 => c`, then `r(1:n) => r2(1:2,1:n/2)`\n\nThis could also be coupled with a new pseudo-component notation `c%reim`\nthat would be equivalent the `r2` respresentation (i.e. `c%reim` would be\n`real`, with a shape [2,n/2]).\n\nI personally find that such an intermediate representation just makes\nthe proposal more complex than it needs to be, and that nothing really\nuseful can be performed with it. Moreover the `c%reim` notation would\nrequire another change in the standard to allow non zero ranks on both\nsides of `%`.\n\n3.4 Prototyping, etc...\n\nI think that this proposal doesn't need to have a preliminary prototype\nimplementation, as it essentially consists in standardizing an already\nexisting and common practice. A prototype implementation would do\nnothing else than mimicing the `c_f_pointer()` trick.\n\n\n4. Issues / Objections / Limitations\n\n4.1. Memory layout\n\nThis proposal would constraint the memory layout of the complex type\nbeyond what the current standard does. However, the required layout\nseems to be the de-facto standard, used by virtually all existing\ncompilers (i.e. storing a complex scalar by the sequence real part/\nimaginary part, in that order).\n\nAlso, the proposal would not prevent alternative memory layouts for\nthe arrays in future versions of the standard, such as the row major\nstorage. For instance, in the case of a row major 2D array, `c%re`\nwould refer to the same storage as `r(:,1::2)` instead of `r(1::2,:)`\nfor the column major case. More generally the obtained view would be\nlayout dependent, and the standard would have to describe the view for\neach layout.\n\nSimilarly, the proposal would be compatible with the so-called\nsplit-complex layout, if introduced later (without assessing here if\nsuch a layout is possible at all). In this layout, a complex array is\nstored with all the real parts first, then all the imaginary parts.\nIn this case, `c%re` would refer to the same storage as `r(1:n/2)`.\n\n4.2. Argument association\n\nAllowing a real actual argument to be associated to a complex dummy\nargument -and vice-versa- has also been considered, but it would raise\nbackward compatibility issues. So this part has been dropped from the\nproposal.\n\n4.3. Alignment\n\nConsidering for instance a default real type stored on 4 bytes, the\ndefault complex type is stored on 8 bytes. Compilers may prefer/want to\nalign the complex arrays on 8 bytes boundaries, which cannot be\nguaranteed if a complex pointer is associated to an arbitrary real array\n(e.g. `c => r(2:)`). If this is a problem, the pointer association may\nbe allowed only the other way (real pointer associated to a complex\narray), where alignement should not be a problem.\n\n\n5. References\n\n[1] https://www.fftw.org/fftw3_doc/Reversing-array-dimensions.html\n\n[2]\nhttps://fortran-lang.discourse.group/t/\nimplicit-real-complex-conversion-in-fortran/7381\n\nhttps://stackoverflow.com/questions/31590004/\nis-the-storage-of-complex-in-fortran-guaranteed-to-be-two-reals\n\nhttps://stackoverflow.com/questions/36977737/\npass-a-real-array-if-a-complex-array-is-expected\n\nDiscussions related to this proposal:\nhttps://fortran-lang.discourse.group/t/complex-type-storage-again/7020\nhttps://github.com/j3-fortran/fortran_proposals/issues/323\nhttps://github.com/j3-fortran/fortran_proposals/pull/325\n"
  },
  {
    "path": "proposals/conditional_expressions/21-165.txt",
    "content": "To: J3                                                     J3/21-165\nFrom: Ondrej Certik, Milan Curcic, Zach Jibben\nSubject: Conditional expressions using intrinsic function\nDate: 2021-June-27\nReference: 21-157, 21-159\n\nPaper 21-157 proposes two syntactic forms for conditional expressions. The\npaper 21-159 proposes an alternative form. This paper proposes to implement\nconditional expressions using an intrinsic function.\n\nThe syntactic forms in 21-157 are too verbose, as argued in 21-159. The\nform in 21-159 is concise, but based on the poll [1], it is not the most\npopular either.\n\nWe propose the following syntactic form\n\n   <cond-expr> is ifthen( predicate, consequent, alternative )\n\nwhere the `predicate` is a scalar logical expression and the `consequent`\nand `alternative` are compatible expressions. The `alternative` can be\nanother `ifthen` as shown in an example below.\n\nExamples:\n\n      res = ifthen(x >= 0.0, sqrt(x), -0.0)\n\n      res = ifthen(present(x), a, ifthen(present(b), b, 0))\n\nObjections raised in the past:\n\n1) It is harder to do chaining due to the extra parenthesis at the end.\n\nAnswer: it seems in practice it is not too bad, as in the second example\nabove.  Here is a longer chain:\n\n      res = ifthen(present(x), x, ifthen(present(y), y,\n                     ifthen(present(z), z, 0)))\n\n2) `ifthen` does not behave like a regular function, it is effectively new\nsyntax, so we might as well actually introduce new syntax, to make it less\nconfusing\n\nThere is a precedent in optional arguments, where the argument is not\nevaluated but passed through through nested functions until it hits the\nfunction `present`. In a similar way, the arguments to `ifthen` are not\nevaluated ahead of time, but rather passed into the function `ifthen`\nitself, similar to how `present(x)` works. Both `ifthen` and `present` must\nbe implemented by the compiler itself, they cannot be implemented in\nstandard Fortran code.\n\nReferences:\n\n[1] https://fortran-lang.discourse.group/t/\n    poll-fortran-202x-conditional-expressions-syntax/1425\n\n\n"
  },
  {
    "path": "proposals/default_optional_arguments/proposal.txt",
    "content": "To: J3                                                     J3/XX-XXX\nFrom: Milan Curcic, Jeremie Vandenplas, Zach Jibben\nSubject: Default value for optional arguments\nDate: 2020-January-10\nReference: 18-136r1, 18-122r1\n\n\n1. Introduction\n\nThis paper contains a proposal for Fortran 202y, to allow a programmer\nto specify a default value for optional dummy arguments. This would\nallow the programmer to then safely reference such variables in\nexpressions regardless of whether the actual argument is present or\nnot.\n\n2. Problem\n\nCurrently, standard Fortran does not allow setting a default value for\noptional arguments. Default value of an optional argument is the value\nthat the dummy argument would take if the corresponding actual argument\nis not present. If declaring a dummy argument as optional, the user\nmust:\n\n  * Explicitly test for the presence of the actual argument using the\n    intrinsic function present();\n  * Use a separate variable inside the procedure to assign the value\n    because the optional dummy argument that is not present must not be\n    referenced in expressions other than as actual argument to the\n    intrinsic function present().\n\nThis example function illustrates the problem:\n\n    real function quadratic(x, a, b, c)  \n      ! returns a + b * x + c * x**2 if c is present \n      ! and a + b * x otherwise\n      real, intent(in) :: x, a, b\n      real, intent(in), optional :: c\n      real :: c_tmp ! use another var. to reference the missing arg\n      c_tmp = 0 ! default value if c is not present\n      if (present(c)) c_tmp = c\n      quadratic = a + b * x + c_tmp * x**2\n    end function quadratic\n\nFor any dummy argument with the optional attribute, the programmer must\nuse the intrinsic function present() to check for the presence of the\nargument. Furthermore, if the optional dummy argument is meant to be\nused in multiple places in the procedure, the programmer is likely to\nuse the pattern from the example above, where a \"temporary\" variable is\ndeclared and used in place of the dummy argument, which disconnects the\nimplementation from the user interface. Furthermore, this requires at\nleast 3 lines of code (declaration of c_tmp, initialization of c_tmp,\nand testing for the presence of c) only to handle the scenario of a\nmissing optional argument.\n\nThis proposal seeks to address the issue that explicitly checking for\npresence of the optional dummy argument and using a helper variable is\ncumbersome and error-prone. The primary benefit of this feature is the\nreduction in source code needed to handle optional arguments. This\nbenefit is even greater in scenarios where the optional argument is\nused in many places in the procedure, and a helper variable is used for\nits value instead. Reduction in needed source code would result in more\nreadable and more correct programs. The secondary benefit of this is\nprogrammer happiness, as working with optional arguments would require\nless typing.\n\n3. Proposed solution\n\nAs suggested by Van Snyder in 18-136r1, the problem could be solved by\nallowing an optional argument to be initialized using a constant\nexpression. The optional argument would then only be initialized if the\ncorresponding actual argument is not provided by the caller. Example:\n\n    real function quadratic(x, a, b, c)\n      ! returns a + b * x + c * x**2 if c is present \n      ! and a + b * x otherwise\n      real, intent(in) :: x, a, b\n      real, intent(in), optional :: c = 0\n      quadratic = a + b * x + c * x**2\n    end function quadratic\n\nIn this snippet, we use the assignment operator (=) to specify the\ndefault value of the optional dummy argument.\n\nLike initializer, the optional argument can be assigned any constant \nexpression, as defined in Section 10.1.12 of 18-007r1.\n\nWhile there may be concerns that the same syntax is used to implicitly\nset the save attribute for variables in procedures, there is no\nconflict because the language prohibits dummy arguments from having an\ninitializer, or the save attribute. The change to the standard to allow\nthis feature would thus be to allow an optional dummy argument to have\nan initializer, which would be triggered only when corresponding actual\nargument is not passed by the caller.\n\nThis improvement has already been suggested by Van Snyder in 18-136r1,\nhas received votes in the user survey for 202X (see\nisotc.iso.org/livelink/livelink?func=ll&objId=19530634&objAction=Open),\nand appeared on Data subgroup's wishlist at meeting 215 (see 18-122r1).\n\n4. Backward compatibility\n\nThis addition to the language would not break any existing standard\nconforming Fortran program, and thus preserves Fortran's backward\ncompatibility.\n\n5. Related behavior\n\n5.1. present()\n\nThere are two possible behaviors of the function present() when an\ninitializer is provided.\n\nThe first behavior would be that the function present() always returns\n.true. when the optional dummy argument has an initializer, and\nindependently of the fact that an actual argument is passed or not\nby the caller. Therefore, with such a behavior, the function present()\nbecomes useless for optional arguments with a default value.\n\nExample:\n\n    real function foo(a, b)\n      real, intent(in), optional :: a\n      real, intent(in), optional :: b = 0\n      print*, present(a)  !.true. if an actual argument is provided\n                          !by the caller, .false. otherwise\n      print*, present(b)  !always .true. due to the initializer\n    end function foo\n\nThe second behavior would be that the function present() returns\n.true. or .false. when an actual argument is passed or not by the\ncaller, and independently of the fact that the optional dummy\nargument has, or hasn't an initializer.\n\nA use case of this behavior of the function present() could be:\n\n    real function foo(a, b)\n      real, intent(in) :: a\n      real, intent(in), optional :: b = 1.234\n      if (present(b)) then\n       ... !expensive input validation  here\n      end if\n      ...\n    end function foo\n\n5.2. intent(out)\n\nThere are several different possible behaviors for intent(out)\nvariables. One option is to disallow default values on optional\nintent(out) variables. However, there are use cases where it is\ndesirable to return the value of a variable if a caller requests it,\nwithout requiring the added logic of present() and \"temporary\"\nvariables described above.\n\nAlternatively, we might treat intent(in) and intent(out) variables\nidentically, so that the following would be valid:\n\n    real function foo(a)\n      real, intent(out), optional :: a = 0\n    end function foo\n\nThe benefit is that, just like proposed for intent(in) variables,\nintent(out) variables would be usable regardless of whether the value\nis actually passed back to the caller, removing the need for present()\nand \"temporary\" variables. The complication is that a present\nintent(out) variable is initially undefined, meaning the logic of\npresent() might still be necessary in this case. Furthermore, the\nbehavior suggested above where present() = .true. always for variables\nwith a specified default would not be desired for intent(out)\nvariables. A possible use case for this behavior could be:\n\n    integer function open(filename, mode, iostat) result(u)\n      character(*), intent(in) :: filename\n      character(*), intent(in), optional :: mode\n      integer, intent(out), optional :: iostat = 0\n      character(3) :: mode_\n      character(:),allocatable :: action_, position_, status_, access_\n      character(:),allocatable :: form_\n      !some code\n      !....\n      open(newunit=u, file=filename, &\n          action = action_, position = position_, status = status_, &\n          access = access_, form = form_, &\n          iostat = iostat)\n    end function\n\nA third option is that optional intent(out) variables with a specified\ndefault are always initialized to that default, even when present,\nrather than leaving them undefined.\n\n5.3 intent(inout)\n\nDummy arguments with intent(inout) or no specified intent follow from\nthe behavior for intent(in) and intent(out). If an optional\nintent(inout) variable is present, the existing behavior is\nfollowed. The dummy variable has the value of the actual argument on\ninvocation of the procedure, its data may be used or manipulated during\nthe scope of the procedure, then it is returned to the scoping unit. If\nan actual argument is not provided for an optional dummy argument with\na specified default and intent(inout), the variable recieves the\ndefault value and may be used or modified throughout the procedure. The\ndata is then not returned to the scoping unit, since no actual argument\nwas provided.\n\nThis would allow the following routine:\n\n    subroutine foo(x)\n      integer, intent(inout), optional :: x = 0\n\n      ! do stuff that could use or assign to x\n    end subroutine foo\n\nThis would be equivalent to:\n\n    subroutine foo(x)\n      integer, intent(inout), optional :: x\n\n      integer :: x_\n\n      if (present(x)) then\n          x_ = x\n      else\n          x_ = 0\n      end if\n\n      ! do stuff that could use or assign to x_\n\n      if (present(x)) x = x_\n    end subroutine foo\n\n\n5.4 Arrays\n\nDefault values for array dummy arguments present a difficulty,\nparticularly expressions involving a scalar. Some decision must be made\nfor the behavior in the following instances:\n\n    real, intent(in), optional :: a(:) = 0\n    real, intent(inout), optional :: b(:) = 0\n    real, intent(inout), allocatable, optional :: c(:) = 0\n\nIn each case, the size of the array is not determined if an actual\nargument is not provided. One option is of course to forbid defaults\nfor arrays. This isn't preferable, but allowing defaults for scalars\nonly may still address the majority of use cases. Another option is to\nforbid array broadcasting as a default specifier. That is, allow only\ndefaults such as [0,0] for arrays, where the length is clear.\n\n6. Further discussion\n\nOnline discussion that led to this proposal can be found at\nhttps://github.com/j3-fortran/fortran_proposals/issue/22.\n"
  },
  {
    "path": "proposals/fp_interop/25-189r1.txt",
    "content": "To: J3                                                     J3/25-189r1\nFrom: Patrick Fasano\nSubject: Requirements and specifications for interoperability with C\n         interchange and extended types\nDate: 2025-October-28\n\nReferences:\n      ISO/IEC 9899:2024 Programming languages -- C (\"C23\")\n            (working draft N3220)\n      WG5/N2249 Fortran 202Y Work Items\n      23-176 Add extended floating-point types defined in ISO C23\n            to ISO_C_BINDING\n      ISO/IEC 60559:2020 Floating-Point arithmetic\n      IEEE 754-2019 IEEE Standard for Floating-Point Arithmetic\n      25-189 Requirements and specifications for interoperability with C\n            interchange and extended types\n\n\n1 Background\n============\n\nbg01. The ISO C23 specification (ISO/IEC 9899:2024) added support for\n      interchange and extended floating-point types (C23 Annex H). The\n      current Fortran 202Y work list WG5/N2249 includes adding\n      interoperability with these types as accepted work item US05. At\n      meeting #230 in June 2023, J3 accepted paper 23-176 as\n      background/use-case for additional interchange types.\n\nbg03. This paper contains formal requirements and specifications for\n      Fortran 202Y proposal US05, \"Add extended floating-point types\n      defined in ISO C23 to ISO_C_BINDING\".\n\nbg05. The C23 standard adds a large number of new types, importing\n      significant portions of ISO/IEC 60559 (a.k.a IEEE 754) into its\n      specification. During discussion of 25-189 at meeting #237, a\n      straw poll of J3 indicated strong consensus for adding support for\n      extended binary floating types (rq07-rq09) and decimal floating\n      types (rq11), but strong consensus against extended decimal\n      floating types (25-189 rq13) and arbitrary-size floating types\n      (25-189 rq15-rq17). This revision amends the paper to reflect this\n      consensus.\n\n2 Requirements\n==============\n\nrq02. The ISO_C_BINDING module shall provide integer named constants\n      for KIND parameters corresponding to the C interchange floating\n      types '_Float16', '_Float32', '_Float64', and '_Float128'.\n\nrq03. If the companion processor defines '__STDC_IEC_60559_BFP__' and\n      '__STDC_IEC_60559_TYPES__', then the KIND parameters corresponding\n      to '_Float32' and '_Float64' shall equal those corresponding to\n      'float' and 'double', respectively.\n\nrq05. The ISO_C_BINDING module shall provide integer named constants\n      for KIND parameters corresponding to the C interchange complex\n      types '_Float16_Complex', '_Float32_Complex', '_Float64_Complex',\n      and '_Float128_Complex'. The values of the named constants shall\n      equal those of the respective constants for the interchange\n      floating types.\n\nrq07. The ISO_C_BINDING module shall provide integer named constants\n      for KIND parameters corresponding to the C extended floating types\n      '_Float32x', '_Float64x', and '_Float128x'.\n\nrq09. The ISO_C_BINDING module shall provide integer named constants\n      for KIND parameters corresponding to the C extended complex types\n      '_Float32x_Complex', '_Float64x_Complex', and\n      '_Float128x_Complex'. The values of the named constants shall\n      match those of the respective constants for the extended floating\n      types.\n\nrq11. The ISO_C_BINDING module shall provide integer named constants\n      for KIND parameters corresponding to the C interchange decimal\n      floating types '_Decimal32', '_Decimal64', and '_Decimal128'.\n\n3 Specifications\n================\n\nsp01. For all integer named constants to be added to the ISO_C_BINDING\n      module, the value shall be a valid real kind type parameter or\n      shall be -1 if the companion processor's type does not have a\n      precision equal to the precision of any of the Fortran processor's\n      real kinds, -2 if the companion processor's type does not have a\n      range equal to the range of any of the Fortran processor's real\n      kinds, -3 if the companion processor's type has neither the\n      precision nor range of any of the Fortran processor's real kinds,\n      -4 if there is no interoperating Fortran processor kind for other\n      reasons, and -5 if the companion processor does not define the\n      corresponding C type.\n\nsp02. To the ISO_C_BINDING module, add the following integer named\n      constants for real KIND parameters:\n\n      +----------------+--------------------+\n      | Named constant | C interchange type |\n      +----------------+--------------------+\n      | C_FLOAT16      | _Float16           |\n      | C_FLOAT32      | _Float32           |\n      | C_FLOAT64      | _Float64           |\n      | C_FLOAT128     | _Float128          |\n      +----------------+--------------------+\n\n      If the companion processor defines '__STDC_IEC_60559_BFP__' and\n      '__STDC_IEC_60559_TYPES__', then the constants 'C_FLOAT32' and\n      'C_FLOAT64' shall have the same values as 'C_FLOAT' and\n      'C_DOUBLE', respectively (C2023 H.2.4.2).\n\nsp05. To the ISO_C_BINDING module, add the following integer named\n      constants for real KIND parameters:\n\n      +--------------------+--------------------+\n      | Named constant     | C interchange type |\n      +--------------------+--------------------+\n      | C_FLOAT16_COMPLEX  | _Float16_Complex   |\n      | C_FLOAT32_COMPLEX  | _Float32_Complex   |\n      | C_FLOAT64_COMPLEX  | _Float64_Complex   |\n      | C_FLOAT128_COMPLEX | _Float128_Complex  |\n      +--------------------+--------------------+\n\n      The values of each of these named constants shall be the same as\n      the respective constants defined in sp01.\n\nsp07. To the ISO_C_BINDING module, add the following integer named\n      constants for real KIND parameters:\n\n      +----------------+-----------------+\n      | Named constant | C extended type |\n      +----------------+-----------------+\n      | C_FLOAT32X     | _Float32x       |\n      | C_FLOAT64X     | _Float64x       |\n      | C_FLOAT128X    | _Float128x      |\n      +----------------+-----------------+\n\nsp09. To the ISO_C_BINDING module, add the following integer named\n      constants for real KIND parameters:\n\n      +---------------------+--------------------+\n      | Named constant      | C extended type    |\n      +---------------------+--------------------+\n      | C_FLOAT32X_COMPLEX  | _Float32x_Complex  |\n      | C_FLOAT64X_COMPLEX  | _Float64x_Complex  |\n      | C_FLOAT128X_COMPLEX | _Float128x_Complex |\n      +---------------------+--------------------+\n\nsp11. To the ISO_C_BINDING module, add the following integer named\n      constants for real KIND parameters:\n\n      +----------------+--------------------+\n      | Named constant | C interchange type |\n      +----------------+--------------------+\n      | C_DECIMAL32    | _Decimal32         |\n      | C_DECIMAL64    | _Decimal64         |\n      | C_DECIMAL128   | _Decimal128        |\n      +----------------+--------------------+\n\n=== END ===\n"
  },
  {
    "path": "proposals/fp_interop/25-203.txt",
    "content": "To: J3                                                     J3/25-203\nFrom: Patrick Fasano\nSubject: US05: Edits for C interchange and extended floating types\nDate: 2025-October-30\n\nReferences:\n      ISO/IEC 9899:2024 Programming languages -- C (\"C23\")\n            (working draft N3220)\n      WG5/N2249 Fortran 202Y Work Items\n      ISO/IEC 60559:2020 Floating-Point arithmetic\n      25-189r1 Requirements and specifications for interoperability with\n            C interchange and extended types\n      25-007r1 Fortran 2028 Working Draft\n\n\n1 Background\n============\n\nThe ISO C23 specification (ISO/IEC 9899:2024) added support for\ninterchange and extended floating-point types (C23 Annex H). The current\nFortran 202Y work list WG5/N2249 includes adding interoperability with\nthese types as accepted work item US05. At meeting #237 in October 2025,\nJ3 passed paper 25-189r1 as requirements and specifications for\nadditional floating types.\n\nThis paper provides edits for Fortran 202Y proposal US05, \"Add C\ninteroperability for new interchange floating point types in C\".\n\nThe ISO C23 specification also added 'bool' as a keyword with an\nalternate spelling of '_Bool'. This paper optionally provides edits for\nFortran 202Y to propagate this change.\n\n2 Edits (relative to 25-007r1)\n==============================\n\n------------------------------------------------------------------------\n\n[xv] Add to \"Intrinsic modules\" the sentences:\n\nNamed constants have been added to the ISO_C_BINDING module to allow\ninteroperability with C interchange and extended floating-point formats\ndefined in ISO/IEC 9899:2024 Annex H.\n\n------------------------------------------------------------------------\n\n[539:7-14] Replace 18.2.2 paragraph 4 with the following paragraphs:\n\nThe values of C_FLOAT, C_DOUBLE, C_LONG_DOUBLE, C_FLOAT16, C_FLOAT32,\nC_FLOAT64, C_FLOAT128, C_FLOAT32X, C_FLOAT64X, C_FLOAT128X, C_DECIMAL32\nC_DECIMAL64, and C_DECIMAL128 shall each be a valid value for a real\nkind type parameter on the processor or shall be -1 if the companion\nprocessor's type does not have a precision equal to the precision of any\nof the Fortran processor's real kinds, -2 if the companion processor's\ntype does not have a range equal to the range of any of the Fortran\nprocessor's real kinds, -3 if the companion processor's type has neither\nthe precision nor range of any of the Fortran processor's real kinds, -4\nif there is no interoperating Fortran processor kind for other reasons,\nor -5 if the companion processor does not define the corresponding C\ntype. The values of C_FLOAT_COMPLEX, C_DOUBLE_COMPLEX,\nC_LONG_DOUBLE_COMPLEX, C_FLOAT16_COMPLEX, C_FLOAT32_COMPLEX,\nC_FLOAT64_COMPLEX, C_FLOAT128_COMPLEX, C_FLOAT32X_COMPLEX,\nC_FLOAT64X_COMPLEX, and C_FLOAT128X_COMPLEX shall be the same as those\nof C_FLOAT, C_DOUBLE, C_LONG_DOUBLE, C_FLOAT16, C_FLOAT32, C_FLOAT64,\nC_FLOAT128, C_FLOAT32X, C_FLOAT64X, and C_FLOAT128X, respectively. If\nthe companion processor defines the C preprocessor macros\n__STDC_IEC_60559_BFP__ and __STDC_IEC_60559_TYPES__, the values of\nC_FLOAT32 and C_FLOAT64 shall be the same as those of C_FLOAT and\nC_DOUBLE, respectively.\n\n------------------------------------------------------------------------\n\n[2:6] Insert a new line:\n\n      ISO/IEC 9899:2024, Programming languages -- C\n\n------------------------------------------------------------------------\n\n[547:13] Replace the line\n\n      The C types mentioned in Table 18.2 are defined in ISO/IEC\n      9899:2018, 6.2.5, 7.19, and 7.20.1.\n\nwith the line\n\n      The C types mentioned in Table 18.2 are defined in ISO/IEC\n      9899:2024, 6.2.5, 7.22, and H.2.\n\n------------------------------------------------------------------------\n\n[547:table 18.2] Add the following rows to the REAL section of the table:\n\n      +--------------+-------------+\n      | C_FLOAT16    | _Float16    |\n      | C_FLOAT32    | _Float32    |\n      | C_FLOAT64    | _Float64    |\n      | C_FLOAT128   | _Float128   |\n      | C_FLOAT32X   | _Float32x   |\n      | C_FLOAT64X   | _Float64x   |\n      | C_FLOAT128X  | _Float128x  |\n      | C_DECIMAL32  | _Decimal32  |\n      | C_DECIMAL64  | _Decimal64  |\n      | C_DECIMAL128 | _Decimal128 |\n      +--------------+-------------+\n\n------------------------------------------------------------------------\n\n[547-548:table 18.2] Add the following rows to the COMPLEX section of\nthe table:\n\n      +---------------------+---------------------+\n      | C_FLOAT16_COMPLEX   | _Float16 _Complex   |\n      | C_FLOAT32_COMPLEX   | _Float32 _Complex   |\n      | C_FLOAT64_COMPLEX   | _Float64 _Complex   |\n      | C_FLOAT128_COMPLEX  | _Float128 _Complex  |\n      | C_FLOAT32X_COMPLEX  | _Float32x _Complex  |\n      | C_FLOAT64X_COMPLEX  | _Float64x _Complex  |\n      | C_FLOAT128X_COMPLEX | _Float128x _Complex |\n      +---------------------+---------------------+\n\n------------------------------------------------------------------------\n\n[557:table 18.4] Add the following rows after the row for\nCFI_type_long_double:\n\n      +---------------------+-------------+\n      | CFI_type_Float16    | _Float16    |\n      | CFI_type_Float32    | _Float32    |\n      | CFI_type_Float64    | _Float64    |\n      | CFI_type_Float128   | _Float128   |\n      | CFI_type_Float32x   | _Float32x   |\n      | CFI_type_Float64x   | _Float64x   |\n      | CFI_type_Float128x  | _Float128x  |\n      | CFI_type_Decimal32  | _Decimal32  |\n      | CFI_type_Decimal64  | _Decimal64  |\n      | CFI_type_Decimal128 | _Decimal128 |\n      +---------------------+-------------+\n\n------------------------------------------------------------------------\n\n[557:table 18.4] Add the following rows after the row for\nCFI_type_long_double_Complex:\n\n      +----------------------------+---------------------+\n      | CFI_type_Float16_Complex   | _Float16 _Complex   |\n      | CFI_type_Float32_Complex   | _Float32 _Complex   |\n      | CFI_type_Float64_Complex   | _Float64 _Complex   |\n      | CFI_type_Float128_Complex  | _Float128 _Complex  |\n      | CFI_type_Float32X_Complex  | _Float32x _Complex  |\n      | CFI_type_Float64X_Complex  | _Float64x _Complex  |\n      | CFI_type_Float128X_Complex | _Float128x _Complex |\n      +----------------------------+---------------------+\n\n------------------------------------------------------------------------\n\n[538:30] Replace two instances of:\n\n      (_Bool)\n\nwith:\n\n      (bool)\n\n------------------------------------------------------------------------\n\n[548:table 18.2] Replace the following:\n\n      _Bool\n\nwith:\n\n      bool\n\n------------------------------------------------------------------------\n\n[557:table 18.4] Replace the following:\n\n      +---------------+-------+\n      | CFI_type_Bool | _Bool |\n      +---------------+-------+\n\nwith:\n\n      +---------------+------+\n      | CFI_type_Bool | bool |\n      | CFI_type_bool | bool |\n      +---------------+------+\n\n------------------------------------------------------------------------\n\n===END===\n"
  },
  {
    "path": "proposals/fp_interop/25-203r1.txt",
    "content": "To: J3                                                     J3/25-203r1\nFrom: Patrick Fasano\nSubject: US05: Edits for C interchange and extended floating types\nDate: 2026-January-12\n\nReferences:\n      ISO/IEC 9899:2024 Programming languages -- C (\"C23\")\n            (working draft N3220)\n      WG5/N2249 Fortran 202Y Work Items\n      ISO/IEC 60559:2020 Floating-Point arithmetic\n      25-189r1 Requirements and specifications for interoperability with\n            C interchange and extended types\n      25-007r1 Fortran 2028 Working Draft\n\n\n1 Background\n============\n\nThe ISO C23 specification (ISO/IEC 9899:2024) added support for\ninterchange and extended floating-point types (C23 Annex H). The current\nFortran 202Y work list WG5/N2249 includes adding interoperability with\nthese types as accepted work item US05. At meeting #237 in October 2025,\nJ3 passed paper 25-189r1 as requirements and specifications for\nadditional floating types.\n\nThis paper provides edits for Fortran 202Y proposal US05, \"Add C\ninteroperability for new interchange floating point types in C\".\n\nThe ISO C23 specification also added 'bool' as a keyword with an\nalternate spelling of '_Bool'. This paper additionally provides edits for\nFortran 202Y to propagate this change.\n\n2 Edits (relative to 25-007r1)\n==============================\n\n------------------------------------------------------------------------\n\n[xv] Add to \"Intrinsic modules\" the sentences:\n\nNamed constants have been added to the ISO_C_BINDING module to allow\ninteroperability with C interchange and extended floating-point formats\ndefined in ISO/IEC 9899:2024 Annex H.\n\n------------------------------------------------------------------------\n\n[539:7-14] Replace 18.2.2 paragraph 4 with the following paragraphs:\n\nThe values of C_FLOAT, C_DOUBLE, C_LONG_DOUBLE, C_FLOAT16, C_FLOAT32,\nC_FLOAT64, C_FLOAT128, C_FLOAT32X, C_FLOAT64X, C_FLOAT128X, C_DECIMAL32\nC_DECIMAL64, and C_DECIMAL128 shall each be a valid value for a real\nkind type parameter on the processor or shall be -1 if the companion\nprocessor's type does not have a precision equal to the precision of any\nof the Fortran processor's real kinds, -2 if the companion processor's\ntype does not have a range equal to the range of any of the Fortran\nprocessor's real kinds, -3 if the companion processor's type has neither\nthe precision nor range of any of the Fortran processor's real kinds, -4\nif there is no interoperating Fortran processor kind for other reasons,\nor -5 if the companion processor does not define the corresponding C\ntype. The values of C_FLOAT_COMPLEX, C_DOUBLE_COMPLEX,\nC_LONG_DOUBLE_COMPLEX, C_FLOAT16_COMPLEX, C_FLOAT32_COMPLEX,\nC_FLOAT64_COMPLEX, C_FLOAT128_COMPLEX, C_FLOAT32X_COMPLEX,\nC_FLOAT64X_COMPLEX, and C_FLOAT128X_COMPLEX shall be the same as those\nof C_FLOAT, C_DOUBLE, C_LONG_DOUBLE, C_FLOAT16, C_FLOAT32, C_FLOAT64,\nC_FLOAT128, C_FLOAT32X, C_FLOAT64X, and C_FLOAT128X, respectively. If\nthe companion processor defines the C preprocessor macros\n__STDC_IEC_60559_BFP__ and __STDC_IEC_60559_TYPES__, the values of\nC_FLOAT32 and C_FLOAT64 shall be the same as those of C_FLOAT and\nC_DOUBLE, respectively.\n\n------------------------------------------------------------------------\n\n[2:6] Replace the line:\n\n      ISO/IEC 9899:2018, Programming languages -- C\n\nwith the line\n\n      ISO/IEC 9899:2024, Programming languages -- C\n\n------------------------------------------------------------------------\n\n[547:13] Replace the line\n\n      The C types mentioned in Table 18.2 are defined in ISO/IEC\n      9899:2018, 6.2.5, 7.19, and 7.20.1.\n\nwith the line\n\n      The C types mentioned in Table 18.2 are defined in ISO/IEC\n      9899:2024, 6.2.5, 7.22, and H.2.\n\n------------------------------------------------------------------------\n\n[547:table 18.2] Add the following rows to the REAL section of the table:\n\n      +--------------+-------------+\n      | C_FLOAT16    | _Float16    |\n      | C_FLOAT32    | _Float32    |\n      | C_FLOAT64    | _Float64    |\n      | C_FLOAT128   | _Float128   |\n      | C_FLOAT32X   | _Float32x   |\n      | C_FLOAT64X   | _Float64x   |\n      | C_FLOAT128X  | _Float128x  |\n      | C_DECIMAL32  | _Decimal32  |\n      | C_DECIMAL64  | _Decimal64  |\n      | C_DECIMAL128 | _Decimal128 |\n      +--------------+-------------+\n\n------------------------------------------------------------------------\n\n[547-548:table 18.2] Add the following rows to the COMPLEX section of\nthe table:\n\n      +---------------------+---------------------+\n      | C_FLOAT16_COMPLEX   | _Float16 _Complex   |\n      | C_FLOAT32_COMPLEX   | _Float32 _Complex   |\n      | C_FLOAT64_COMPLEX   | _Float64 _Complex   |\n      | C_FLOAT128_COMPLEX  | _Float128 _Complex  |\n      | C_FLOAT32X_COMPLEX  | _Float32x _Complex  |\n      | C_FLOAT64X_COMPLEX  | _Float64x _Complex  |\n      | C_FLOAT128X_COMPLEX | _Float128x _Complex |\n      +---------------------+---------------------+\n\n------------------------------------------------------------------------\n\n[557:table 18.4] Add the following rows after the row for\nCFI_type_long_double:\n\n      +---------------------+-------------+\n      | CFI_type_Float16    | _Float16    |\n      | CFI_type_Float32    | _Float32    |\n      | CFI_type_Float64    | _Float64    |\n      | CFI_type_Float128   | _Float128   |\n      | CFI_type_Float32x   | _Float32x   |\n      | CFI_type_Float64x   | _Float64x   |\n      | CFI_type_Float128x  | _Float128x  |\n      | CFI_type_Decimal32  | _Decimal32  |\n      | CFI_type_Decimal64  | _Decimal64  |\n      | CFI_type_Decimal128 | _Decimal128 |\n      +---------------------+-------------+\n\n------------------------------------------------------------------------\n\n[557:table 18.4] Add the following rows after the row for\nCFI_type_long_double_Complex:\n\n      +----------------------------+---------------------+\n      | CFI_type_Float16_Complex   | _Float16 _Complex   |\n      | CFI_type_Float32_Complex   | _Float32 _Complex   |\n      | CFI_type_Float64_Complex   | _Float64 _Complex   |\n      | CFI_type_Float128_Complex  | _Float128 _Complex  |\n      | CFI_type_Float32X_Complex  | _Float32x _Complex  |\n      | CFI_type_Float64X_Complex  | _Float64x _Complex  |\n      | CFI_type_Float128X_Complex | _Float128x _Complex |\n      +----------------------------+---------------------+\n\n------------------------------------------------------------------------\n\n[538:30] Replace two instances of:\n\n      (_Bool)\n\nwith:\n\n      (bool)\n\n------------------------------------------------------------------------\n\n[548:table 18.2] Replace the following:\n\n      _Bool\n\nwith:\n\n      bool\n\n------------------------------------------------------------------------\n\n[557:table 18.4] Replace the following:\n\n      +---------------+-------+\n      | CFI_type_Bool | _Bool |\n      +---------------+-------+\n\nwith:\n\n      +---------------+------+\n      | CFI_type_Bool | bool |\n      | CFI_type_bool | bool |\n      +---------------+------+\n\n------------------------------------------------------------------------\n\n===END===\n"
  },
  {
    "path": "proposals/namelist_delimiters/namelist_proposal.txt",
    "content": "To: J3                                                     J3/XX-XXX\nFrom: Marshall Ward\nSubject: Require delimiters for character arrays in namelist output\nDate: 19 November 2019\n\nProposal for Fortran Standard: 202y\n\n\n1. Introduction\n\nAccording to the current standard, a WRITE statement can write a\nnamelist file that does not conform to the namelist specification.  This\nhappens when the namelist group contains a character array and the DELIM\nspecifier has a value of NONE.  In particular, this is the default\nbehavior of a WRITE statement whose input is a namelist.\n\nOur proposal is to require delimiters when using WRITE to write a\nnamelist to a file, by either requiring a value of DELIM which is\nnamelist-compliant, or by overriding a value of NONE when the input is a\nnamelist.\n\n\n2. Motivation\n\nThe namelist format is described in section 13.11 of the standard, and\n13.11.3.3p7 requires that character arrays in namelist groups must be\ndelimited with single or double quotes.\n\n   When the next effective item is of type character, the input form\n   consists of a sequence of zero or more rep-chars whose kind type\n   parameter is implied by the kind of the corresponding list item,\n   delimited by apostrophes or quotes.\n\nAny namelist whose character arrays are non-delimited is non-conformant.\nAny parsing of this output is therefore considered to be unformatted,\nand the interpretation is at the discretion of the interpreter.\n\nWithout delimiters, many character arrays become unparseable.  If a\ncharacter array contains any lexical namelist tokens, such as `&` or\n`/`, then any non-delimited values may be misinterpreted as part of the\nnamelist object structure.\n\nThe standard acknowledges the limitations of non-delimited character\narray parsing, and specifically directs the interpreter to ignore the\nvalue of DELIM when reading a namelist (12.5.6.8).\n\n   The scalar-default-char-expr shall evaluate to APOSTROPHE, QUOTE, or\n   NONE.  The DELIM= specifier is permitted only for a connection for\n   formatted input/output. It specifies the delimiter mode (12.6.2.8)\n   for list-directed (13.10.4) and namelist (13.11.4.2) output for the\n   connection. This mode has no effect on input.\n\nHowever, despite the acknowledgment of the issues above, the default\nbehavior of a WRITE command is to produce non-delimited character\narrays.  From 13.11.4.2p1,\n\n   Values in namelist output records are edited as for list-directed\n   output (13.10.4).\n\nThis is done despite the fact that list-directed output follows\ndifferent I/O rules for character arrays.  From 13.10.3.1p7 (my\nemphasis),\n\n   When the next effective item is of type character, the input form\n   consists of a **possibly** delimited sequence of zero or more\n   rep-chars whose kind type parameter is implied by the kind of the\n   effective item.\n\nThe namelist specification 13.11.3.3p7 deliberately omits \"possibly\"\nfrom its description.\n\nIn other words, list-directed output permits non-delimited arrays,\nwhereas namelists do not.  In addition, the default value of DELIM is to\nrevert back to its value in the OPEN call.  From 12.5.6.8p1,\n\n   If this specifier is omitted in an OPEN statement that initiates a\n   connection, the default value is NONE.\n\nThe default behavior of a WRITE call using namelist data is therefore to\nproduce an output which is non-conformant with the namelist standard.\n\n\n3. Example\n\nConsider the program listed below, which will produce a namelist\ncontaining a single group `sample_nml`, containing a single character\narray, `input`.\n\n   program writenml\n     implicit none\n     character(len=20) :: input\n     namelist /sample_nml/ input\n\n     input = trim(\"some/path/to/file\")\n     open(5, file=\"out.nml\")\n     write(5, nml=sample_nml)\n   end program writenml\n\nAccording to the interpretation above, the absence of a DELIM argument\nmeans that `input` is formatted with no delimiter.  A\nstandard-conforming output would be\n\n   &SAMPLE_NML\n   INPUT   = some/path/to/file   \n   /\n\nFor this example, we have used the output produced by the Intel Fortran\nCompiler 19.0.5.281.\n\nNow consider the following program, which reads this namelist.\n\n   program readnml\n     implicit none\n     character(len=20) :: input\n     namelist /sample_nml/ input\n\n     open(5, file='out.nml')\n     read(5, nml=sample_nml)\n\n     open(6, file='new.nml')\n     write(6, nml=sample_nml)\n   end program readnml\n\nThe namelist `new.nml` produced by this program is the following.\n\n   &SAMPLE_NML\n   INPUT   = some\n   /\n\nThe namelist group `sample_nml` is terminated after the first `/` token,\nand any characters following the token are ignored.\n\nAlthough the interpretation is correct, it also means that a write\nstatement of the following form\n\n   write(unit, nml=filename)\n\nwhere the DELIM argument is unset will produce namelists which are\nnon-conforming.  The fact that this is not only possible, but is the\ndefault behavior, is counterintuitive and is likely to introduce errors\ninto namelist I/O operations.\n\nAs an aside, we note that GNU Fortran explicitly breaks from the\nstandard and does produce a quote-delimited namelist, such as the one\nshown below.\n\n&SAMPLE_NML\n INPUT=\"some/path/to/file   \",\n /\n\nThis namelist above was produced by GNU Fortran 9.2.1.\n\n\n4. Proposal\n\nWe propose one of the following additions to the *io-control-spec-list*,\ndetailed in 12.6.2.1.\n\nA. If *namelist-group-name* appears, then a DELIM= specifier with the\n   value of either APOSTROPHE or QUOTE shall also appear.\n\nOption A would take the current recommended advice to always use DELIM\nwhen writing namelist output and turn it into an explicit rule.  The\nfollowing statement would constitute an error\n\n   write(unit, nml=filename)\n\nand would require the user to include a DELIM argument, e.g.\n\n   write(unit, nml=filename, delim=\"quote\")\n\nThis would also mean that currently compliant code missing a DELIM would\nbe non-compliant, and may require modifications if used by future\ninterpreters.\n\nB. If *namelist-group-name* appears and a DELIM= specifier has the value\n   of NONE, then this value is ignored and the data transfer uses a\n   value of APOSTROPHE.\n\nOption B would change the behavior of existing standard-compliant\ninterpreters, in that non-delimited character arrays would be replaced\nwith apostrophe-delimited arrays.  But existing source code would\notherwise remain compliant and continue to compile on both older and\nnewer interpreters.\n\n\n5. Reference\n\nDiscussion of this issue on the Intel Fortran forums:\n\n   https://software.intel.com/en-us/forums/intel-fortran-compiler/topic/831685\n\nDiscussion of GNU Fortran's decision to use quote delimiters:\n\n   https://gcc.gnu.org/ml/gcc-patches/2014-03/msg00030.html\n\nInitial submission and discussion to the J3 Fortran Github repository:\n\n   https://github.com/j3-fortran/fortran_proposals/pull/94\n"
  },
  {
    "path": "proposals/namespace_modules/19-246.txt",
    "content": "To: J3                                                     J3/19-246\nFrom: Ondrej Certik\nSubject: Namespace For Modules\nDate: 2019-October-16\n\nProposal for Fortran Standard: 202y (NOT 202x)\n\n\n1. Introduction\n\nThe proposal is to allow import a module as a namespace and access its\nmembers using the % operator. Example:\n\n    use, namespace :: utils\n    ...\n    call utils%savetxt(...)\n\nWhere `utils` is the only name that is imported in the local namespace.\n`savetxt` is not accesible directly, only via `utils%`.\n\n2. Motivation\n\nFortran module usage is equivalent to Python:\n\n    Python                                   Fortran\n\n    from A import foo                        use A, only: foo\n    from A import foo as Afoo                use A, only: Afoo => foo\n    from A import *                          use A\n\nExcept:\n\n    Python                                   Fortran\n\n    import A                                 N/A\n    import A as B                            N/A\n\nThis proposal proposes to fill in the missing functionality as follows:\n\n    Python                                   Fortran\n\n    import A                                 use, namespace :: A\n    import A as B                            use, namespace :: B => A\n\n3. Use Cases\n\n3.1 Same function names in multiple modules\n\nIn Python a very common idiom is:\n\n    import math\n    import numpy as np\n    import sympy as sym\n    ...\n    e1 = np.sin(np.pi)      # NumPy expression\n    e2 = math.sin(math.pi)  # Built-in Python math expression\n    e3 = sym.sin(sym.pi)    # SymPy expression\n\nIn Fortran currently one has to do:\n\n    use math, only: math_sin => sin, math_pi => pi\n    use numpy, only: np_sin => sin, np_pi => pi\n    use sympy, only: sym_sin => sin, sym_pi => pi\n    ...\n    e1 = np_sin(np_pi)      ! NumPy expression\n    e2 = math_sin(math_pi)  ! Built-in Python math expression\n    e3 = sym_sin(sym_pi)    ! SymPy expression\n\nWith this proposal one could also do:\n\n    use, namespace :: math\n    use, namespace :: np => numpy\n    use, namespace :: sym => sympy\n    ...\n    e1 = np%sin(np%pi)      ! NumPy expression\n    e2 = math%sin(math%pi)  ! Built-in Python math expression\n    e3 = sym%sin(sym%pi)    ! SymPy expression\n\n\n3.2 Need to import lots of functions from a module\n\nExising code (https://github.com/certik/fortran-utils/blob/\nb43bd24cd421509a5bc6d3b9c3eeae8ce856ed88/src/linalg.f90):\n\n    use lapack, only: dsyevd, dsygvd, ilaenv, zgetri, zgetrf, zheevd, &\n        dgeev, zgeev, zhegvd, dgesv, zgesv, dgetrf, dgetri, dgelsy, &\n        zgelsy, dgesvd, zgesvd, dgeqrf, dorgqr, dpotrf, dtrtrs\n    ...\n    call dgeev('N', 'V', n, At, lda, wr, wi, vl, ldvl, vr, ldvr, &\n     work, lwork, info)\n    ...\n    call dgetrf(n, n, Amt, lda, ipiv, info)\n    ...\n\nInstead, one can write it as:\n\n    use, namespace :: lapack\n    ...\n    call lapack%dgeev('N', 'V', n, At, lda, wr, wi, vl, ldvl, vr, ldvr, &\n     work, lwork, info)\n    ...\n    call lapack%dgetrf(n, n, Amt, lda, ipiv, info)\n    ...\n\nThen when another subroutine must be called from the `lapack` module, one\ncan just call it, without having to modify the `use` statement.\n\n\n"
  },
  {
    "path": "proposals/namespace_modules/20-108.txt",
    "content": "To: J3                                                     J3/20-108\nFrom: Ondrej Certik\nSubject: Namespace For Modules\nDate: 2020-February-23\n\nProposal for Fortran Standard: 202y (NOT 202x)\n\n\n1. Introduction\n\nThe proposal is to allow import a module as a namespace and access its\nmembers using the % operator. Example:\n\n    use, namespace :: utils\n    ...\n    call utils%savetxt(...)\n\nWhere `utils` is the only name that is imported in the local namespace.\n`savetxt` is not accesible directly, only via `utils%`.\n\nThis proposal originated at the J3 GitHub repository at [1].\n\n2. Motivation\n\nFortran module usage is equivalent to Python:\n\n    Python                                   Fortran\n\n    from A import foo                        use A, only: foo\n    from A import foo as Afoo                use A, only: Afoo => foo\n    from A import *                          use A\n\nExcept:\n\n    Python                                   Fortran\n\n    import A                                 N/A\n    import A as B                            N/A\n\nThis proposal proposes to fill in the missing functionality as follows:\n\n    Python                                   Fortran\n\n    import A                                 use, namespace :: A\n    import A as B                            use, namespace :: B => A\n\n3. Use Cases\n\n3.1 Same function names in multiple modules\n\nIn Python a very common idiom is:\n\n    import math\n    import numpy as np\n    import sympy as sym\n    ...\n    e1 = np.sin(np.pi)      # NumPy expression\n    e2 = math.sin(math.pi)  # Built-in Python math expression\n    e3 = sym.sin(sym.pi)    # SymPy expression\n\nIn Fortran currently one has to do:\n\n    use math, only: math_sin => sin, math_pi => pi\n    use numpy, only: np_sin => sin, np_pi => pi\n    use sympy, only: sym_sin => sin, sym_pi => pi\n    ...\n    e1 = np_sin(np_pi)      ! NumPy expression\n    e2 = math_sin(math_pi)  ! Built-in Python math expression\n    e3 = sym_sin(sym_pi)    ! SymPy expression\n\nWith this proposal one could also do:\n\n    use, namespace :: math\n    use, namespace :: np => numpy\n    use, namespace :: sym => sympy\n    ...\n    e1 = np%sin(np%pi)      ! NumPy expression\n    e2 = math%sin(math%pi)  ! Built-in Python math expression\n    e3 = sym%sin(sym%pi)    ! SymPy expression\n\n\n3.2 Need to import lots of functions from a module\n\nExisting code (https://github.com/certik/fortran-utils/blob/\nb43bd24cd421509a5bc6d3b9c3eeae8ce856ed88/src/linalg.f90):\n\n    use lapack, only: dsyevd, dsygvd, ilaenv, zgetri, zgetrf, zheevd, &\n        dgeev, zgeev, zhegvd, dgesv, zgesv, dgetrf, dgetri, dgelsy, &\n        zgelsy, dgesvd, zgesvd, dgeqrf, dorgqr, dpotrf, dtrtrs\n    ...\n    call dgeev('N', 'V', n, At, lda, wr, wi, vl, ldvl, vr, ldvr, &\n     work, lwork, info)\n    ...\n    call dgetrf(n, n, Amt, lda, ipiv, info)\n    ...\n\nInstead, one can write it as:\n\n    use, namespace :: lapack\n    ...\n    call lapack%dgeev('N', 'V', n, At, lda, wr, wi, vl, ldvl, vr, ldvr, &\n     work, lwork, info)\n    ...\n    call lapack%dgetrf(n, n, Amt, lda, ipiv, info)\n    ...\n\nThen when another subroutine must be called from the `lapack` module, one\ncan just call it, without having to modify the `use` statement.\n\n4. References\n\n[1] https://github.com/j3-fortran/fortran_proposals/issues/1\n\n\n"
  },
  {
    "path": "proposals/protected_attribute.txt",
    "content": "To: J3                                                     J3/##-###\nFrom: Balint Aradi\nSubject: Protected attribute for derived type components\nDate: 2019-October-21\n\nProposal for Fortran Standard: 202y (NOT 202x)\n\n\n1. Introduction\n\nThe proposal is to allow specify the protected attribute for components in\nderived types. Example:\n\n\n    type :: prot_t\n      integer, allocatable, protected :: array(:)\n    end type prot_t\n\n\n2. Motivation\n\nData hiding using derived types with private components allows programmer\nto provide robust types, where internals can only be changed in controlled\nfashion. The usual implementation is to provide setter and getter routines\nfor writing and reading components. Both operations involve copying the\npassed data, which can be inefficient when storing large arrays in the\nderived type instance. While in the setter routine the copying serves\nrobustness by \"disentangling\" the data stored in the derived type from the\noriginal data, the getter routine and the connected copy operation might be\nsuperfluous, when the consumer only wants to read but not modify the data\nstored in the derived type intance.\n\nBy allowing for a direct read-only access, one could enhance efficiency in\nthose cases without sacrificing the consistency of the encapsulated\ndata. Direct access is possible with current Fortran already, but only if\nthe respective derived type component is public. This would jeopardize data\nconsistency, though, as a consumer could change the respective component\narbitrarily, without using the provided setter routine.\n\nThis proposal suggests to allow the \"protected\" attribute already used for\nmodule variables being used for derived type components as well. It would\nalso remedy the asymmetry between the attributes \"private\"/\"public\" and the\nattribute \"protected\", as the former two can be applied to both, module\nvariables and derived type components, while the latter only for module\nvariables so far.\n\n\n3. Use Cases\n\nDerived types storing large amount of data could enable read-only access to\ncomponents without the necessity of a getter routine and the connected copy\noperation:\n\n  module data_m\n    implicit none\n\n    type :: prot_t\n      ! Large array component\n      integer, allocatable, protected :: array(:)\n    contains\n      procedure :: set\n    end type prot_t\n\n  contains\n\n    subroutine set(this, array)\n      type(prot_t), intent(out) :: this\n\n      this%array = array\n\n    end subroutine set\n\n  end module data_m\n\n\n\n  program use_data\n    use data_m\n    implicit none\n\n    type(prot_t) :: storage\n    integer, allocatable :: large_array(:)\n\n    ! Filling up and allocating the large array\n    ! ...\n\n    ! Storing the large array in the derived type instance\n    call storage%set(large_array)\n\n    ! Accessing large array stored in the derived type directly\n    ! No getter routine and no copy necessary\n    ! Dummy argument of the called routine must be intent(in)\n    call some_routine_processing_but_not_changing_the_array(storage%array)\n\n    ! Inconsistent change, consumer is supposed to call set() to change\n    ! encapsulated data.\n    ! Uncommenting the next line should trigger a compiler error.\n    !storage%array(1) = -1\n\n  end program use_data\n\n4. Online discussion\n\nThis proposal derived from the discussion on the j3-fortran github page:\nhttps://github.com/j3-fortran/fortran_proposals/issues/16\n"
  },
  {
    "path": "proposals/run-time_polymorphism/Examples/AppendixA/taylor.f90",
    "content": "! Fortran implementation of the Taylor series example program based on\n! subclassing given in Appendix A of the proposal \"Improved run-time\n! polymorphism for Fortran\".\n!\n\nmodule derivs\n\n   type, abstract :: Deriv\n   contains\n      procedure(pderiv), deferred, nopass ::  deriv1\n   end type Deriv\n\n   abstract interface\n      subroutine pderiv()\n      end subroutine pderiv      \n   end interface\n   \n   type, extends(Deriv) :: DerivF\n   contains\n      procedure, nopass :: deriv1 => deriv1f\n   end type DerivF\n\n   type, extends(DerivF) :: HDerivF\n   contains\n      procedure, nopass :: deriv2 => deriv2f\n   end type HDerivF\n\n   type, extends(Deriv) :: DerivG\n   contains\n      procedure, nopass :: deriv1 => deriv1g\n   end type DerivG\n\n   type, extends(DerivG) :: HDerivG\n   contains\n      procedure, nopass :: deriv2 => deriv2g\n   end type HDerivG\n   \ncontains\n\n   subroutine deriv1f()\n      write(*,*) ' 1st derivative of function F!'\n   end subroutine deriv1f\n\n   subroutine deriv2f()\n      write(*,*) ' 2nd derivative of function F!'\n   end subroutine deriv2f\n\n   subroutine deriv1g()\n      write(*,*) ' 1st derivative of function G!'\n   end subroutine deriv1g\n\n   subroutine deriv2g()\n      write(*,*) ' 2nd derivative of function G!'\n   end subroutine deriv2g\n\nend module derivs\n\nmodule series\n\n   use derivs, only: Deriv, HDerivF, HDerivG\n\n   type :: Taylor\n      class(Deriv), allocatable :: calc\n   contains\n      procedure :: term1\n      procedure :: evaluate\n   end type Taylor\n\n   type, extends(Taylor) :: HTaylor\n   contains\n      procedure :: term2    => hterm2\n      procedure :: evaluate => hevaluate\n   end type HTaylor\n\ncontains\n\n   subroutine term1(self)\n      class(Taylor), intent(in) :: self\n      call self%calc%deriv1()\n   end subroutine term1\n\n   subroutine evaluate(self)\n      class(Taylor), intent(in) :: self\n      write(*,*) 'Evaluating Taylor series using'\n      call self%term1()\n   end subroutine evaluate\n      \n   subroutine hterm2(self)\n      class(HTaylor), intent(in) :: self\n      select type ( calc => self%calc )\n      class is ( HDerivF )\n         call calc%deriv2()\n      class is ( HDerivG )\n         call calc%deriv2()\n      class default\n         write(*,*) 'Unknown type!'\n      end select\n   end subroutine hterm2\n\n   subroutine hevaluate(self)\n      class(HTaylor), intent(in) :: self\n      write(*,*) 'Evaluating Taylor series using'\n      call self%term1()\n      call self%term2()\n   end subroutine hevaluate\n\nend module series\n\nprogram client\n\n   use derivs, only: DerivG, HDerivG, Deriv\n   use series, only: Taylor, HTaylor\n\n   class(Deriv),  allocatable :: derv\n   class(Taylor), allocatable :: teval\n   \n   derv  = DerivG()\n   teval = Taylor(derv)   \n   call teval%evaluate()   \n\n   write(*,*)\n   \n   derv  = HDerivG()\n   teval = HTaylor(derv)\n   call teval%evaluate()   \n\nend program client\n"
  },
  {
    "path": "proposals/run-time_polymorphism/Examples/AppendixB/taylor.f90",
    "content": "! Fortran implementation of the Taylor series example program based on\n! subtyping given in Appendix B of the proposal \"Improved run-time\n! polymorphism for Fortran\".\n!\n\nmodule interfaces\n\n   abstract interface :: IDeriv\n      subroutine deriv1()\n      end subroutine deriv1\n   end interface IDeriv\n\n   abstract interface, extends(IDeriv) :: IHDeriv\n      subroutine deriv2()\n      end subroutine deriv2\n   end interface IHDeriv\n\nend module interfaces\n   \nmodule derivs\n\n   use interfaces, only: IDeriv, IHDeriv\n   \n   type, implements(IDeriv) :: DerivF\n   contains\n      procedure, nopass :: deriv1 => deriv1f\n   end type DerivF\n\n   type, implements(IHDeriv) :: HDerivF\n   contains\n      procedure, nopass :: deriv1 => deriv1f\n      procedure, nopass :: deriv2 => deriv2f\n   end type HDerivF\n   \n   type, implements(IDeriv) :: DerivG\n   contains\n      procedure, nopass :: deriv1 => deriv1g\n   end type DerivG\n\n   type, implements(IHDeriv) :: HDerivG\n   contains\n      procedure, nopass :: deriv1 => deriv1g\n      procedure, nopass :: deriv2 => deriv2g\n   end type HDerivG\n   \ncontains\n\n   subroutine deriv1f()\n      write(*,*) \" 1st derivative of function F!\"\n   end subroutine deriv1f\n\n   subroutine deriv2f()\n      write(*,*) \" 2nd derivative of function F!\"\n   end subroutine deriv2f\n   \n   subroutine deriv1g()\n      write(*,*) \" 1st derivative of function G!\"\n   end subroutine deriv1g\n   \n   subroutine deriv2g()\n      write(*,*) \" 2nd derivative of function G!\"\n   end subroutine deriv2g\n\nend module derivs\n\nmodule series\n\n   use interfaces, only: IDeriv, IHDeriv\n\n   type :: Taylor\n      class(IDeriv), allocatable :: calc\n   contains\n      procedure :: term1\n      procedure :: evaluate\n   end type Taylor\n   \n   type :: HTaylor\n      class(IHDeriv), allocatable :: calc\n   contains\n      procedure :: term1    => hterm1\n      procedure :: term2    => hterm2\n      procedure :: evaluate => hevaluate\n   end type HTaylor\n \ncontains\n\n    subroutine term1(self)\n       class(Taylor), intent(in) :: self\n       call self%calc%deriv1()\n    end subroutine term1\n    \n    subroutine evaluate(self)\n       class(Taylor), intent(in) :: self\n       write(*,*) 'Evaluating Taylor series using'\n       call self%term1()\n    end subroutine evaluate\n\n    subroutine hterm1(self)\n       class(HTaylor), intent(in) :: self\n       call self%calc%deriv1()\n    end subroutine hterm1\n    \n    subroutine hterm2(self)\n       class(HTaylor), intent(in) :: self\n       call self%calc%deriv2()\n    end subroutine hterm2\n\n    subroutine hevaluate(self)\n       class(HTaylor), intent(in) :: self\n       write(*,*) 'Evaluating Taylor series using'\n       call self%term1()\n       call self%term2()\n    end subroutine hevaluate\n\nend module series\n \nprogram client\n\n   use derivs, only: DerivG, HDerivG\n   use series, only: Taylor, HTaylor\n   \n   type(Taylor),  allocatable :: teval\n   type(HTaylor), allocatable :: hteval\n   \n   teval = Taylor( DerivG() )\n   call teval%evaluate()\n\n   write(*,*)\n\n   hteval = HTaylor( HDerivG() )\n   call hteval%evaluate()\n   \nend program client\n"
  },
  {
    "path": "proposals/run-time_polymorphism/Examples/AppendixB/taylor.java",
    "content": "// Java implementation of the Taylor series example program based on\n// subtyping given in Appendix B of the proposal \"Improved run-time\n// polymorphism for Fortran\".\n//\n\ninterface IDeriv {\n    void deriv1();\n}\n\ninterface IHDeriv extends IDeriv {\n    void deriv2();\n}\n\nclass DerivF implements IDeriv {\n    public void deriv1() {\n      \tSystem.out.println(\" 1st derivative of function F!\");\n    }\n}\n\nclass HDerivF implements IHDeriv {\n    public void deriv1() {\n      \tSystem.out.println(\" 1st derivative of function F!\");\n    }\n    public void deriv2() {\n\tSystem.out.println(\" 2nd derivative of function F!\");\n    }\n}\n\nclass DerivG implements IDeriv {\n    public void deriv1() {\n      \tSystem.out.println(\" 1st derivative of function G!\");\n    }\n}\n\nclass HDerivG implements IHDeriv {\n    public void deriv1() {\n      \tSystem.out.println(\" 1st derivative of function G!\");\n    }\n    public void deriv2() {\n\tSystem.out.println(\" 2nd derivative of function G!\");\n    }\n}\n\nclass Taylor {\n    IDeriv calc;\n    Taylor(IDeriv calculator) {\n\tcalc = calculator;\n    }    \n    public void term1() {\n\tcalc.deriv1();\n    }\n    public void evaluate() {\n\tSystem.out.println(\"Evaluating Taylor series using\");\n\tterm1();\n    }\n}\n   \nclass HTaylor {\n    IHDeriv calc;\n    HTaylor(IHDeriv calculator) {\n\tcalc = calculator;\n    }\n    public void term1() {\n\tcalc.deriv1();\n    }\n    public void term2() {\n\tcalc.deriv2();\n    }\n    public void evaluate() {\n\tSystem.out.println(\"Evaluating Taylor series using\");\n\tterm1();\n\tterm2();\n    }\n}\n\nclass ClientApp {\n\n    public static void main(String[] args) {\n\t\n\tTaylor eval = new Taylor( new DerivG() );\n\teval.evaluate();\n\n\tSystem.out.println(\"\");\n\t\n\tHTaylor heval = new HTaylor( new HDerivG() );\n\theval.evaluate();\n    }\n}\n"
  },
  {
    "path": "proposals/run-time_polymorphism/Examples/AppendixB/taylor.rs",
    "content": "// Rust implementation of the Taylor series example program based on\n// subtyping given in Appendix B of the proposal \"Improved run-time\n// polymorphism for Fortran\".\n//\n\npub mod interfaces {\n\n    pub trait IDeriv {\n        fn deriv1(&self);\n    }\n\n    pub trait IHDeriv {\n        fn deriv1(&self);\n        fn deriv2(&self);\n    }\n}\n\npub mod derivs {\n    \n    use interfaces::IDeriv;\n    use interfaces::IHDeriv;\n    \n    pub struct DerivF {\n    }    \n    impl IDeriv for DerivF {\n        fn deriv1(&self) {\n      \t    println!(\" 1st derivative of function F!\");\n        }\n    }    \n\n    pub struct HDerivF {\n    }    \n    impl IHDeriv for HDerivF {\n        fn deriv1(&self) {\n      \t    println!(\" 1st derivative of function F!\");\n        }\n        fn deriv2(&self) {\n\t    println!(\" 2nd derivative of function F!\");\n        }\n    }\n    \n    pub struct DerivG {\n    }    \n    impl IDeriv for DerivG {\n        fn deriv1(&self) {\n      \t    println!(\" 1st derivative of function G!\");\n        }\n    }\n\n    pub struct HDerivG {\n    }    \n    impl IHDeriv for HDerivG {\n        fn deriv1(&self) {\n      \t    println!(\" 1st derivative of function G!\");\n        }\n        fn deriv2(&self) {\n\t    println!(\" 2nd derivative of function G!\");\n        }\n    }\n}\n\npub mod series {\n\n    use interfaces::IDeriv;\n    use interfaces::IHDeriv;\n    \n    pub struct Taylor {\n        pub calc: Box<dyn IDeriv>\n    }\n    impl Taylor {\n        pub fn term1(&self) {\n\t    self.calc.deriv1();\n        }\n        pub fn evaluate(&self) {\n\t    println!(\"Evaluating Taylor series using\");\n\t    self.term1();\n        }\n    }\n    \n    pub struct HTaylor {\n        pub calc: Box<dyn IHDeriv>\n    }           \n    impl HTaylor {\n        pub fn term1(&self) {\n\t    self.calc.deriv1();\n        }\n        pub fn term2(&self) {\n\t    self.calc.deriv2();\n        }\n        pub fn evaluate(&self) {\n\t    println!(\"Evaluating Taylor series using\");\n\t    self.term1();\n\t    self.term2();\n        }\n    }\n}\n\nfn main() {\n\n    use derivs::DerivG;\n    use derivs::HDerivG;\n\n    use series::Taylor;\n    use series::HTaylor;    \n\n    let derivg = Box::new( DerivG{} );\n    let eval   = Box::new( Taylor{calc: derivg} );\n    eval.evaluate();\n    \n    println!(\"\");\n\n    let hderivg = Box::new( HDerivG{} );\n    let heval   = Box::new( HTaylor{calc: hderivg} );\n    heval.evaluate();\n    \n}\n"
  },
  {
    "path": "proposals/run-time_polymorphism/Examples/Text/taylor_basic.f90",
    "content": "module derivs\n   type :: DerivF\n   contains\n      procedure, nopass :: deriv1 => deriv1f\n   end type DerivF\ncontains\n   subroutine deriv1f()\n      write(*,*) ' 1st derivative of function F!'\n   end subroutine deriv1f\nend module derivs\n\nmodule series\n   use derivs, only: DerivF\n   type :: Taylor\n      type(DerivF), allocatable :: calc\n   contains\n      procedure :: term1\n      procedure :: evaluate\n   end type Taylor\ncontains\n   subroutine term1(self)\n      class(Taylor), intent(in) :: self\n      call self%calc%deriv1()\n   end subroutine term1\n\n   subroutine evaluate(self)\n      class(Taylor), intent(in) :: self\n      write(*,*) 'Evaluating Taylor series using'\n      call self%term1()\n   end subroutine evaluate\nend module series\n\nprogram client\n   use derivs, only: DerivF\n   use series, only: Taylor\n   type(Taylor), allocatable :: teval\n   teval = Taylor( DerivF() )   \n   call teval%evaluate()   \nend program client\n"
  },
  {
    "path": "proposals/run-time_polymorphism/Fortran_OOP.bib",
    "content": "@INPROCEEDINGS{Snyder86,\n    author = {Alan Snyder},\n    title = {Encapsulation and Inheritance in Object-Oriented\n             Programming Languages},\n    booktitle = {OOPSLA'86 Proceedings},\n    year = {1986},\n    month = \"September\",\n    pages = {38--45},\n    publisher = \"ACM\"\n}\n\n@book{Bates_et_al_09,\n    author    = \"Bates, Bert and Sierra, Kathy and Freeman, Eric and\n                 Robson, Elisabeth\",\n    title     = \"Head First Design Patterns\",\n    year      = \"2009\",\n    publisher = \"O'Reilly Media\",\n    address   = \"\"\n}\n\n@book{Gamma_et_al_94,\n    author    = \"Gamma, Erich and Helm, Richard and Johnson, Ralph and\n                 Vlissides, John\",\n    title     = \"Design Patterns. \n                 Elements of Reusable Object-Oriented Software\",\n    year      = \"1994\",\n    publisher = \"Prentice Hall\",\n    address   = \"\"\n}\n\n@book{Martin_03,\n    author    = \"Martin, Robert C.\",\n    title     = \"Agile Software Development: \n                 Principles, Patterns, and Practices\",\n    year      = \"2002\",\n    publisher = \"Pearson\",\n    address   = \"\"\n}\n\n@misc{Weck_Szyperski,\n    author    = \"Weck, Wolfgang and Szyperski, Clemens\",\n    title     = \"{Do We Need Inheritance?}\",\n    howpublished  = {\\url{https://www.researchgate.net/publication/2297653_Do_We_Need_Inheritance}},\n    note = {Accessed February 4, 2020},\n}\n\n\n\n"
  },
  {
    "path": "proposals/run-time_polymorphism/Fortran_OOP.tex",
    "content": "\\documentclass[11pt,oneside]{article}\n\\usepackage[a4paper, total={6.5in, 9in}]{geometry}\n\\usepackage{natbib}\n\\usepackage{url}\n\\usepackage{listings}\n\\usepackage{xcolor}\n\\usepackage[title]{appendix}\n\n\\frenchspacing\n\n\\definecolor{codegreen}{rgb}{0,0.6,0}\n\\definecolor{codegray}{rgb}{0.5,0.5,0.5}\n\\definecolor{codepurple}{rgb}{0.58,0,0.82}\n\\definecolor{backcolour}{rgb}{0.95,0.95,0.92}\n \n\\lstdefinestyle{mystyle}{\n%   backgroundcolor=\\color{backcolour},   \n    commentstyle=\\color{codegreen},\n%   keywordstyle=\\color{magenta},\n    numberstyle=\\tiny\\color{codegray},\n    stringstyle=\\color{codepurple},\n    basicstyle=\\ttfamily\\footnotesize,\n    breakatwhitespace=false,         \n    breaklines=true,                 \n    captionpos=b,                    \n    keepspaces=true,                 \n%   numbers=left,                    \n    numbers=none,                    \n    numbersep=5pt,                  \n    showspaces=false,                \n    showstringspaces=false,\n    showtabs=false,                  \n    tabsize=2\n}\n \n\\lstset{style=mystyle}\n\n\\begin{document}\n\n\\title{Improved run-time polymorphism for Fortran \\\\ [1em]\n  \\large{Proposal to J3 for inclusion into Fortran 202y}\n}\n\\author{K. Kifonidis}\n\n\\maketitle\n\n\\abstract{A case is made for extending Fortran's support for\n  object-oriented (OO) programming (i.e. run-time polymorphism) in\n  order to enable and encourage the use of best practices for the\n  design and implementation of flexible OO software, and to improve\n  the safety and efficiency of the language. It is proposed to\n  introduce multiple inheritance of specification, in order to\n  supplement the single inheritance of implementation that is already\n  contained in the language. The new feature extends Fortran's\n  abstract interfaces and derived types by functionality akin to what\n  is present in Java, and some other, recent, languages. It is\n  essential for writing code that conforms to the dependency inversion\n  principle of OO programming. This will encourage the development of\n  software that forgoes dependency upon concretions in favor of\n  dependency on abstractions. The decoupling of classes that can be\n  achieved in this way will lead to significantly more flexible and\n  extensible numerical codes, that are also more efficient. The new\n  feature enables a programming style that dispenses with the use of\n  implementation inheritance, and therefore helps to eliminate type\n  conflicts whose resolution requires ``select type'' (down-casting)\n  statements. These, and their associated run-time overhead, have been\n  a frequent gripe of Fortran OO programmers since the introduction of\n  Fortran 2003. As a bonus, the feature should be relatively easy to\n  implement in Fortran compilers that adhere to at least the Fortran\n  2003 standard.}\n\n\\section{Introduction}\n\nOver the last decades, a significant body of experience has\naccumulated concerning the practical use of object-oriented\nprogramming (OOP). This experience has markedly shaped the design of\nsome very recent programming languages, like Rust and Go, and it has\nalso led to some notable revision of our notions of what actually\nconstitutes OOP. In this modern view, the very essence of OOP, and in\nfact its ultimate upshot, is the use of (run-time) polymorphism to\nmanage (i.e. minimize) code dependencies\n\\cite{Martin_03,Bates_et_al_09}. Viewed in this way, OOP is simply a\nmeans to organize code so that it achieves a maximum amount of\n\\emph{decoupling}.\n\nThe crucial idea in this context is that polymorphism has the unique\nability to allow one to invert the flow of dependency in a computer\ncode, which normally points from higher level modules to lower level\nmodules (read ``classes'' in the OOP context). Polymorphism makes it\npossible to replace (``invert'') the dependency of a higher level\nclass upon a lower level class by a dependency of both these classes\nupon a pure abstraction, which is called an interface (or a contract,\nprotocol, or trait). Thereby, high-level policy gets decoupled from\nlow-level implementation detail. This is known as the dependency\ninversion principle \\cite{Martin_03}. If strictly followed, this\nprinciple leads to the development of loosely coupled, easily\nextensible, easily testable, modular, maintainable, and thus\nfuture-proof software. It is this decoupling which allows for the\nre-usability and flexibility of well-written OO code.\n\nThe situation encountered in practice is usually a different one,\nthough. Experience has shown that OO software which is written in\nFortran 2003 (and its successors) seldom displays these desirable\ncharacteristics. It will be argued in the following that it is the\ncombination of a lack of appropriate features in the language, for\nencouraging (or even enforcing) a programming style that upholds the\ndependency inversion principle, and the consequent indiscriminate use\nof features that the language \\emph{does} provide (in particular\ninheritance of implementation), that has to be blamed for this\nsituation.\n\n\\section{Deficiencies in Fortran 2018 addressed by this proposal}\n\\label{sect:F08_deficits}\n\n\\subsection{No explicit distinction between different inheritance types}\n\nIn statically typed languages, like Fortran, run-time polymorphism is\ntightly bound to inheritance. In order to manage dependencies in the\nway it was described above, the users of these languages must employ\nsome form of inheritance mechanism. It is important to realize that it\nis \\emph{inheritance of (object) specification}, i.e. inheritance of\ninterfaces, that is required for this purpose. It is this (restricted)\nform of inheritance that is today viewed as being indispensable for\nOOP. Interface inheritance allows for the aforementioned\ninterface-based programming style, that embodies the dependency\ninversion principle.\n\nFortran, on the other hand, makes exclusive use of \\emph{inheritance\n  of implementation}, i.e. inheritance of classes. A class encompasses\nboth an interface (given by the union of its methods' signatures,\nthrough which it communicates with the external world), \\emph{and} the\nimplementation details of an OO algorithm (in the form of data\nvariables, and the implementation bodies of its methods). A class is\ntherefore not a proper abstraction (for other classes or procedures)\nto depend upon. It is not sufficiently generic. It contains\nimplementation-dependent detail, which other classes end up being\nneedlessly coupled to, if they make use of it via either inheritance\nor object composition. Only the class's interface is free from such\ndetail and should be depended upon for these purposes, to achieve a\nmaximum amount of decoupling in an application.\n\nFortran presently makes no explicit distinction between implementation\ninheritance and specification inheritance. The latter can only be\n\\emph{emulated} in Fortran by \\emph{re-purposing} class inheritance,\nand exploiting (or rather abusing) the fact that classes intermingle\nimplementation with specification. Fortran offers abstract types\n(i.e. abstract classes) for related use cases, which can contain\ndeferred (i.e. abstract) procedures, for which ``abstract interfaces''\nhave to be specified by the user. However, abstract classes (as all\nother classes) are explicitly allowed to \\emph{also} contain variables\nand concrete methods, i.e. state, as well as implementation code,\nwhich makes abstract classes dangerous to depend upon for inheriting\nspecification from.\n\nIn contrast to Java, C\\#, D, Swift, Rust, Go and some other modern\nlanguages, Fortran does not offer a means to inherit specification\ndirectly from its ``abstract interfaces'', which --- though available,\nand guaranteed to be completely free of implementation detail --- play\nonly a subordinate, instead of a cardinal role in the language. Hence\nit is not possible to enforce, at the language level, the strict\nseparation of the implementation of an OO algorithm from its\ninterface, that is required for adherence to the dependency inversion\nprinciple.\n\n\\subsection{Problems due to the lack of distinction between inheritance types}\n\\label{sect:problems}\n\nInterface inheritance has the sole purpose of enabling polymorphism,\nin order to invert dependencies and thereby make parts of an algorithm\ninterchangeable (i.e. to achieve high-level code reuse\n\\cite{Gamma_et_al_94}). This is also called \\emph{sub-typing}. In\ncontrast, class inheritance is meant to be used primarily for sharing\ncommon implementation code between parent and child classes. This is\nalso called \\emph{sub-classing}, and can be viewed as a form of\nlow-level code reuse.\n\nThere is a significant body of evidence that demonstrates that\nsub-classing is a dangerous practice, which, moreover, is not\nessential to OOP. Snyder \\cite{Snyder86} showed already in the\neighties that sub-classing breaks encapsulation. Weck and Szyperski\nre-emphasized this \\cite{Weck_Szyperski}. They proposed to abolish\nsub-classing, since they regard it as being prone to abuse. Even\nmoderately incautious use of sub-classing typically leads to rigid,\nbrittle code, that is tightly coupled to the details of concrete\n(implementation) classes, and is therefore unmaintainable and\nin-extensible. This is especially the case when sub-classing is used in\ncombination with method overriding, or changes to a base object's\nstate \\cite{Weck_Szyperski}. Moreover, when sub-classing is employed\nalong with object composition in an application (which is inevitable\nin practice), type conflicts can often result. These can then only be\nresolved by down-casting, i.e. by the use of \\texttt{select type}\nstatements in Fortran, which lead to unnecessary run-time\noverhead. This can be viewed as resulting from a violation of the\ndependency inversion principle, which states that inheritance should\nbe used \\emph{exclusively} for sub-typing.\n\nAll these issues could be avoided, if Fortran would be extended to\nallow for (multiple) inheritance of interfaces, in order to provide\nits programmers with easy and safe access to sub-typing. Sub-classing\n(i.e. type extension) could then be mostly shunned in the development\nof new codes. Clear guidelines could then be given to Fortran\nprogrammers to rely instead on object composition for low-level, and\non the features proposed in this proposal for high-level code reuse,\nin the vast majority of their code. A coding style that is in\naccordance with the dependency inversion principle would thus be\nencouraged that would eliminate type conflicts, the need for\n\\texttt{select type} statements, and their run-time overhead. A\npotential drawback of object composition is the need for some\nboilerplate code, i.e. for methods that delegate functionality to\ncomposed classes. However, efficiency can still be expected to improve\nover present Fortran OOP codes, especially in cases where\n\\texttt{select type} statements appear in low-level code, e.g. in\ncomputational kernels.\n\nThe importance of such a coding style is actually not some entirely\nnew insight. Among the very first recommendations that one finds in\nthe pioneering work of Gamma et al. \\cite{Gamma_et_al_94} on OO design\npatterns are the statements ``program to an interface not an\nimplementation'' and ``favor object composition over class\ninheritance''. What had apparently not been recognized widely is that\nthese are also recommendations for language design. This has changed\nrecently, with the availability of the Rust and Go languages. In these\nlanguages, interface inheritance is the \\emph{only} type of inheritance\nthat is supported. These languages therefore \\emph{enforce} an OOP\nstyle that is in accordance with the dependency inversion principle.\n\n\n\\section{Proposed additions to Fortran 202y}\n\\label{sect:propositions}\n\nThe new features proposed to solve the problems discussed in the last\nsection are\n\n\\begin{itemize}\n\\item\n  A possibility to declare \\emph{named} versions of Fortran's abstract\n  interfaces, from which derived types would then be able to inherit\n  specification.\n\\item\n  An \\texttt{extends} attribute-specifier for the declaration header of\n  these named abstract interfaces, to allow hierarchies of such (named)\n  abstract interfaces to be built\\footnote{Hierarchies of interfaces\n    do not pose the dangers that sub-classing poses, as only\n    \\emph{specification} is shared, see \\cite{Weck_Szyperski}.}.\n\\item\n  A new \\texttt{implements} type-attribute-specifier for derived types, to\n  enable these types to inherit specification from one or more named\n  abstract interfaces.\n\\item\n  An extension of Fortran's \\texttt{class} declaration-type-specifier\n  for polymorphic variables, to accept named abstract interfaces. This\n  would enable one to declare polymorphic variables of named abstract\n  interfaces, in order to make use of sub-typing polymorphism.\n\n\\end{itemize}\n\n\\subsection{Extended declaration syntax for abstract interfaces}\n\\label{sect:declare}\n\nThe following listing shows an example of an extended syntax for\ninterface declarations. In a module named \\texttt{interfaces}, four\nnamed abstract interfaces are declared: \\texttt{ISolver},\n\\texttt{IPrinter}, \\texttt{IClient}, and\n\\texttt{IRelaxationSolver}. \\texttt{ISolver} and \\texttt{IPrinter}\ncontain the declarations of subroutines \\texttt{solve\\_system}, and\n\\texttt{print\\_result}, respectively. Notice that \\texttt{IClient}, on\nthe other, hand contains declarations for \\emph{two} procedures:\nsubroutines \\texttt{solve\\_system}, \\emph{and} \\texttt{print\\_result},\nwhich it inherits from \\texttt{ISolver} and \\texttt{IPrinter},\nrespectively, by means of the \\texttt{extends} attribute-specifier.\n\n\\begin{lstlisting}[language=Fortran]\nmodule interfaces\n  abstract interface :: ISolver\n      subroutine solve_system(a,b,x)\n         real, dimension(:,:), intent(in)  :: a\n         real, dimension(:),   intent(in)  :: b\n         real, dimension(:),   intent(out) :: x\n      end subroutine solve_system\n   end interface ISolver\n\n   abstract interface :: IPrinter\n      subroutine print_result(x)\n         real, dimension(:), intent(in) :: x\n      end subroutine print_result\n   end interface IPrinter\n   \n   abstract interface, extends(ISolver,IPrinter) :: IClient\n   end interface IClient\n\n   abstract interface :: IRelaxationSolver\n      subroutine driver(self,d,rhs,x)\n         import :: IRelaxationSolver\n         class(IRelaxationSolver), intent(in)  :: self\n         real, dimension(:,:,:,:), intent(in)  :: d\n         real, dimension(:,:,:),   intent(in)  :: rhs\n         real, dimension(:,:,:),   intent(out) :: x\n      end subroutine driver\n      subroutine relax(blksolver,d,rhs,x)\n         import :: ISolver\n         class(ISolver),           intent(in)  :: blksolver\n         real, dimension(:,:,:,:), intent(in)  :: d\n         real, dimension(:,:,:),   intent(in)  :: rhs\n         real, dimension(:,:,:),   intent(out) :: x\n      end subroutine relax\n   end interface IRelaxationSolver\nend module interfaces\n\\end{lstlisting}\n\\label{list:interface}\nFinally, the declaration of the \\texttt{IRelaxationSolver} interface\nillustrates that a named abstract interface may depend on other named\nabstract interfaces, not only via an \\texttt{extends}\nattribute-specifier (as shown above), but also through the procedure\ndeclarations that it contains. Namely, the latter may contain\npolymorphic arguments that are declared with the help of the\n\\texttt{class} declaration-type-specifier (see\nSect.~\\ref{sect:declarations}), to give these procedures access to\neither the data fields (variables) of the type that \\emph{implements}\nthe abstract interface (i.e. to the descendant of that interface) or\nto the descendants of \\emph{other} abstract interfaces. In these\ncases, Fortran's \\texttt{import} statement would be required in order\nto bring such external names into the procedure declarations' own\nscope.\n\nOther ways to express and implement the proposed functionality are\npossible, and need to be considered. The one discussed here has the\nadvantages that abstract interfaces are already a part of the language\nand are merely extended here by functionality that does not affect\ntheir other uses. It does, however, elevate their status in the\nlanguage as it makes them central to expressing interface\ninheritance. This syntax also makes the distinction between sub-typing\nand sub-classing apparent, which is a major plus. It has the further\nadvantage that named abstract interfaces could also be used in future\nextensions of the language, e.g. in connection with \\emph{intrinsic}\ntypes, and with generics. This is the approach taken in the Swift\nprogramming language where (named) abstract interfaces (called\n``protocols'' there) are so central to its functionality, that Swift\nhas been called a ``protocol-based'' language. It is not our purpose\nhere to delve deeper into syntactic or extensibility issues. We rather\nneed some syntax that is able to express the following code examples,\nand the present one does so satisfactorily.\n\n\n\\subsection{Facility to implement interfaces}\n\nOnce a named abstract interface has been declared, it can be\nimplemented by a derived type that needs to conform to that interface,\nby using the new \\texttt{implements} type-attribute-specifier as\nfollows\n\\begin{lstlisting}[language=Fortran]\nmodule lu_decomp\n   use interfaces, only: ISolver\n   type, implements(ISolver) :: LUDecomposition\n   contains\n      procedure, nopass :: solve_system\n   end type LUDecomposition\ncontains\n   subroutine solve_system(a,b,x)\n      real, dimension(:,:), intent(in)  :: a\n      real, dimension(:),   intent(in)  :: b\n      real, dimension(:),   intent(out) :: x\n      ! Implementation of LU decomposition goes here\n   end subroutine solve_system   \nend module lu_decomp\n\\end{lstlisting}\nIn case the derived type is abstract, it is allowed to provide an only\npartial implementation of the interface(s) that it implements. Any\nnon-abstract derived type that extends the abstract type must,\nhowever, provide a full implementation.\n\n\\subsection{Polymorphism via sub-typing}\n\\label{sect:declarations}\n\nTo make actual use of the sub-typing polymorphism that we have just\nset up, polymorphic variables of named abstract interfaces would then\nbe declared with the help of the (extended) \\texttt{class}\ndeclaration-type-specifier; for instance, as arguments of a procedure,\nor within another derived type. They could then be used in the actual\nimplementation of this derived type's bound procedures, e.g. as\nfollows:\n\\begin{lstlisting}[language=Fortran]\ntype, implements(IClient) :: Client\n   class(ISolver),  allocatable :: solver\n   class(IPrinter), pointer     :: printer => null()\ncontains\n   procedure, nopass :: solve_system\n   procedure, nopass :: print_result\nend type Client\n\\end{lstlisting}\nHere, two polymorphic variables, \\texttt{solver} and \\texttt{printer},\nthat conform to the \\texttt{ISolver} and \\texttt{IPrinter} interfaces,\nrespectively, are declared for the purpose of object composition\nwithin type \\texttt{Client}, which itself implements the\n\\texttt{IClient} interface, and thus has to provide implementations\nfor the procedures \\texttt{solve\\_system} and \\texttt{print\\_result}\n(whose actual code is omitted here, and would simply employ delegation\nto \\texttt{solver} and \\texttt{printer} to provide the required\nfunctionality).\n\nNotice also, that the proposed features allow multiple interface\ninheritance. In case \\texttt{Client} has to conform to either\n\\texttt{ISolver} or \\texttt{IPrinter}, one could, for instance,\nprovide an implementation much as in the last example, but would use\nthe \\texttt{implements} specifier as follows\n\\begin{lstlisting}[language=Fortran]\ntype, implements(ISolver,IPrinter) :: Client\n   class(ISolver),  allocatable :: solver\n   class(IPrinter), pointer     :: printer => null()\ncontains\n   procedure, nopass :: solve_system\n   procedure, nopass :: print_result\nend type Client\n\\end{lstlisting}\n\nThe next example shows, in detail, how sub-typing polymorphism would\nbe used together with delegation, and also how type-bound procedures\nwith the \\texttt{pass} attribute would be handled\n\\begin{lstlisting}[language=Fortran]\nmodule jacobi\n   use interfaces, only: IRelaxationSolver, ISolver\n   type, implements(IRelaxationSolver) :: BlockJacobi\n      class(ISolver), allocatable :: blksolver\n   contains\n      procedure, pass   :: driver\n      procedure, nopass :: relax\n   end type BlockJacobi\ncontains\n   subroutine driver(self,d,rhs,x)\n      class(BlockJacobi),       intent(in)  :: self\n      real, dimension(:,:,:,:), intent(in)  :: d\n      real, dimension(:,:,:),   intent(in)  :: rhs\n      real, dimension(:,:,:),   intent(out) :: x\n      call self%relax(self%blksolver,d,rhs,x)\n   end subroutine driver\n   subroutine relax(blksolver,d,rhs,x)\n      class(ISolver),           intent(in)  :: blksolver\n      real, dimension(:,:,:,:), intent(in)  :: d\n      real, dimension(:,:,:),   intent(in)  :: rhs\n      real, dimension(:,:,:),   intent(out) :: x\n      integer :: i, j\n      do j = 1, size(x,3)\n         do i = 1, size(x,2)\n            call blksolver%solve_system(d(:,:,i,j),rhs(:,i,j),x(:,i,j))\n         end do\n      end do\n   end subroutine relax\nend module jacobi\n\\end{lstlisting}\nNotice that \\texttt{BlockJacobi} is an implementor (i.e. descendant)\nof \\texttt{IRelaxationSolver} and that therefore the above signature\nof method \\texttt{driver} is in accordance with its declaration in\nmodule \\texttt{interfaces}. To use \\texttt{BlockJacobi}, one would\nhave to simply inject into it, via a constructor, an instance of\n\\texttt{LUDecomposition} (or any other object that implements the\n\\texttt{ISolver} interface) in order to intialize the allocatable,\npolymorphic variable \\texttt{blksolver}.\n\n\\subsection{Combination of sub-classing with sub-typing}\n\nThe new features need to be inter-operable also with type extension\n(i.e. sub-classing). They need to enable one to declare derived types\nthat conform to some interfaces, and inherit at the same time\nimplementation from some other derived type, e.g. the procedure\n\\texttt{solve\\_system} implemented by type \\texttt{LUDecomposition} in\nthe following example:\n\\begin{lstlisting}[language=Fortran]\ntype, extends(LUDecomposition), implements(ISolver,IPrinter) :: Client\n   class(IPrinter), pointer :: printer => null()\ncontains\n   procedure, nopass :: print_result\nend type Client\n\\end{lstlisting}\nIn the Java language, from which this idea is borrowed, the convention\nis that \\texttt{extends} shall precede \\texttt{implements}. The\ncombination of sub-typing and sub-classing will allow advanced users\nof the language, who have a good understanding of OO design, to employ\nsome advanced techniques that make use of both the flexibility that\nsub-typing affords one, with the raw reduction of code lines that\nsub-classing permits.\n\n\n\\section{Example of a use case: a Taylor series application}\n\nTo illustrate the difficulties that were discussed in\nSect.~\\ref{sect:problems}, and to demonstrate how the use of the new\nfeatures will contribute to the solution of these problems, we will\npresent here a small case study that exhibits a pattern that is\nencountered often in practical applications, namely the coupling of\ntwo separate inheritance hierarchies through object composition. It is\ntruly only the pattern that is of importance here, but in order to\nprovide a concrete example, we will present it in the framework of a\nsomewhat fictional application that calculates the Taylor series\nexpansion of some function up to certain orders of accuracy.\n\n\\subsection{The basic design}\n\\label{sect:basic_design}\n\nSuppose that we have an application that needs to calculate the Taylor\nseries of a function $F(x)$ for some concrete $x$ --- and it needs to\ndo so only up to the linear term, i.e. it only needs access to the\nfirst derive, $F'(x)$, of $F$ with respect to $x$. Ignoring all the\ndetails of how this first derivative might be calculated, a code\nskeleton for using it within our application might look as\nfollows. Declare a derived type \\texttt{DerivF} that contains a\nprocedure \\texttt{deriv1} that calculates $F'(x)$, and a separate\ntype, named \\texttt{Taylor}, that makes use of type \\texttt{DerivF}\nvia object composition in order to \\texttt{evaluate} the actual Taylor\nseries approximation itself (whose details, like calculation of the\nzeroth order term, etc., are immaterial here):\n\\begin{lstlisting}[language=Fortran]\nmodule derivs\n   type :: DerivF\n   contains\n      procedure, nopass :: deriv1 => deriv1f\n   end type DerivF\ncontains\n   subroutine deriv1f()\n      write(*,*) ' 1st derivative of function F!'\n   end subroutine deriv1f\nend module derivs\n\nmodule series\n   use derivs, only: DerivF\n   type :: Taylor\n      type(DerivF), allocatable :: calc\n   contains\n      procedure :: term1\n      procedure :: evaluate\n   end type Taylor\ncontains\n   subroutine term1(self)\n      class(Taylor), intent(in) :: self\n      call self%calc%deriv1()\n   end subroutine term1\n\n   subroutine evaluate(self)\n      class(Taylor), intent(in) :: self\n      write(*,*) 'Evaluating Taylor series using'\n      call self%term1()\n   end subroutine evaluate   \nend module series\n\\end{lstlisting}\nOur client application would then set up an object \\texttt{teval} of\ntype \\texttt{Taylor} in order to evaluate the Taylor series\napproximation it needs, e.g. as follows\n\n\\newpage\n\n\\begin{lstlisting}[language=Fortran]\nprogram client\n   use derivs, only: DerivF\n   use series, only: Taylor\n   type(Taylor), allocatable :: teval\n   teval = Taylor( DerivF() )   \n   call teval%evaluate()   \nend program client\n\\end{lstlisting}\n\nSuppose now, that our requirements on the application have changed.\nWe need some additional functionality. We want the application to be\nable to also calculate, if required, a higher-order accurate\napproximation to the Taylor series of $F$, say up to the quadratic\nterm. In addition, we also want it to be able to use some other\nfunction, say $G$, instead of $F$. Moreover, we do not want to change\nany of the present code structure, if possible. We only wish to extend\nit by the new functionality.\n\n\n\\subsection{Extension by sub-classing}\n\\label{sect:sub-classing-example}\n\nWe will concentrate on implementing the functionality related to the\nhigher-order-accuracy capability first. To accomplish this, we will\nuse Fortran's \\texttt{extends} feature for derived types\n(i.e. sub-classing). We extend type \\texttt{DerivF} by a child type,\n\\texttt{HDerivF}, that contains a procedure \\texttt{deriv2} to\ncalculate also the higher (i.e. second) order derivative of $F$.\n\\begin{lstlisting}[language=Fortran]\ntype :: DerivF\ncontains\n   procedure, nopass :: deriv1 => deriv1f\nend type DerivF\n\ntype, extends(DerivF) :: HDerivF\ncontains\n   procedure, nopass :: deriv2 => deriv2f\nend type HDerivF\n\\end{lstlisting}\nWe also extend the type \\texttt{Taylor} by a child type,\n\\texttt{HTaylor}, to deal with the evaluation of the higher order\nTaylor series:\n\\begin{lstlisting}[language=Fortran]\ntype :: Taylor\n   type(DerivF), allocatable :: calc\ncontains\n   procedure :: term1\n   procedure :: evaluate\nend type Taylor\n\ntype, extends(Taylor) :: HTaylor\ncontains\n   procedure :: term2    => hterm2\n   procedure :: evaluate => hevaluate\nend type HTaylor\n\\end{lstlisting}\nHere, we inherited method \\texttt{term1} from the parent type, and\nadded method \\texttt{term2} to enable us to calculate also the\nsecond-order Taylor term. We also had to override the\n\\texttt{evaluate} method of the parent type, since the higher-order\nevaluation of the complete series needs to account for this\nadditional, i.e. second-order, term. We have thus implemented the\nskeleton of the high-order functionality, using types that make up two\nseparate inheritance hierarchies. However, we are still bound to\nexclusive use of the function $F$. To implement the capability to use\ndifferent functions, we are going to employ the strategy pattern\n\\cite{Gamma_et_al_94}. We introduce a further inheritance hierarchy\nmade up of two new types, \\texttt{DerivG}, and \\texttt{HDerivG}, to\nprovide the same functionality for function $G$, as it was done above\nfor function $F$. We also need to make these hierarchies, connected to\n$F$ and $G$, interchangeable, so that we can use either of them within\nthe code that evaluates the Taylor series. For this purpose, we\nintroduce the following abstract type\n\\begin{lstlisting}[language=Fortran]\ntype, abstract :: Deriv\ncontains\n   procedure(pderiv), deferred, nopass ::  deriv1\nend type Deriv\n\nabstract interface\n   subroutine pderiv()\n   end subroutine pderiv      \nend interface\n\\end{lstlisting}\nNow we can make both the inheritance hierarchies connected to $F$ and $G$\nderive from this abstract type, and hence merge them into a single\nhierarchy. Its $G$-related branch, for instance, looks as follows\n\\begin{lstlisting}[language=Fortran]\ntype, extends(Deriv) :: DerivG\ncontains\n   procedure, nopass :: deriv1 => deriv1g\nend type DerivG\n\ntype, extends(DerivG) :: HDerivG\ncontains\n   procedure, nopass :: deriv2 => deriv2g\nend type HDerivG\n\\end{lstlisting}\nwhereas the $F$-related branch looks completely analogous. The last\nstep, in implementing the strategy pattern, is to transform the variable\n\\texttt{calc} in type \\texttt{Taylor} into a polymorphic variable of\n\\texttt{class(Deriv)}\n\\begin{lstlisting}[language=Fortran]\ntype :: Taylor\n   class(Deriv), allocatable :: calc\ncontains\n\\end{lstlisting}\nin order to accept \\texttt{Deriv} types from either branch of our\nmerged hierarchy. The complete code, that we end up with, is given\nin Appendix~\\ref{sect:example1}. This code\\footnote{compiled\n  with gfortran Version 9} produces the following output\n\\begin{lstlisting}[language=Fortran]\n Evaluating Taylor series using\n  1st derivative of function G!\n\n Evaluating Taylor series using\n  1st derivative of function G!\n  2nd derivative of function G!\n\\end{lstlisting}\nThat is, the code calculates first the low-order approximation of $G$,\nand subsequently its high-order approximation, as intended. It works\ncorrectly. Yet, it is extremely bad, rigid code! The most conspicuous\nsymptom of its rigidity is the appearance of the \\texttt{select type}\nstatement in the subroutine \\texttt{hterm2}, that we reproduce here for\nillustration:\n\\begin{lstlisting}[language=Fortran]\nsubroutine hterm2(self)\n   class(HTaylor), intent(in) :: self\n   select type ( calc => self%calc )\n   class is ( HDerivF )\n      call calc%deriv2()\n   class is ( HDerivG )\n      call calc%deriv2()\n   class default\n      write(*,*) 'Unknown type!'\n   end select\nend subroutine hterm2\n\\end{lstlisting}\nObviously, this routine expects the \\texttt{calc} instance to be of\neither type \\texttt{HDerivF} or \\texttt{HDerivG}, whereas this has\nbeen inherited from the parent type \\texttt{Taylor} being of type\n\\texttt{class(Deriv)},\n\\begin{lstlisting}[language=Fortran]\ntype :: Taylor\n   class(Deriv), allocatable :: calc\ncontains\n\\end{lstlisting}\nOur abstract type \\texttt{Deriv} does not contain a declaration for\nthe method \\texttt{deriv2} that the subroutine needs. Since the\ncompiler can't know at compile time whether at run-time \\texttt{calc}\nwill be of the right type-extension to contain the \\texttt{deriv2}\nmethod, it will refuse to compile subroutine \\texttt{hterm2} if the\n\\texttt{select type} statement is omitted. By coupling two inheritance\nhierarchies (based on \\texttt{Deriv} and \\texttt{Taylor}) together, via\nobject composition, we have created a (potential) type conflict that\nnow requires a type check every time we run through the subroutine. If\nwe had written a real production application along these lines, that\nwould evaluate the Taylor series for a single scalar $x$ per call, the\ntype-checking would have completely killed performance!\n\nType extension (i.e. sub-classing) has locked us into a\nstraight-jacket of rigid inheritance hierarchies that denies us the\nflexibility to provide our procedures with the right data types, and\nhas thereby forced us to circumvent the static type system of the\nlanguage, in order to get the code to work at all. But this is not the\nonly problem. The entire code relies on concrete derived types,\ni.e. on concrete implementations. Except for type \\texttt{Deriv}, it\ndoes not use any abstractions. Should the implementation of some\nconcrete type need to be changed, all types that depend on it would\nneed to be checked and possibly changed, too, in order not to break\nthe program.\n\n\\subsection{Extension by sub-typing and object composition}\n\nNow, let us go back to the point we were at at the end of\nSect.~\\ref{sect:basic_design}. Let us, furthermore, suppose that Fortran\ndoesn't support sub-classing, and instead supports only object\ncomposition and sub-typing (via the features proposed in\nSect.~\\ref{sect:propositions}), akin to Rust or Go. We will again\nfocus first on the extension of our application to higher order of\naccuracy. We still contemplate to introduce this functionality through\nfour derived types \\texttt{DerivF}, \\texttt{HDerivF}, \\texttt{Taylor},\nand \\texttt{HTaylor}. But since we no longer have sub-classing at\nour disposal, the only way to make these types cooperate, on solving\nthe task, is the following\n\\begin{lstlisting}[language=Fortran]\ntype :: Taylor\n   type(DerivF), allocatable :: calc\ncontains\n   procedure :: term1\n   procedure :: evaluate\nend type Taylor\n   \ntype :: HTaylor\n   type(HDerivF), allocatable :: calc\ncontains\n   procedure :: term1    => hterm1\n   procedure :: term2    => hterm2\n   procedure :: evaluate => hevaluate\nend type HTaylor\n\\end{lstlisting}\nthat is, we need to employ object composition \\emph{twice}, once in\n\\texttt{Taylor} and once in \\texttt{HTaylor}. This is already\nsufficient to avoid the appearance of a \\texttt{select type} statement\nin subroutine \\texttt{hterm2}, because now our instance of\n\\texttt{calc} will be of type \\texttt{HDerivF}, i.e. of the proper\ntype for doing high-order calculations. We will, of course, see to\nit that it contains the procedure \\texttt{deriv2} which calculates the\nsecond order derivative required by the high-order Taylor series term.\n\nThe above code fragment still has a problem, though. It relies on the\nconcrete types \\texttt{DerivF} and \\texttt{HDerivF}. Our copy of\n``Fortran 202y Explained'' tells us that we should rely on\nabstractions instead of concretions, and depend on polymorphic\nvariables of abstract interfaces within our derived types, instead. We\ntherefore think about the functionality that these two concrete types\nneed to provide to their clients. We already mentioned that\n\\texttt{HDerivF} will have to provide an implementation of subroutine\n\\texttt{deriv2}. However, and as it was the case in\nSect.~\\ref{sect:sub-classing-example}, \\texttt{HDerivF} also needs to\nimplement procedure \\texttt{deriv1}, while \\texttt{DerivF} needs to\nimplement \\emph{only} the latter procedure. Hence, we distill the\nsignatures of these methods into two abstract interfaces\n\\begin{lstlisting}[language=Fortran]\nabstract interface :: IDeriv\n   subroutine deriv1()\n   end subroutine deriv1\nend interface IDeriv\n\nabstract interface, extends(IDeriv) :: IHDeriv\n   subroutine deriv2()\n   end subroutine deriv2\nend interface IHDeriv\n\\end{lstlisting}\nand then make use of these interfaces to modify our code for the\nTaylor types as follows\n\\begin{lstlisting}[language=Fortran]\ntype :: Taylor\n   class(IDeriv), allocatable :: calc\ncontains\n   procedure :: term1\n   procedure :: evaluate\nend type Taylor\n   \ntype :: HTaylor\n   class(IHDeriv), allocatable :: calc\ncontains\n   procedure :: term1    => hterm1\n   procedure :: term2    => hterm2\n   procedure :: evaluate => hevaluate\nend type HTaylor\n\\end{lstlisting}\nWith this single stroke, we have just solved our entire problem,\nincluding the requirement of being able to calculate the Taylor series\nof different functions! Moreover, we have accomplished this goal with\nease. The only things that remain to be done are to make\n\\texttt{DerivF} and \\texttt{HDerivF} simply implement the two abstract\ninterfaces, e.g. as follows\n\\begin{lstlisting}[language=Fortran,\n    caption={Implementation of interfaces for derivatives of function $F$.},\n    label={listing:implderivf}]\ntype, implements(IDeriv) :: DerivF\ncontains\n   procedure, nopass :: deriv1 => deriv1f\nend type DerivF\n\ntype, implements(IHDeriv) :: HDerivF\ncontains\n   procedure, nopass :: deriv1 => deriv1f\n   procedure, nopass :: deriv2 => deriv2f\nend type HDerivF\n\\end{lstlisting}\nand to add two more types, \\texttt{DerivG}, and \\texttt{HDerivG}, in\nexactly the same fashion, in order to provide implementations of the\nsame functionality for function $G$.\n\nWe are finished! Since both \\texttt{DerivF} and \\texttt{DerivG} now\nconform to the abstract \\texttt{IDeriv} interface, we can easily swap\ninstances of either of them into type \\texttt{Taylor} at will, in\norder to calculate the Taylor series of either $F$ or $G$. Similar\nfunctionality is exhibited by the types that implement the high-order\nseries. We didn't even have to spend a single thought on using the\nstrategy pattern for these purposes. We used it naturally without\nthinking about it because it was encouraged by the features contained\nin the language.\n\nThe complete code, that uses this sub-typing approach, is given in\nAppendix~\\ref{sect:example2}. It is an almost literal translation of a\nJava as well as a Rust code, that were used to test and verify the\npresented ideas. The code in Appendix~\\ref{sect:example2} is vastly\nsuperior compared to the one that uses sub-classing and is given in\nAppendix~\\ref{sect:example1}. Both codes have roughly the same number\nof lines, but in the one relying on sub-typing there are \\emph{no}\n\\texttt{select type} statements, \\emph{no} sub-classing hierarchies,\nand \\emph{no} dependencies on concrete types. We have inverted all the\ndependencies in the algorithm, i.e. the only dependencies are on\nabstract interfaces. We have thus attained the highest possible degree\nof decoupling. The \\emph{only} part of the code that depends on\nconcrete types is the main client program, whose sole purpose is to\norganize the entire process of injecting instances of the correct\nconcrete types via (Fortran default) constructors into the lower level\ncode.\n\nThis decoupling of types leads to multiple benefits. For instance (and\nprovided we have compiled the \\texttt{interfaces} module), we gain the\nfreedom to compile the \\texttt{derivs} and \\texttt{series} modules in\nany order we like, even in parallel if we wish to. We thereby\nneutralized the biggest drawback of a module system (like Fortran's)\nfor separate compilation, namely serialization of the compilation\nprocess. We also avoid re-compilation cascades in case we need to\nchange the implementation of some concrete type, as long as we leave\nits (abstract) interface intact. We are, moreover, free to take any of\nthe aforementioned modules and reuse it in another application,\nwithout having to drag along numerous dependencies. In summary, using\nthe new features we have not only accomplished to make the code more\nefficient, but also much more flexible, much more maintainable, and\nmuch more reusable.\n\n\\subsection{Combination of the two inheritance types}\n\nThe code given in Appendix~\\ref{sect:example2} strictly conforms to\nthe dependency inversion principle. By relaxing this requirement, and\nallowing for the use of both sub-typing and sub-classing, we could\nhave written the code fragment in Listing~\\ref{listing:implderivf}\nabove somewhat more concise as\n\\begin{lstlisting}[language=Fortran]\ntype, implements(IDeriv) :: DerivF\ncontains\n   procedure, nopass :: deriv1 => deriv1f\nend type DerivF\n\ntype, extends(DerivF), implements(IHDeriv) :: HDerivF\ncontains\n   procedure, nopass :: deriv2 => deriv2f\nend type HDerivF\n\\end{lstlisting}\nThis saves us the labor of providing an implementation for procedure\n\\texttt{deriv1} within type \\texttt{HDerivF}, at the significant cost\nof \\texttt{HDerivF} depending now on a concretion, i.e. on type\n\\texttt{DerivF}. In this particular, trivial, example, we have only\nsaved a single line of code in this way. But had \\texttt{DerivF}\ncontained half a dozen or so methods, which we would have been forced\nto implement also in \\texttt{HDerivF}, the convenience that the\ncombination of \\texttt{extends} and \\texttt{implements} would have\nafforded us for reducing the number of code-lines could hardly have\nbeen passed up.\n\n\\subsection{Summary}\n\nThe features proposed in this document would significantly enhance\nFortran's OOP capabilities without affecting backwards compatibility.\nMoreover, Fortran compilers that adhere to at least the Fortran 2003\nstandard could implement them relatively easily, as most of the\nfunctionality required to support them is already present in some form\nin such compilers for the support of sub-classing, i.e. the extension\nof derived types.\n\n\\bibliographystyle{plain}\n\\bibliography{Fortran_OOP}\n\n\n\\lstdefinestyle{mystyle}{\n%   backgroundcolor=\\color{backcolour},   \n    commentstyle=\\color{codegreen},\n%   keywordstyle=\\color{magenta},\n    numberstyle=\\tiny\\color{codegray},\n    stringstyle=\\color{codepurple},\n    basicstyle=\\ttfamily\\footnotesize,\n    breakatwhitespace=false,         \n    breaklines=true,                 \n    captionpos=b,                    \n    keepspaces=true,                 \n    numbers=left,                    \n    numbersep=5pt,                  \n    showspaces=false,                \n    showstringspaces=false,\n    showtabs=false,                  \n    tabsize=2\n}\n\n\\lstset{style=mystyle}\n\n\n\\begin{appendices}\n\n\\section{Taylor series example based on sub-classing}\n\\label{sect:example1}\n\n\\begin{lstlisting}[language=Fortran]\nmodule derivs\n\n   type, abstract :: Deriv\n   contains\n      procedure(pderiv), deferred, nopass ::  deriv1\n   end type Deriv\n\n   abstract interface\n      subroutine pderiv()\n      end subroutine pderiv      \n   end interface\n   \n   type, extends(Deriv) :: DerivF\n   contains\n      procedure, nopass :: deriv1 => deriv1f\n   end type DerivF\n\n   type, extends(DerivF) :: HDerivF\n   contains\n      procedure, nopass :: deriv2 => deriv2f\n   end type HDerivF\n\n   type, extends(Deriv) :: DerivG\n   contains\n      procedure, nopass :: deriv1 => deriv1g\n   end type DerivG\n\n   type, extends(DerivG) :: HDerivG\n   contains\n      procedure, nopass :: deriv2 => deriv2g\n   end type HDerivG\n   \ncontains\n\n   subroutine deriv1f()\n      write(*,*) ' 1st derivative of function F!'\n   end subroutine deriv1f\n\n   subroutine deriv2f()\n      write(*,*) ' 2nd derivative of function F!'\n   end subroutine deriv2f\n\n   subroutine deriv1g()\n      write(*,*) ' 1st derivative of function G!'\n   end subroutine deriv1g\n\n   subroutine deriv2g()\n      write(*,*) ' 2nd derivative of function G!'\n   end subroutine deriv2g\n\nend module derivs\n\nmodule series\n\n   use derivs, only: Deriv, HDerivF, HDerivG\n\n   type :: Taylor\n      class(Deriv), allocatable :: calc\n   contains\n      procedure :: term1\n      procedure :: evaluate\n   end type Taylor\n\n   type, extends(Taylor) :: HTaylor\n   contains\n      procedure :: term2    => hterm2\n      procedure :: evaluate => hevaluate\n   end type HTaylor\n\ncontains\n\n   subroutine term1(self)\n      class(Taylor), intent(in) :: self\n      call self%calc%deriv1()\n   end subroutine term1\n\n   subroutine evaluate(self)\n      class(Taylor), intent(in) :: self\n      write(*,*) 'Evaluating Taylor series using'\n      call self%term1()\n   end subroutine evaluate\n      \n   subroutine hterm2(self)\n      class(HTaylor), intent(in) :: self\n      select type ( calc => self%calc )\n      class is ( HDerivF )\n         call calc%deriv2()\n      class is ( HDerivG )\n         call calc%deriv2()\n      class default\n         write(*,*) 'Unknown type!'\n      end select\n   end subroutine hterm2\n\n   subroutine hevaluate(self)\n      class(HTaylor), intent(in) :: self\n      write(*,*) 'Evaluating Taylor series using'\n      call self%term1()\n      call self%term2()\n   end subroutine hevaluate\n\nend module series\n\nprogram client\n\n   use derivs, only: DerivG, HDerivG, Deriv\n   use series, only: Taylor, HTaylor\n\n   class(Deriv),  allocatable :: derv\n   class(Taylor), allocatable :: teval\n   \n   derv  = DerivG()\n   teval = Taylor(derv)   \n   call teval%evaluate()   \n\n   write(*,*)\n   \n   derv  = HDerivG()\n   teval = HTaylor(derv)\n   call teval%evaluate()   \n\nend program client\n\\end{lstlisting}\n\n\n\\section{Taylor series example based on sub-typing}\n\\label{sect:example2}\n\n\\begin{lstlisting}[language=Fortran]\nmodule interfaces\n\n   abstract interface :: IDeriv\n      subroutine deriv1()\n      end subroutine deriv1\n   end interface IDeriv\n\n   abstract interface, extends(IDeriv) :: IHDeriv\n      subroutine deriv2()\n      end subroutine deriv2\n   end interface IHDeriv\n\nend module interfaces\n   \nmodule derivs\n\n   use interfaces, only: IDeriv, IHDeriv\n   \n   type, implements(IDeriv) :: DerivF\n   contains\n      procedure, nopass :: deriv1 => deriv1f\n   end type DerivF\n\n   type, implements(IHDeriv) :: HDerivF\n   contains\n      procedure, nopass :: deriv1 => deriv1f\n      procedure, nopass :: deriv2 => deriv2f\n   end type HDerivF\n   \n   type, implements(IDeriv) :: DerivG\n   contains\n      procedure, nopass :: deriv1 => deriv1g\n   end type DerivG\n\n   type, implements(IHDeriv) :: HDerivG\n   contains\n      procedure, nopass :: deriv1 => deriv1g\n      procedure, nopass :: deriv2 => deriv2g\n   end type HDerivG\n   \ncontains\n\n   subroutine deriv1f()\n      write(*,*) \" 1st derivative of function F!\"\n   end subroutine deriv1f\n\n   subroutine deriv2f()\n      write(*,*) \" 2nd derivative of function F!\"\n   end subroutine deriv2f\n   \n   subroutine deriv1g()\n      write(*,*) \" 1st derivative of function G!\"\n   end subroutine deriv1g\n   \n   subroutine deriv2g()\n      write(*,*) \" 2nd derivative of function G!\"\n   end subroutine deriv2g\n\nend module derivs\n\nmodule series\n\n   use interfaces, only: IDeriv, IHDeriv\n\n   type :: Taylor\n      class(IDeriv), allocatable :: calc\n   contains\n      procedure :: term1\n      procedure :: evaluate\n   end type Taylor\n   \n   type :: HTaylor\n      class(IHDeriv), allocatable :: calc\n   contains\n      procedure :: term1    => hterm1\n      procedure :: term2    => hterm2\n      procedure :: evaluate => hevaluate\n   end type HTaylor\n \ncontains\n\n    subroutine term1(self)\n       class(Taylor), intent(in) :: self\n       call self%calc%deriv1()\n    end subroutine term1\n    \n    subroutine evaluate(self)\n       class(Taylor), intent(in) :: self\n       write(*,*) 'Evaluating Taylor series using'\n       call self%term1()\n    end subroutine evaluate\n\n    subroutine hterm1(self)\n       class(HTaylor), intent(in) :: self\n       call self%calc%deriv1()\n    end subroutine hterm1\n    \n    subroutine hterm2(self)\n       class(HTaylor), intent(in) :: self\n       call self%calc%deriv2()\n    end subroutine hterm2\n\n    subroutine hevaluate(self)\n       class(HTaylor), intent(in) :: self\n       write(*,*) 'Evaluating Taylor series using'\n       call self%term1()\n       call self%term2()\n    end subroutine hevaluate\n\nend module series\n \nprogram client\n\n   use derivs, only: DerivG, HDerivG\n   use series, only: Taylor, HTaylor\n   \n   type(Taylor),  allocatable :: teval\n   type(HTaylor), allocatable :: hteval\n   \n   teval = Taylor( DerivG() )\n   call teval%evaluate()\n\n   write(*,*)\n\n   hteval = HTaylor( HDerivG() )\n   call hteval%evaluate()\n   \nend program client\n\\end{lstlisting}\n\n\\end{appendices}\n\n\\end{document}\n"
  },
  {
    "path": "proposals/traits/20-109.txt",
    "content": "To: J3                                                     J3/20-109\nFrom: Brad Richardson\nSubject: Traits for Types\nDate: 2020-February-23\n\nProposal for Fortran Standard: 202y (NOT 202x)\n\n1. Problem\n\nCurrently, in order to pass a derived type to some library expected a type\nderived from it's own abstract type requires the addition of a \"wrapper\"\ntype to be used. This requires a cumbersome amount of boiler plate code and\nis not conducive to the type of \"generic\" code one would like to be able to\nwrite.\n\nThis proposal seeks to address the issue that writing \"generic\" libraries\nis either not possible, or places undue burden on its users. The main\nbenefits are the reduction in repeated logic or boiler plate wrapper types\nrequired for generic libraries, thereby enabling more code reuse and easier\nto maintain code bases.\n\n2. Proposed Solution\n\nThe solution would require the addition of a few attributes and variable\ndeclaration capabilities. First is the addition of the `trait` attribute to\na type specification. This requires that the type be abstract, and contain\nno components. I.e.\n\n    type, abstract, trait :: Show_t\n    contains\n      procedure(show_i), deferred :: show\n    end type Show_t\n\n    abstract interface\n      function show_i(self) result(string)\n        class(Show_t), intent(in) :: self\n        character(len=:), allocatable :: string\n      end function show_i\n    end interface\n\nSecond is the addition of the `implements` attribute for a type\nspecification. The `implements` attribute requires a list of at least one\ntrait the type is to implement, requiring the type to contain the\nprocedures with the interfaces defined by the trait(s). I.e.\n\n    type, implements(Show_t) :: Thing_t\n      character(len=:), allocatable :: the_string\n    contains\n      procedure :: show\n    end type Thing_t\n\n    function show(self) result(string)\n      class(Thing_t), intent(in) :: self\n      character(len=:), allocatable :: string\n\n      string = self%the_string\n    end function show\n\nThird is the addition of a variable declaration form using `trait`, in a\nsimilar fashion to `class`. The `trait` specification would require a list\nof at least one trait, and must either be allocatable, or a dummy argument\nof a procedure. In a similar manner that the instantiated value of a class\nvariable must be of that type, or an extended type, the instantiated value\nof a trait variable must be of a type which implements the given trait(s).\nThus, no components of the instantiated value are accessible, only the\nprocedures defined by the trait(s).\n\n3. Backward compatibility\n\nThis addition to the language would not break any existing standard\nconforming Fortran program, and thus preserves Fortran's backward\ncompatibility.\n\n4. Further discussion\n\nOnline discussion that led to this proposal can be found at\nhttps://github.com/j3-fortran/fortran_proposals/issues/125\n\n\n"
  },
  {
    "path": "proposals/worklist/26-116-din3a-recommend.txt",
    "content": "To: J3                                                     J3/26-116\nFrom: HPC\nSubject: Recommendation for DIN3a \"Support atomic operations in local memory\"\nDate: 2026-February-11\nReferences: 24-167, WG5/N2230, WG5/N2234, WG5/N2249\n\n1. Background\n=============\n\nWG5/N2249 provides the list of accepted work items for the next revision of\nISO/IEC 1539:2023 (Fortran 202Y). That list currently includes accepted work\nitem:\n\n  - DIN3a Add support for atomic operations in local memory\n          Ref: N2230 \"DIN Suggestions for F202Y\" (other features requested\n          in DIN3 were not accepted.)\n\nThis work item was initially added to the list by WG5 at the June 2024 meeting\nin WG5/N2234. As indicated above, it comprises a small subset of the broader\nitem DIN3 proposed in WG5/N2230 (and subsequently mostly declined by WG5) to\nexpand support for APU processing. The remaining subset relevant to atomic\noperations amounts to a two-sentence request with no specific rationale or use\ncases. To our knowledge, no follow-up J3 papers have been published to further\nsupport work item DIN3a or elaborate a proposed design for this feature in\nisolation. Nevertheless, Info paper 24-167 rated item DIN3a with difficulty\nlevel 5 (\"Technical change likely to need more than two J3 meetings to\ndevelop\").\n\nIn June 2025, WG5 voted to remove the proposed asynchronous tasking feature\nfrom Fortran 202Y work list item US04. With the deferral of asynchronous\ntasking, it's even less clear how the underspecified DIN3a work item is\nmotivated to fit into the remaining language features in Fortran 202Y.\n\n2. Subgroup Recommendation\n==========================\n\nThe J3 HPC subgroup recommends that item DIN3a be removed (without prejudice)\nfrom the Fortran 202Y work list. Proponents are welcome to resubmit the feature\nrequest for a future revision, along with a more substantive rationale and\ndesign sketch.\n\n\n3. Resolution\n=============\n\nIn passing this paper, INCITS/Fortran (J3) recommends to WG5 that item DIN3a be\nremoved from the work list for Fortran 202Y.\n\n===END===\n"
  }
]