2

The ASSOCIATE feature is in principle quite useful, as it allows assigning values to names without incurring the syntactical overhead of explicitly defining local variables. However, its utility is limited because the values are bound only after the ASSOCIATE statement. This quickly leads to the need for nested associate statements, e.g.

PROGRAM toyexample
  IMPLICIT NONE
  ASSOCIATE(a => 2)
    ASSOCIATE(b => [a, 2*a, 3*a])
      PRINT *, a
      PRINT *, b
    END ASSOCIATE
  END ASSOCIATE
END PROGRAM toyexample

In Lisp terms, this would be the behavior of let, while I seek to emulate the behavior of let*, which would allow me to write

PROGRAM toyexample
  IMPLICIT NONE
  ASSOCIATE(a => 2, b => [a, 2*a, 3*a])
    PRINT *, a
    PRINT *, b
  END ASSOCIATE
END PROGRAM toyexample

Is there any feature in Fortran that allows me to do this?

Ian Bush
  • 6,996
  • 1
  • 21
  • 27
kdb
  • 4,098
  • 26
  • 49
  • 1
    It depends on your compiler. For example ifort does allow what you are asking for even as it is not standard conforming. – jack Mar 10 '21 at 09:53
  • @jack I tested and confirm. Sadly, I need to code to work across several compilers. – kdb Mar 10 '21 at 12:54
  • It is indeed the case that you cannot use the associate name in a selector in the same associate list. There are ways to force things in to one associate construct, but perhaps none is as understandable/elegant as nested associate constructs (however awkward that is). – francescalus Mar 10 '21 at 19:41
  • @roygvib That solution looks more like obfuscation. It doesn't gain anything except a few typed characters, but it doesn't affect, e.g., nesting levels. Though in principle something like `#define associate3(a,b,c) ASSOCIATE(a); ASSOCIATE(b); ASSOCIATE(c)` might achieve the purpose -- but still at the cost of slight obfuscation (and confusing the editors indentation capabilities). – kdb Mar 11 '21 at 17:20
  • @kdb okay... Because current Fortran does not allow that syntax, I think it will be very nice if you post the desired behavior here (via the "issue" tab) https://github.com/j3-fortran/fortran_proposals I would also like to use that syntax if available in future. – roygvib Mar 11 '21 at 21:26

1 Answers1

1
program toyexample1
    implicit none

    integer, parameter :: a = 11
    integer, parameter :: b = 22
    integer, parameter :: c = 33

    associate(a => b, b => c, c => a)
        print *, a, b, c ! Intel Fortran print: 22 33 22, other 22 33 11
    end associate
    block; integer, parameter :: a = b, b = c, c = a ! NAG Fortran rejected
        print *, a, b, c ! All compilers print: 22 33 22
    end block
    block; integer, parameter :: a = 2, b(*) = ([a, 2*a, 3*a]) ! PGfortran crash
        print *, a, b(:) ! All compilers print 2 2 4 6
    end block
end program toyexample1
Serge3leo
  • 411
  • 2
  • 4
  • 1
    Practical use-cases would not use `PARAMETER` values. The use of constants is purely for the sake of providing a minimal example. – kdb Mar 10 '21 at 15:52