• Re: CALL FOO when FOO is a function

    From pmk@21:1/5 to All on Wed May 18 09:07:12 2022
    Only one Fortran compiler can cope with this usage -- most crash
    hard with internal errors -- but I contend that it's conforming
    usage.
    On what grounds?

    Within the body of the function FOO, the name FOO refers to its result variable. The result variable in this case is a procedure pointer to a subroutine. A CALL statement's procedure designator is allowed to be a procedure pointer.

    module m
    contains
    function foo()
    procedure(bar), pointer :: foo
    foo => bar
    call foo ! <-- CALL of a function
    end function
    subroutine bar
    print *, 'in bar'
    end subroutine
    end module

    program demo
    use m
    procedure(bar), pointer :: p
    p => foo()
    call p
    end
    Sounds fishy, at least...

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From pmk@21:1/5 to All on Wed May 18 08:39:58 2022
    Only one Fortran compiler can cope with this usage -- most crash hard with internal errors -- but I contend that it's conforming usage.

    module m
    contains
    function foo()
    procedure(bar), pointer :: foo
    foo => bar
    call foo ! <-- CALL of a function
    end function
    subroutine bar
    print *, 'in bar'
    end subroutine
    end module

    program demo
    use m
    procedure(bar), pointer :: p
    p => foo()
    call p
    end

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Koenig@21:1/5 to pmk on Wed May 18 15:58:22 2022
    pmk <pmklausler@gmail.com> schrieb:

    Only one Fortran compiler can cope with this usage -- most crash
    hard with internal errors -- but I contend that it's conforming
    usage.

    On what grounds?

    module m
    contains
    function foo()
    procedure(bar), pointer :: foo
    foo => bar
    call foo ! <-- CALL of a function
    end function
    subroutine bar
    print *, 'in bar'
    end subroutine
    end module

    program demo
    use m
    procedure(bar), pointer :: p
    p => foo()
    call p
    end

    Sounds fishy, at least...

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to pmk on Wed May 18 10:37:46 2022
    On Wednesday, May 18, 2022 at 9:07:14 AM UTC-7, pmk wrote:
    Only one Fortran compiler can cope with this usage -- most crash
    hard with internal errors -- but I contend that it's conforming
    usage.

    On what grounds?

    Within the body of the function FOO, the name FOO refers to its
    result variable. The result variable in this case is a procedure pointer
    to a subroutine. A CALL statement's procedure designator is
    allowed to be a procedure pointer.

    I suspect I believe that it should not be an internal compiler error, but otherwise
    I might believe compilers could accept it. But there is no claim that the result
    is actually executable.

    Many systems have a different calling method for functions, depending
    on the type, and other attributes, of a function.

    A procedure pointer can point to either a function or subroutine,
    but you can only call functions with it when it points to functions,
    and subroutines when it points to subroutines.

    And if the compiler believes that you are not doing that, it is allowed
    to reject the program.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to pmk on Wed May 18 10:53:43 2022
    On Wednesday, May 18, 2022 at 8:40:00 AM UTC-7, pmk wrote:
    Only one Fortran compiler can cope with this usage -- most crash hard with internal errors -- but I contend that it's conforming usage.

    Some years ago, I tried one like this. gfortran didn't like it then,
    and (the one I have here) doesn't like it now:

    external fun, sub
    call trythis(1,sub)
    call trythis(2,fun)
    stop
    end
    subroutine sub(i)
    print *,'sub',i
    return
    end
    integer function fun(i)
    print *,'fun',i
    fun=3*i
    return
    end
    subroutine trythis(j, fs)
    if(j.eq.1) call fs(5)
    if(j.eq.2) k=fs(5)
    return
    end


    If you comment out one of the IF statements, then it is fine.
    Note that it never calls a function as a subroutine, or
    subroutine as a function, but with both IF statements,
    gfortran won't compile it.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Steve Lionel@21:1/5 to pmk on Wed May 18 14:53:47 2022
    On 5/18/2022 12:07 PM, pmk wrote:
    Within the body of the function FOO, the name FOO refers to its result variable. The result variable in this case is a procedure pointer to a subroutine. A CALL statement's procedure designator is allowed to be a procedure pointer.

    I agree with this.

    --
    Steve Lionel
    ISO/IEC JTC1/SC22/WG5 (Fortran) Convenor
    Retired Intel Fortran developer/support
    Email: firstname at firstnamelastname dot com
    Twitter: @DoctorFortran
    LinkedIn: https://www.linkedin.com/in/stevelionel
    Blog: https://stevelionel.com/drfortran
    WG5: https://wg5-fortran.org

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From FortranFan@21:1/5 to pmk on Wed May 18 17:35:55 2022
    On Wednesday, May 18, 2022 at 11:40:00 AM UTC-4, pmk wrote:

    Only one Fortran compiler can cope with this usage -- most crash hard with internal errors -- but I contend that it's conforming usage. ..

    Yes, that appears correct based on the wording in the standard.

    However the relevant wording is not part of any numbered constraint. And the processors then appear to miss out on coping with the semantics in such parts of the standard, especially with features introduced starting with Fortran 90. The "sleeping dogs
    lie" until an astute reader catches the omission and files support request(s) and the compiler developers find the resources to follow-up on the request(s).

    Nonetheless the chances are more compilers can cope with this variant:

    function foo() result(r)
    procedure(bar), pointer :: r
    r => bar
    call r
    end function

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From JRR@21:1/5 to pmk on Thu May 19 16:07:37 2022
    On 5/18/22 17:39, pmk wrote:
    Only one Fortran compiler can cope with this usage -- most crash hard with internal errors -- but I contend that it's conforming usage.

    module m
    contains
    function foo()
    procedure(bar), pointer :: foo
    foo => bar
    call foo ! <-- CALL of a function
    end function
    subroutine bar
    print *, 'in bar'
    end subroutine
    end module

    program demo
    use m
    procedure(bar), pointer :: p
    p => foo()
    call p
    end


    Indeed, the compiler gets confused between the result of the function
    foo (which should be the procedure pointer) and the function foo itself.
    It works if the result is explicitly specified like by Vipul
    (FortranFan), or if the function is defined as recursive. Then gfortran
    and Nagfor can compile, Nagfor even the original code with the -f2018
    flag (using the Fortran 2018 standard where every function is recursive).


    --
    Juergen Reuter
    Theoretical Particle Physics
    Deutsches Elektronen-Synchrotron
    Hamburg, Germany
    ---------------------------------
    invalid is desy .and. com is de

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Nagle@21:1/5 to Steve Lionel on Thu May 19 10:08:50 2022
    Hi,

    On May 18, 2022, Steve Lionel wrote
    (in article <jektlsFr6vU1@mid.individual.net>):

    On 5/18/2022 12:07 PM, pmk wrote:
    Within the body of the function FOO, the name FOO refers to its result variable. The result variable in this case is a procedure pointer to a subroutine. A CALL statement's procedure designator is allowed to be a procedure pointer.

    I agree with this.

    And I'll respectfully disagree.

    I think the gremlin lies in the procedure pointer assignment 10.2.2.4.

    These are all procedures in the same module so the interfaces are explicit
    (as is required by the pointer-ness and the procedure-ness).
    Since the interfaces are explicit, agreement is required of the characteristics.
    The characteristics include whether it is a subroutine or a function 15.3.1. qed

    (I'm reading 22-007r1)

    --
    Cheers!

    Dan Nagle

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From pmk@21:1/5 to JRR on Thu May 19 10:21:58 2022
    On Thursday, May 19, 2022 at 7:07:42 AM UTC-7, JRR wrote:
    It works if the result is explicitly specified like by Vipul
    (FortranFan), or if the function is defined as recursive. Then gfortran
    and Nagfor can compile, Nagfor even the original code with the -f2018
    flag (using the Fortran 2018 standard where every function is recursive).

    The recursive attribute (defaulted or not) is not relevant to the interpretation of names in a program.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From pmk@21:1/5 to Dan Nagle on Thu May 19 10:17:13 2022
    On Thursday, May 19, 2022 at 9:08:54 AM UTC-7, Dan Nagle wrote:
    I think the gremlin lies in the procedure pointer assignment 10.2.2.4.

    These are all procedures in the same module so the interfaces are explicit (as is required by the pointer-ness and the procedure-ness).
    Since the interfaces are explicit, agreement is required of the characteristics.
    The characteristics include whether it is a subroutine or a function 15.3.1. qed

    The procedure pointer is assigned to the same procedure used to define its interface.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From FortranFan@21:1/5 to JRR on Thu May 19 11:32:22 2022
    On Thursday, May 19, 2022 at 10:07:42 AM UTC-4, JRR wrote:

    .. if the function is defined as recursive. Then gfortran
    and Nagfor can compile, Nagfor even the original code with the -f2018
    flag (using the Fortran 2018 standard where every function is recursive). ..

    @Juergen Reuter,

    No recursion is involved here, the 2 compilers you have tried might be confused if they are bringing up anything recursion: they both appear to be treating occurrences of `FOO` in the `execution-part` of the function as `function-name`, instead of as
    function result, the latter being the semantics as stipulated by the standard. Both those compilers will then be non-conforming.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From FortranFan@21:1/5 to Dan Nagle on Thu May 19 11:26:23 2022
    On Thursday, May 19, 2022 at 12:08:54 PM UTC-4, Dan Nagle wrote:

    ..
    And I'll respectfully disagree.

    I think the gremlin lies in the procedure pointer assignment 10.2.2.4.

    These are all procedures in the same module so the interfaces are explicit (as is required by the pointer-ness and the procedure-ness).
    Since the interfaces are explicit, agreement is required of the characteristics.
    The characteristics include whether it is a subroutine or a function 15.3.1. qed

    (I'm reading 22-007r1) ..

    @Dan Nagle,

    Are you reading much into OP' s comment in the code in the original post, "CALL of a function"? There is no "call of a function" there, `FOO` is not a function on that line of instruction!

    Anyways, the characteristics with the function result which is FOO in the execution-part of the function match with the interface, there are no issues with this.

    The only problem here appears to be that several compilers as well as human readers overlook the text of the standard that states, "If RESULT does not appear, the name of the function result is function-name and all occurrences of the function name in
    execution-part statements in its scope are references to the function result."

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Nagle@21:1/5 to All on Thu May 19 13:25:10 2022
    On May 19, 2022, pmk wrote
    (in article<8c2cbb6d-7f18-4cdc-9112-05f3c278d30bn@googlegroups.com>):

    On Thursday, May 19, 2022 at 9:08:54 AM UTC-7, Dan Nagle wrote:
    I think the gremlin lies in the procedure pointer assignment 10.2.2.4.

    These are all procedures in the same module so the interfaces are explicit (as is required by the pointer-ness and the procedure-ness).
    Since the interfaces are explicit, agreement is required of the characteristics.
    The characteristics include whether it is a subroutine or a function 15.3.1.
    qed

    The procedure pointer is assigned to the same procedure used to define its interface.

    The function statement declares foo to be a function.
    The explicit interface for bar declares bar to be a subroutine.
    Hence, the mismatch.

    --
    Cheers!

    Dan Nagle

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From FortranFan@21:1/5 to Dan Nagle on Thu May 19 13:36:15 2022
    On Thursday, May 19, 2022 at 3:25:14 PM UTC-4, Dan Nagle wrote:

    ..
    The function statement declares foo to be a function.
    The explicit interface for bar declares bar to be a subroutine.
    Hence, the mismatch...

    That is not the case.

    See R1532 and note what is said about function statement versus execution-part and J3/22-007r1, page 336, lines 27 thru' 29.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From pmk@21:1/5 to Dan Nagle on Thu May 19 14:39:16 2022
    On Thursday, May 19, 2022 at 12:25:14 PM UTC-7, Dan Nagle wrote:
    The function statement declares foo to be a function.
    The explicit interface for bar declares bar to be a subroutine.
    Hence, the mismatch.

    I think you're saying that a function returning a procedure pointer can only return a pointer to a function, but not a pointer to a subroutine.

    That turns out to not be the case.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to Dan Nagle on Thu May 19 17:43:35 2022
    On Thursday, May 19, 2022 at 12:25:14 PM UTC-7, Dan Nagle wrote:

    (snip)

    The function statement declares foo to be a function.
    The explicit interface for bar declares bar to be a subroutine.
    Hence, the mismatch.

    Does that explain why my program doesn't work?

    Note that it only calls a function as function, and subroutine as subroutine, but still it won't compile with gfortran.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to All on Thu May 19 19:46:34 2022
    On Thursday, May 19, 2022 at 7:19:44 PM UTC-7, FortranFan wrote:

    (snip, I wrote)

    Does that explain why my program doesn't work?

    No, your code has genuine mismatch in the scope of your `trythis` subprogram.
    but still it won't compile with gfortran.

    If you have a Fortran 2018 compiler, here's a variant of your code the processor
    should accept: with "gfortran", you can replace the "generic" statement with an INTERFACE block.

    I actually wrote a program like this some years ago, when a similar question came up. I then had to recreate it. As far as I know, it uses only Fortran 66 features, but the only compiler I tried it on was gfortran.

    Much of Fortran 66 trusts users to do things right, such as argument
    type matching. Even so, as far as I know, Fortran 66 doesn't have a
    different type for subroutine names and function names.

    But okay, the way you write it sub and fun have to be in the module,
    which is less convenient than it could be. It is especially inconvenient
    if you want to separately compile each of them.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From FortranFan@21:1/5 to All on Thu May 19 19:19:42 2022
    On Thursday, May 19, 2022 at 8:43:37 PM UTC-4, gah4 wrote:

    @gah4,


    Does that explain why my program doesn't work?

    No, your code has genuine mismatch in the scope of your `trythis` subprogram.

    but still it won't compile with gfortran.

    If you have a Fortran 2018 compiler, here's a variant of your code the processor should accept: with "gfortran", you can replace the "generic" statement with an INTERFACE block.

    module m
    generic :: trythis => trythis1, trythis2
    contains
    subroutine trythis1(fs)
    procedure(sub) :: fs
    call fs(5)
    end subroutine
    subroutine trythis2(fs)
    procedure(fun) :: fs
    print *, "fs returns: ", fs(5)
    end subroutine
    subroutine sub(i)
    print *,'sub',i
    return
    end
    integer function fun(i)
    print *,'fun',i
    fun=3*i
    return
    end
    end module
    use m
    call trythis(sub)
    call trythis(fun)
    end

    --- console output ---
    C:\temp>ifort /standard-semantics p.f90
    Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.5.0 Build 20211109_000000
    Copyright (C) 1985-2021 Intel Corporation. All rights reserved.

    Microsoft (R) Incremental Linker Version 14.31.31105.0
    Copyright (C) Microsoft Corporation. All rights reserved.

    -out:p.exe
    -subsystem:console
    p.obj

    C:\temp>p.exe
    sub 5
    fun 5
    15

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Nagle@21:1/5 to All on Fri May 20 10:00:24 2022
    On May 19, 2022, FortranFan wrote
    (in article<ca164c05-4151-451d-b1d8-df1e91a44967n@googlegroups.com>):

    On Thursday, May 19, 2022 at 3:25:14 PM UTC-4, Dan Nagle wrote:

    ..
    The function statement declares foo to be a function.
    The explicit interface for bar declares bar to be a subroutine.
    Hence, the mismatch...

    That is not the case.

    See R1532 and note what is said about function statement versus execution-part and J3/22-007r1, page 336, lines 27 thru' 29.

    And at line 25 the function result variable has all the characteristics of
    the function.

    --
    Cheers!

    Dan Nagle

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Nagle@21:1/5 to All on Fri May 20 10:05:49 2022
    Hi,

    On May 19, 2022, pmk wrote
    (in article<b62af7de-49fd-420a-89b1-dd43552dd58bn@googlegroups.com>):

    On Thursday, May 19, 2022 at 12:25:14 PM UTC-7, Dan Nagle wrote:
    The function statement declares foo to be a function.
    The explicit interface for bar declares bar to be a subroutine.
    Hence, the mismatch.

    I think you're saying that a function returning a procedure pointer can only return a pointer to a function, but not a pointer to a subroutine.

    That turns out to not be the case.

    If you write a result-name in foo,
    and you use a local variable with the subroutine characteristic in bar.

    --
    Cheers!

    Dan Nagle

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From FortranFan@21:1/5 to Dan Nagle on Fri May 20 10:27:50 2022
    On Friday, May 20, 2022 at 12:00:28 PM UTC-4, Dan Nagle wrote:
    ..
    And at line 25 the function result variable has all the characteristics of the function. ..
    and
    On Friday, May 20, 2022 at 12:05:53 PM UTC-4, Dan Nagle wrote:
    ..
    If you write a result-name in foo,
    and you use a local variable with the subroutine characteristic in bar.

    @Dan Nagle,

    I fail to see how your first point, "the function result variable has all the characteristics of the function" of any relevance to the original post. A function can *indeed* have a function-result that is a procedure pointer to a subroutine, there are
    no doubts it. The following is a conforming program:

    module m
    contains
    function foo() result(r)
    procedure(bar), pointer :: r
    r => bar
    end function
    subroutine bar
    print *, 'in bar'
    end subroutine
    end module

    The question implied by OP is
    1. If RESULT clause does NOT appear and
    2. There is a reference to the function-name in the execution-part of the function,
    what does the standard and the compilers have to "say" about that?

    Well with the code in the original post, it conforms.

    The compilers appear to "fall over" at the line "CALL foo" only because the function-name itself is FOO.

    But the standard makes it clear, "If RESULT does not appear, the name of the function result is function-name and all occurrences of the function name in execution-part statements in its scope are references to the function result."

    Thus "CALL foo" does not involved a reference to the function-name per the standard, instead it is a reference to a procedure pointer associated with `bar`. One can see it as though the "offending" line were `CALL bar` and there is nothing non-
    conformant when viewed as such.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robin Vowels@21:1/5 to pmk on Sat May 21 02:56:03 2022
    On Thursday, May 19, 2022 at 1:40:00 AM UTC+10, pmk wrote:
    Only one Fortran compiler can cope with this usage -- most crash hard with internal errors -- but I contend that it's conforming usage.

    module m
    contains
    function foo()
    procedure(bar), pointer :: foo
    foo => bar
    call foo ! <-- CALL of a function
    end function
    subroutine bar
    print *, 'in bar'
    end subroutine
    end module

    program demo
    use m
    procedure(bar), pointer :: p
    p => foo()
    call p
    end
    .
    Why do you want to do this?
    .
    Just CALL a subroutine, and invoke a function with a function reference,
    in the traditional way.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Nagle@21:1/5 to All on Sat May 21 09:26:38 2022
    Hi,

    On May 20, 2022, FortranFan wrote
    (in article<46eb9bc5-af40-43fe-acef-1f1dd29556adn@googlegroups.com>):

    On Friday, May 20, 2022 at 12:00:28 PM UTC-4, Dan Nagle wrote:
    ..
    And at line 25 the function result variable has all the characteristics of the function. ..
    and
    On Friday, May 20, 2022 at 12:05:53 PM UTC-4, Dan Nagle wrote:
    ..
    If you write a result-name in foo,
    and you use a local variable with the subroutine characteristic in bar.

    @Dan Nagle,

    I fail to see how your first point, "the function result variable has all the characteristics of the function" of any relevance to the original post.

    The relevance is that, once the function statement gives the name foo the function characteristic,
    the declaration of the local result variable cannot change it. The
    declaration can set other
    attributes, but cannot change whether a name refers to an entity that is a function or a subroutine.
    That is determined by whether the name appears in a function statement
    or a subroutine statement.

    A
    function can *indeed* have a function-result that is a procedure pointer to a subroutine, there are no doubts it. The following is a conforming program:

    module m
    contains
    function foo() result(r)
    procedure(bar), pointer :: r
    r => bar
    end function
    subroutine bar
    print *, 'in bar'
    end subroutine
    end module

    I agree that this is conforming code.
    But that is due to the use of a result variable with a different name.
    This allows declaration of the function characteristics separately
    from the result value characteristics.

    That is, the above code never tells me that foo is a function and a
    subroutine.



    The question implied by OP is
    1. If RESULT clause does NOT appear and
    2. There is a reference to the function-name in the execution-part of the function,
    what does the standard and the compilers have to "say" about that?

    It says the result variable has all the characteristics of the function name, and that whether something is a function or a subroutine is a characteristic.



    Well with the code in the original post, it conforms.

    It does not. The original code confuses whether foo is a function or a subroutine.
    This it cannot do and be standard-conforming.

    I believe that another local variable is needed where foo is called,
    again to separate the function (value-producing) aspect from the subroutine aspect
    (target of pointer).



    The compilers appear to "fall over" at the line "CALL foo" only because the function-name itself is FOO.

    And the compiler can't guess whether you mean foo is a function or a subroutine.
    There are contradictory declarations.



    But the standard makes it clear, "If RESULT does not appear, the name of the function result is function-name and all occurrences of the function name in execution-part statements in its scope are references to the function result."

    Can you read the paragraph just before the above?
    You cannot specify the type of a function both on the function statement
    and within the function. Yet that is what you want to do.

    You must separate the declaration of the function from the declaration
    of the function's value. Do this by using another name, as in your result example
    (which I agree is conforming).

    "


    Thus "CALL foo" does not involved a reference to the function-name per the standard, instead it is a reference to a procedure pointer associated with `bar`. One can see it as though the "offending" line were `CALL bar` and there is nothing non-conformant when viewed as such.

    Not so. C1525 disagrees. The name appearing in a call statement must
    designate
    a subroutine. foo is the name of a function (whose value is a pointer to subroutine).

    Again, this can be cured by using a local variable to hold the value
    returned from the function foo, the which can then be called.

    The theme is that one must distinguish the function-ness of foo
    from the subroutine-ness of foo's result value. An extra variable does the trick.

    --
    Cheers!

    Dan Nagle

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ron Shepard@21:1/5 to Dan Nagle on Sat May 21 12:33:45 2022
    On 5/21/22 10:26 AM, Dan Nagle wrote:
    [...]
    Thus "CALL foo" does not involved a reference to the function-name per the >> standard, instead it is a reference to a procedure pointer associated with >> `bar`. One can see it as though the "offending" line were `CALL bar` and
    there is nothing non-conformant when viewed as such.

    Not so. C1525 disagrees. The name appearing in a call statement must designate
    a subroutine.

    In that call statement, foo is a procedure pointer to a subroutine, so
    does that not qualify as designating a subroutine?

    foo is the name of a function (whose value is a pointer to
    subroutine).

    Without the result() clause, foo is the value of the function within the function body, which is a pointer to a procedure. A procedure pointer
    can point to either subroutines or functions, without restriction. There
    are not separate pointers for functions and for subroutines, they all
    share the same type declaration.

    Furthermore, after the pointer assignment, it would be illegal to
    reference foo as a function within the body of the function. It is
    REQUIRED to reference it only as a subroutine and with the interface
    that is consistent with that of the target subroutine.


    Again, this can be cured by using a local variable to hold the value
    returned from the function foo, the which can then be called.

    The result() clause was added to the language in order to allow direct recursion to the function from within the body of the function. Of
    course, the recursive attribute is required, either explicitly (f90) or implicitly (f2003), in this case. After result(r) is added, then any
    references to foo are to the function, while references to r are to the
    value. It is even allowed to do indirect recursion without the result()
    clause, it is only direct recursion from foo to itself that requires the result() clause. However, in this example, there is no recursion
    involved anywhere, direct nor indirect. If recursion is not involved
    then it seems like result() should not be necessary.

    Without result(), there is no ambiguity that within the body of the
    function that references to foo are references to the value.


    The theme is that one must distinguish the function-ness of foo
    from the subroutine-ness of foo's result value. An extra variable does the trick.

    Those two "-ness" are already distinguished. Without the result(), all references to foo within the body are to its value. With the result()
    clause, all references to foo are recursive references to the function
    itself. It follows that since no recursive references to foo are
    invoked, then result() is unnecessary. It is like declaring a variable
    and then not referencing it. Of course, in this case, that might not be
    a bad idea for human readers of the code, but it seems unnecessary for
    the compiler which knows all of this because there is no ambiguity in
    the language in this respect.

    There is also the question of the argument list. If foo() and/or bar()
    had arguments, then all references to the foo function would require
    that argument list while references to the procedure pointer value would require the absence of an argument list. The associated code would then
    look like

    ! no result() code
    foo => bar ! no argument list.
    call bar(arg1,...) ! with argument list
    call foo(arg1,...) ! with argument list, through the pointer value.

    ! with result(r)
    r => bar ! no argument list.
    x=....foo(arg1,...) ! expression with direct recursion to foo()
    call bar(arg1,...) ! with argument list.
    call r(arg1,...) ! with argument list, through the pointer value.

    $.02 -Ron Shepard

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From FortranFan@21:1/5 to Dan Nagle on Sat May 21 15:49:21 2022
    On Saturday, May 21, 2022 at 11:26:43 AM UTC-4, Dan Nagle wrote:

    ..
    The relevance is that, once the function statement gives the name foo the function characteristic,
    the declaration of the local result variable cannot change it. The declaration can set other
    attributes, but cannot change whether a name refers to an entity that is a function or a subroutine.
    That is determined by whether the name appears in a function statement
    or a subroutine statement.

    @Dan Nagle,

    Re: your comment "The relevance is that, once the function statement gives the name foo the function characteristic, the declaration of the local result variable cannot change it,"

    * are you saying a function statement `foo` prevents the name `foo` from it from being treated as a function result variable that is a procedure pointer to a subroutine whereas it can have other characteristics?

    The following is a conforming program per my read of the Fortran 90 standard, chances are rather high every Fortran 90 and later compiler you can try will process the program ok:

    print *, foo(1)
    contains
    function foo(a)
    integer, intent(in) :: a
    integer :: foo(2)
    foo(1) = a
    foo(2) = foo(1) + 1
    end function
    end

    Do you think in this case once the function statement gives the name foo the function characteristic, the declaration of the local result variable cannot change it to an array of rank-1?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Nagle@21:1/5 to Ron Shepard on Sun May 22 09:22:52 2022
    Hi,

    You can't change a characteristic with a type statement. Full stop.
    You can create a characteristic with a type statement, but you cannot
    change an existing characteristic.

    On May 21, 2022, Ron Shepard wrote
    (in article <_n9iK.4090$Dr6.3622@fx06.iad>):

    On 5/21/22 10:26 AM, Dan Nagle wrote:
    [...]
    Thus "CALL foo" does not involved a reference to the function-name per the
    standard, instead it is a reference to a procedure pointer associated with
    `bar`. One can see it as though the "offending" line were `CALL bar` and there is nothing non-conformant when viewed as such.

    Not so. C1525 disagrees. The name appearing in a call statement must designate
    a subroutine.

    In that call statement, foo is a procedure pointer to a subroutine, so
    does that not qualify as designating a subroutine?

    No. The name foo appears in a function statement,
    which makes it a function.

    The value of foo is a pointer to subroutine.
    But foo is a function.



    foo is the name of a function (whose value is a pointer to
    subroutine).

    Without the result() clause, foo is the value of the function within the function body, which is a pointer to a procedure. A procedure pointer
    can point to either subroutines or functions, without restriction. There
    are not separate pointers for functions and for subroutines, they all
    share the same type declaration.

    The use must be consistent with the declarations of pointer and target.
    For example, the use must be consistent with the interface.



    Furthermore, after the pointer assignment, it would be illegal to
    reference foo as a function within the body of the function. It is
    REQUIRED to reference it only as a subroutine and with the interface
    that is consistent with that of the target subroutine.

    The function result variable inherits all the characteristics
    of the function name.

    The statement declaring foo to be a pointer to subroutine
    is invalid because it attempts to change the characteristics of foo.

    The function statement declares two characteristics of foo:
    1. foo is a function, and
    2. foo has no arguments.

    Neither can be contradicted and be standard-conforming.

    (aside- this is real nitpicking)

    In the above paragraph, shouldn't the prohibition on foo-as-function
    start with the declaration of foo-as-pointer-to-subroutine?
    So how do you assign a value at all?
    What is the function result variable of a subroutine?

    (end aside)




    Again, this can be cured by using a local variable to hold the value returned from the function foo, the which can then be called.

    The result() clause was added to the language in order to allow direct recursion to the function from within the body of the function. Of
    course, the recursive attribute is required, either explicitly (f90) or implicitly (f2003), in this case. After result(r) is added, then any references to foo are to the function, while references to r are to the value. It is even allowed to do indirect recursion without the result() clause, it is only direct recursion from foo to itself that requires the result() clause. However, in this example, there is no recursion
    involved anywhere, direct nor indirect. If recursion is not involved
    then it seems like result() should not be necessary.

    result was also added to allow the function value to be an array.
    (This is one reason why result variables inherit all characteristics
    of the function name- you want the array to have the correct shape.)



    Without result(), there is no ambiguity that within the body of the
    function that references to foo are references to the value.


    The theme is that one must distinguish the function-ness of foo
    from the subroutine-ness of foo's result value. An extra variable does the trick.

    Those two "-ness" are already distinguished. Without the result(), all references to foo within the body are to its value. With the result()
    clause, all references to foo are recursive references to the function itself. It follows that since no recursive references to foo are
    invoked, then result() is unnecessary. It is like declaring a variable
    and then not referencing it. Of course, in this case, that might not be
    a bad idea for human readers of the code, but it seems unnecessary for
    the compiler which knows all of this because there is no ambiguity in
    the language in this respect.

    The ambiguity is that you want some references to foo to be a function,
    and some references to foo to be a subroutine.

    Whether foo is a function or a subroutine is a characteristic
    that cannot change.

    foo is a function because it is the name in a function statement.
    The type of foo is irrelevant.

    foo is not a subroutine because its name does not appear in a subroutine statement.
    Attempting to do so by setting the type of the result is not conforming.

    <snip>


    $.02 -Ron Shepard

    --
    Cheers!

    Dan Nagle

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ron Shepard@21:1/5 to Dan Nagle on Sun May 22 13:06:26 2022
    On 5/22/22 10:22 AM, Dan Nagle wrote:
    [...]
    The function result variable inherits all the characteristics
    of the function name.

    Your claim would seem to apply to both cases, with and without the
    result() clause. Yet you have already stated that it doesn't, that it
    only applies to the case without the result() clause.

    Or are you claiming that with result(r), the entity r is not the result variable? Or that the entity r does not inherit all the characteristics
    of foo, the function name.

    Either way, it seems like a contradiction to the above statement?


    The statement declaring foo to be a pointer to subroutine
    is invalid because it attempts to change the characteristics of foo.

    Yet, with the result() clause you claim that the same thing is allowed.
    Isn't this inconsistent with your above argument?


    The function statement declares two characteristics of foo:
    1. foo is a function, and
    2. foo has no arguments.

    Within the body of the function, and without the result() clause,
    references to foo are to the result value, not recursive references to
    the function. This is the same as if it were say, an integer function. References within the body would be to the integer value, not recursive references to the function with no arguments. Here is another example of
    this, which I think is conforming:

    program func
    write(*,*) foo(3)
    contains
    function foo(n)
    integer :: foo(2) ! return an integer array.
    integer, intent(in) :: n
    foo(1) = -n
    foo(2) = n
    return
    end function foo
    end program func

    Note that there is no result() clause. The result of the function is an
    integer array, so result() is not necessary simply to declare an array
    valued function. Also, within the function body, the references to
    foo(1) and foo(2) are to the elements of the integer array, they are not recursive references to the function with its single integer argument.

    Is this small program conforming?

    [...]
    result was also added to allow the function value to be an array.

    The example above shows that result() is not required for this purpose.

    (This is one reason why result variables inherit all characteristics
    of the function name- you want the array to have the correct shape.)

    See the above example which contradicts this statement.

    Without result(), there is no ambiguity that within the body of the
    function that references to foo are references to the value.

    This is demonstrated with the above example. There is no result()
    clause, and there is no ambiguity, even though foo(1) looks the same
    with either interpretation.


    The theme is that one must distinguish the function-ness of foo
    from the subroutine-ness of foo's result value. An extra variable does the >>> trick.

    Those two "-ness" are already distinguished.

    This is demonstrated with the above code for the case of an integer
    array. The language already distinguishes between foo(1) as a recursive function reference and foo(1) as an array reference. The same occurs for
    other types, including I believe procedure pointers.


    The ambiguity is that you want some references to foo to be a function,
    and some references to foo to be a subroutine.

    There is no ambiguity. Without the result() clause, all references to
    foo within the function body are to its value as an integer array in the
    above example, and to a procedure pointer in the example being discussed.


    Whether foo is a function or a subroutine is a characteristic
    that cannot change.

    foo is a function, and its value is a procedure pointer.

    foo is a function because it is the name in a function statement.
    The type of foo is irrelevant.

    This statement is not consistent with the above example. There foo is a function, and the type of its value is an integer array. References such
    as foo(1) within the body of the function are to the integer array, not recursive references to the function.

    foo is not a subroutine because its name does not appear in a subroutine statement.
    Attempting to do so by setting the type of the result is not conforming.

    Are you claiming that the value of foo cannot be a procedure pointer
    that is assigned to a subroutine either with or without the result() clause?

    I remember Richard Maine saying that one should never write a function
    that returns a pointer value. I'm not sure this is what he had in mind,
    but perhaps this discussion reflects the wisdom of his warning.

    However, having said that, if I were to write a function that returns a procedure pointer, I would always use the result() clause to make it
    easier for a human to understand, although I think the language is
    unambiguous in either the result() or the no result() case.

    $.02 -Ron Shepard

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Van Buskirk@21:1/5 to Ron Shepard on Sun May 22 12:44:09 2022
    "Ron Shepard" wrote in message news:CYuiK.16679$wIO9.3518@fx12.iad...

    Within the body of the function, and without the result() clause,
    references to foo are to the result value, not recursive references to
    the function. This is the same as if it were say, an integer function. References within the body would be to the integer value, not recursive references to the function with no arguments. Here is another example of this, which I think is conforming:

    program func
    write(*,*) foo(3)
    contains
    function foo(n)
    integer :: foo(2) ! return an integer array.
    integer, intent(in) :: n
    foo(1) = -n
    foo(2) = n
    return
    end function foo
    end program func

    Note that there is no result() clause. The result of the function is an integer array, so result() is not necessary simply to declare an array
    valued function. Also, within the function body, the references to
    foo(1) and foo(2) are to the elements of the integer array, they are not recursive references to the function with its single integer argument.

    This was an issue that Steve Lionel was certainly familiar with because
    the Digital compiler had an extension that allowed for recursive
    functions. When the standard itself expanded to allow recursive
    procedures one could create standard-conforming programs where
    the Digital extension led to a result inconsistent with what the
    standard dictates, and the above example might be one such.

    Of course, Digital had to follow the standard but yet not require
    its user base to throw out all of their code at the same time. It's
    kind of mind-bending to think about the function foo and the
    result variable foo as different things with the same name in
    the seminal example of this thread, but different things can indeed
    have the same name. If you google my name the first thing it comes
    up with is some pervert from the West Coast. Another thing about
    names with which we are all familiar: https://en.wikipedia.org/wiki/Haddocks%27_Eyes

    I note that the title of this thread is intentionally provocative. If
    it were something like "CALL the target of FOO when FOO is a
    result variable that is a pointer to a subroutine" the thread would
    not have been nearly as entertaining.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Cyrmag@21:1/5 to James Van Buskirk on Sun May 22 21:16:55 2022
    On 5/22/2022 1:44 PM, James Van Buskirk wrote:
    <--SNIP-->

    It's kind of mind-bending to think about the function foo and the
    result variable foo as different things with the same name in
    the seminal example of this thread, but different things can indeed
    have the same name. If you google my name the first thing it comes
    up with is some pervert from the West Coast. Another thing about
    names with which we are all familiar: https://en.wikipedia.org/wiki/Haddocks%27_Eyes

    Not only the same name, as James writes, but sometimes we use the same
    notation but with different meanings.

    Indeed, having multiple purposes/meanings of parentheses -- to hold a
    sequence of subprogram arguments, and also to hold subscripts -- is the
    cause of so many complicated and confusing rules. Had we used the
    notation of other programming languages, "foo(n)" would be a function invocation and "foo[n]" would be the n-th or (n+1)th element of array
    "foo". As things stand in Fortran, we are burdened with mind-bending
    stuff such as the following in F2008:

    "If RESULT appears, the name of the result variable of the function is result-name and all occurrences of the function name in execution-part statements in its scope refer to the function itself. If RESULT does not appear, the name of the result variable is function-name and all
    occurrences of the function name in execution-part statements in its
    scope are references to the result variable."

    One could comically restate this quotation as "If RESULT appears, the
    result is RESULT and the function is FUNCTION. If RESULT does not
    appear, result is FUNCTION and function is RESULT".

    -- CyrMag

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From jfh@21:1/5 to CyrMag on Sun May 22 21:41:23 2022
    On Monday, May 23, 2022 at 2:17:01 PM UTC+12, CyrMag wrote:
    On 5/22/2022 1:44 PM, James Van Buskirk wrote:
    <--SNIP-->
    It's kind of mind-bending to think about the function foo and the
    result variable foo as different things with the same name in
    the seminal example of this thread, but different things can indeed
    have the same name. If you google my name the first thing it comes
    up with is some pervert from the West Coast. Another thing about
    names with which we are all familiar: https://en.wikipedia.org/wiki/Haddocks%27_Eyes

    Not only the same name, as James writes, but sometimes we use the same notation but with different meanings.

    Indeed, having multiple purposes/meanings of parentheses -- to hold a sequence of subprogram arguments, and also to hold subscripts -- is the
    cause of so many complicated and confusing rules. Had we used the
    notation of other programming languages, "foo(n)" would be a function invocation and "foo[n]" would be the n-th or (n+1)th element of array
    "foo".
    <-SNIP->

    That would give [ ] multiple meanings. If you think parentheses have too many meanings in Fortran, what about the asterisk? It had 20 the last time I looked, and many of them are not obsolescent.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Nagle@21:1/5 to Ron Shepard on Mon May 23 10:41:43 2022
    Hi,

    On May 22, 2022, Ron Shepard wrote
    (in article <CYuiK.16679$wIO9.3518@fx12.iad>):

    On 5/22/22 10:22 AM, Dan Nagle wrote:
    [...]
    The function result variable inherits all the characteristics
    of the function name.

    Your claim would seem to apply to both cases, with and without the
    result() clause. Yet you have already stated that it doesn't, that it
    only applies to the case without the result() clause.

    Because that is the same name in the result variable and the function.
    I have posted that I believe the code is valid, provided a differently-named result variable is used.

    I claim (again) that declarations may not contradict each other.



    Or are you claiming that with result(r), the entity r is not the result variable? Or that the entity r does not inherit all the characteristics
    of foo, the function name.

    Either way, it seems like a contradiction to the above statement?


    The statement declaring foo to be a pointer to subroutine
    is invalid because it attempts to change the characteristics of foo.

    Yet, with the result() clause you claim that the same thing is allowed.
    Isn't this inconsistent with your above argument?

    No, because with a result clause, the same name in the same scope
    is not being given contradictory characteristics.

    <snip>

    Here is another example of
    this, which I think is conforming:

    program func
    write(*,*) foo(3)
    contains
    function foo(n)
    integer :: foo(2) ! return an integer array.
    integer, intent(in) :: n
    foo(1) = -n
    foo(2) = n
    return
    end function foo
    end program func

    Note that there is no result() clause. The result of the function is an integer array, so result() is not necessary simply to declare an array
    valued function. Also, within the function body, the references to
    foo(1) and foo(2) are to the elements of the integer array, they are not recursive references to the function with its single integer argument.

    Is this small program conforming?

    Where does a declaration contradict another declaration?



    [...]
    result was also added to allow the function value to be an array.

    The example above shows that result() is not required for this purpose.

    (This is one reason why result variables inherit all characteristics
    of the function name- you want the array to have the correct shape.)

    See the above example which contradicts this statement.

    Again, where are the contradictory declarations?

    <snip>


    There is no ambiguity. Without the result() clause, all references to
    foo within the function body are to its value as an integer array in the above example, and to a procedure pointer in the example being discussed.

    But your example declaration (integer function) the later declaration
    does not contradict the earlier one.

    Look, the statement "function foo" declares foo to be a function.
    Declaring foo's return value to be a pointer-to-subroutine contradicts that,
    if you try to use the same name. Declaring foo to return an integer array
    does not contradict foo being a function.




    Whether foo is a function or a subroutine is a characteristic
    that cannot change.

    foo is a function, and its value is a procedure pointer.

    Correct. Which is why, in the same scope, they both cannot
    be declared using the same name.



    foo is a function because it is the name in a function statement.
    The type of foo is irrelevant.

    This statement is not consistent with the above example. There foo is a function, and the type of its value is an integer array. References such
    as foo(1) within the body of the function are to the integer array, not recursive references to the function.

    Note that "subsequent declaration" and "contradictory declaration" are different cases.

    Please.

    Comment

    A code is not standard-conforming unless the standard says what it means.

    Fortran allows declarations of one name in one scope to be spread across several statements. But the incremental declarations must all be consistent.

    Recall that the OP asked why so many compilers "crash hard with internal errors".
    My answer is that many compilers have not seen a lot of code with procedure pointers,
    and they do not yet catch all the errors they might (and possibly will someday).

    --
    Cheers!

    Dan Nagle

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Steve Lionel@21:1/5 to pmk on Mon May 23 19:29:25 2022
    On 5/18/2022 11:39 AM, pmk wrote:
    Only one Fortran compiler can cope with this usage -- most crash hard with internal errors -- but I contend that it's conforming usage.

    module m
    contains
    function foo()
    procedure(bar), pointer :: foo
    foo => bar
    call foo ! <-- CALL of a function
    end function
    subroutine bar
    print *, 'in bar'
    end subroutine
    end module

    program demo
    use m
    procedure(bar), pointer :: p
    p => foo()
    call p
    end


    I respectfully disagree with Dan Nagle here.

    Referencing Fortran 2018, 15.6.2.2 (Function subprogram), paragraph 3, says:

    "The type and type parameters (if any) of the result of the function
    defined by a function subprogram may be specified by a type
    specification in the FUNCTION statement or by the name of the function
    result appearing in a type declaration statement in the specification
    part of the function subprogram. They shall not be specified both ways.
    If they are not specified either way, they are determined by the
    implicit typing rules in effect within the function subprogram. If the
    function result is an array, allocatable, or a pointer, this shall be
    specified by specifications of the name of the function result within
    the function body. The specifications of the function result attributes,
    the specification of dummy argument attributes, and the information in
    the procedure heading collectively define the characteristics of the
    function (15.3.1)"

    P4 then says, in part, "If RESULT does not appear, the name of the
    function result is function-name and all occurrences of the function
    name in execution-part statements in its scope are references to the
    function result."

    NOTE 1 then says, "The function result is similar to any other entity
    (variable or procedure pointer) local to a function subprogram. Its
    existence begins when execution of the function is initiated and ends
    when execution of the
    function is terminated."

    Within the function, FOO is not a function, it is a local variable that
    is the function result. Its characteristics are those declared in the specification section as a procedure pointer with interface (BAR), which happens to be a subroutine. This is fine, and there is no conflict or
    duplicate declaration.

    If we were to accept Dan's position that the FUNCTION statement causes
    the function result to be a function, a function such as:

    function BAZ ()
    REAL :: BAZ
    BAZ = 3.0
    end function BAZ

    would be invalid, since you can't assign 3.0 to a function.

    This case is confusing, I'll admit. I note that NAG Fortran 7.1 rejects
    it, complaining of a recursive reference to FOO. I'm going to run this
    by the committee and see what they think. (I'll also report the ICE to
    Intel, though not before I get an answer as to what it is supposed to do.)

    --
    Steve Lionel
    ISO/IEC JTC1/SC22/WG5 (Fortran) Convenor
    Retired Intel Fortran developer/support
    Email: firstname at firstnamelastname dot com
    Twitter: @DoctorFortran
    LinkedIn: https://www.linkedin.com/in/stevelionel
    Blog: https://stevelionel.com/drfortran
    WG5: https://wg5-fortran.org

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to Steve Lionel on Mon May 23 19:55:56 2022
    On Monday, May 23, 2022 at 4:29:31 PM UTC-7, Steve Lionel wrote:

    (snip)

    This case is confusing, I'll admit. I note that NAG Fortran 7.1 rejects
    it, complaining of a recursive reference to FOO. I'm going to run this
    by the committee and see what they think. (I'll also report the ICE to
    Intel, though not before I get an answer as to what it is supposed to do.)

    Much of this can be confusing to humans, if not the compiler.

    Since you can't call integers, or add functions, we know the difference
    between an integer variable and procedure pointer.

    I know it slightly better in C, and maybe it is a little less confusing.

    In C you can declare a function:

    double fun();

    or a function pointer:

    double (*fp)();

    Also, in C () is the function call operator, similar to the way [] is the
    array reference operator. (It isn't quite as easy in Fortran.)

    You can assign to a function pointer:

    fp=sqrt; // no () operator

    and call a function using a dereferenced function pointer:

    x=(*fp)(2.0);

    However, it seems that C lets you get away with calling a function
    pointer instead of a function:

    x=fp(2.0);
    even though maybe it shouldn't.

    But now, consider a function that returns a function pointer.

    Here is one place where the difference between C and Fortran appears.
    In C, you can reference an array element of an array (actually
    a pointer) returned by a function:

    double *af();
    x = af()[0];

    while Fortran requires assigning the function value to an array.

    But now, consider a function returning a function pointer,
    a function pointer to such function, and reference using it.
    and then a call to the function from the returned pointer.

    Declare function pointer to function returning a function pointer:
    double (*(*fpp)())();

    Declare function returning a function pointer:
    double (*ffp())();

    ffp=fpp; // point to the function

    Call the function, and then the returned function:

    printf("%f\n", (*fpp())(3.14));

    or call it this way:

    printf("%f\n", (fpp())(3.14));

    I don't know how to write or call functions returning function pointers,
    or pointers to them in Fortran. Here is the whole C program:


    #include <stdio.h>
    #include <math.h>
    int main() {
    double (*fp)();
    double (*(*fpp)())();
    double (*ffp())();
    fp=sqrt;
    printf("%f\n", (*fp)(2.0));
    printf("%f\n", fp(2.0));
    fpp = ffp;
    printf("%f\n", (*fpp())(3.14));
    printf("%f\n", (fpp())(3.14));
    }

    double (*ffp())() {
    return cos;
    }

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From FortranFan@21:1/5 to Steve Lionel on Mon May 23 20:15:24 2022
    On Monday, May 23, 2022 at 7:29:31 PM UTC-4, Steve Lionel wrote:

    ..
    This case is confusing, I'll admit. I note that NAG Fortran 7.1 rejects
    it, complaining of a recursive reference to FOO. I'm going to run this
    by the committee and see what they think.

    Given OP's first line, "Only one Fortran compiler can cope with this usage," I had been wondering whether NAG Fortran was the one that managed to "cope with this usage". Your note that "NAG Fortran 7.1 rejects it, complaining of a recursive reference to
    FOO" is interesting. The note by @Juergen Reuter upthread, ".. if the function is defined as recursive. Then gfortran and Nagfor can compile, Nagfor even the original code with the -f2018 flag (using the Fortran 2018 standard where every function is
    recursive)" had indicated the same.

    Given the situation, your plan that "I'm going to run this by the committee and see what they think" is perfect. Thank you, it will be very helpful to learn of the committee feedback.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Steve Lionel@21:1/5 to Steve Lionel on Tue May 24 09:17:45 2022
    On 5/23/2022 7:29 PM, Steve Lionel wrote:
    This case is confusing, I'll admit. I note that NAG Fortran 7.1 rejects
    it, complaining of a recursive reference to FOO. I'm going to run this
    by the committee and see what they think. (I'll also report the ICE to
    Intel, though not before I get an answer as to what it is supposed to do.)

    Malcolm Cohen (NAG Fortran, standard editor) said, "There is no doubt
    that within FOO, FOO is the eponymous result name, not the name of the subprogram. This is similar to functions returning arrays – within an
    array function F with no RESULT clause, F(I,J) is an array element of
    the result, not a recursive self-reference."

    --
    Steve Lionel
    ISO/IEC JTC1/SC22/WG5 (Fortran) Convenor
    Retired Intel Fortran developer/support
    Email: firstname at firstnamelastname dot com
    Twitter: @DoctorFortran
    LinkedIn: https://www.linkedin.com/in/stevelionel
    Blog: https://stevelionel.com/drfortran
    WG5: https://wg5-fortran.org

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From CyrMag@21:1/5 to Steve Lionel on Tue May 24 16:39:41 2022
    On Tuesday, May 24, 2022 at 8:17:49 AM UTC-5, Steve Lionel wrote:
    On 5/23/2022 7:29 PM, Steve Lionel wrote:
    This case is confusing, I'll admit. I note that NAG Fortran 7.1 rejects it, complaining of a recursive reference to FOO. I'm going to run this
    by the committee and see what they think. (I'll also report the ICE to Intel, though not before I get an answer as to what it is supposed to do.)
    Malcolm Cohen (NAG Fortran, standard editor) said, "There is no doubt
    that within FOO, FOO is the eponymous result name, not the name of the subprogram. This is similar to functions returning arrays – within an array function F with no RESULT clause, F(I,J) is an array element of
    the result, not a recursive self-reference."
    --
    Steve Lionel

    In that case, the comment by PMK in the code fragment in the leading post:

    call foo ! <-- CALL of a function

    is incorrect, and perhaps misleading. On this line, "foo" is not the function FOO, but a pointer that is associated with a subroutine, and it is that subroutine that is being called through the pointer, and there is no the function itself being (
    recursively or otherwise) "called", as the comment suggests.

    Do you agree, Steve L.?

    -- Cyrmag

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From FortranFan@21:1/5 to Steve Lionel on Tue May 24 18:26:54 2022
    On Tuesday, May 24, 2022 at 9:17:49 AM UTC-4, Steve Lionel wrote:
    ..
    Malcolm Cohen (NAG Fortran, standard editor) said, "There is no doubt
    that within FOO, FOO is the eponymous result name, not the name of the subprogram. This is similar to functions returning arrays – within an array function F with no RESULT clause, F(I,J) is an array element of
    the result, not a recursive self-reference." ..

    Thank you for the follow-up, that is very useful to know. I wonder whether NAG Fortran team will open up a support incident on this.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to Steve Lionel on Wed May 25 04:43:24 2022
    On Monday, May 23, 2022 at 4:29:31 PM UTC-7, Steve Lionel wrote:

    (snip)

    If we were to accept Dan's position that the FUNCTION statement causes
    the function result to be a function, a function such as:

    function BAZ ()
    REAL :: BAZ
    BAZ = 3.0
    end function BAZ

    would be invalid, since you can't assign 3.0 to a function.

    It seems to me that isn't quite right. Variables can have different
    attributes, depending on where they are used.

    My first thought is that I should be able to use an array as a DO
    variable, since I can assign one in an assignment statement.

    integer i(10)
    do i=1,10
    print *,i
    enddo

    I expect this not to work, even though there is nothing wrong
    with assigning to i.

    But yes, in an assignment statement BAZ is an integer variable,
    and not a function, so the assignment works.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Steve Lionel@21:1/5 to FortranFan on Wed May 25 17:55:16 2022
    On 5/24/2022 9:26 PM, FortranFan wrote:
    Thank you for the follow-up, that is very useful to know. I wonder whether NAG Fortran team will open up a support incident on this.

    Yes, Malcolm filed one. I have also reported the ICE to Intel.

    --
    Steve Lionel
    ISO/IEC JTC1/SC22/WG5 (Fortran) Convenor
    Retired Intel Fortran developer/support
    Email: firstname at firstnamelastname dot com
    Twitter: @DoctorFortran
    LinkedIn: https://www.linkedin.com/in/stevelionel
    Blog: https://stevelionel.com/drfortran
    WG5: https://wg5-fortran.org

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Steve Lionel@21:1/5 to CyrMag on Wed May 25 17:55:37 2022
    On 5/24/2022 7:39 PM, CyrMag wrote:
    In that case, the comment by PMK in the code fragment in the leading post:

    call foo ! <-- CALL of a function

    is incorrect, and perhaps misleading.

    Yes.

    --
    Steve Lionel
    ISO/IEC JTC1/SC22/WG5 (Fortran) Convenor
    Retired Intel Fortran developer/support
    Email: firstname at firstnamelastname dot com
    Twitter: @DoctorFortran
    LinkedIn: https://www.linkedin.com/in/stevelionel
    Blog: https://stevelionel.com/drfortran
    WG5: https://wg5-fortran.org

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)