# Repeat count for modern-style initializations

**URL:** <https://fortran-lang.discourse.group/t/repeat-count-for-modern-style-initializations/8386>\
**Category:** Help\
**Created:** [July 25, 2024, 6:09pm UTC](https://fortran-lang.discourse.group/t/repeat-count-for-modern-style-initializations/8386 "2024-07-25T18:09:14Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Machalot](https://avatars.discourse-cdn.com/v4/letter/m/ebca7d/32.png) [@Machalot](https://fortran-lang.discourse.group/u/Machalot)\
**Post date:** [July 25, 2024, 6:09pm UTC](https://fortran-lang.discourse.group/t/repeat-count-for-modern-style-initializations/8386/1 "2024-07-25T18:09:14Z")

</div>

One of the common suggestions for modernization is to replace

```fortran
real var
data var / 0.0 /

```

with

```fortran
real :: var = 0.0

```

But is there a modern form of the repeat count? For example, this fills a 200-element array.

```fortran
real y(200)
data y / 50*0.0, 50*1.0, 50*2.0, 25*3.0, 25*4.0 /

```

But this form doesn’t work:

```fortran
real,dimension(200) :: y = [50*0.0, 50*1.0, 50*2.0, 25*3.0, 25*4.0]

```

```bash
init.f90(4): error #7948: In this initialization, there are more variables than values assigned to the variables. [Y]
real,dimension(200) :: y = [50*0.0, 50*1.0, 50*2.0, 25*3.0, 25*4.0]
-----------------------^
compilation aborted for init.f90 (code 1)

```

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [July 25, 2024, 6:28pm UTC](https://fortran-lang.discourse.group/t/repeat-count-for-modern-style-initializations/8386/2 "2024-07-25T18:28:51Z")

</div>

There are implied do-loops, for example

```auto
implicit none
integer :: i
integer :: v(5) = [(4, i=1,2), (8, i=1,3)]
print "(*(1x,i0))", v ! 4 4 8 8 8
end

```

---

<div class="post-metadata">

**Author:** ![Machalot](https://avatars.discourse-cdn.com/v4/letter/m/ebca7d/32.png) [@Machalot](https://fortran-lang.discourse.group/u/Machalot)\
**Post date:** [July 25, 2024, 6:37pm UTC](https://fortran-lang.discourse.group/t/repeat-count-for-modern-style-initializations/8386/3 "2024-07-25T18:37:54Z")

</div>

Thanks, I can see how that works. Implied do-loops are much more powerful than simple repeat counts. But for the trivial case in my example, implied do is a bit clunky, with the throwaway integer variable.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [July 25, 2024, 7:30pm UTC](https://fortran-lang.discourse.group/t/repeat-count-for-modern-style-initializations/8386/4 "2024-07-25T19:30:26Z")

</div>

> [@Machalot](#):
>
> One of the common suggestions for modernization is to replace […]

This can be done in some cases, usually simpler ones, but not for all. For example, the data statements allow partial initialization of arrays (the first few elements, or the even elements, etc.), while the assignment syntax doesn’t. The data statements can be broken up into a series of statements, while the assignment syntax requires everything to be together in a single statement. Also, the array constructor syntax is more verbose, and if RESHAPE() is necessary, more cumbersome.

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [July 25, 2024, 8:50pm UTC](https://fortran-lang.discourse.group/t/repeat-count-for-modern-style-initializations/8386/5 "2024-07-25T20:50:31Z")

</div>

You can avoid the loop variable by defining an operator:

```auto
module m
implicit none
interface operator(.r.)
   module procedure rep
end interface
contains
function rep(val, n) result(vec)
integer, intent(in) :: n, val
integer :: vec(n)
integer :: i
vec = [(val, i=1,n)]
end function rep
end module m
!
program main
use m, only: operator(.r.)
implicit none
integer :: i
integer :: v(5) = [(4, i=1,2), (8, i=1,3)]
character (len=*), parameter :: fmt_i="(*(1x,i0))"
print fmt_i, v ! 4 4 8 8 8
print fmt_i,[4.r.2, 8.r.3] ! same
end program main

```

---

<div class="post-metadata">

**Author:** ![Machalot](https://avatars.discourse-cdn.com/v4/letter/m/ebca7d/32.png) [@Machalot](https://fortran-lang.discourse.group/u/Machalot)\
**Post date:** [July 25, 2024, 9:39pm UTC](https://fortran-lang.discourse.group/t/repeat-count-for-modern-style-initializations/8386/6 "2024-07-25T21:39:57Z")

</div>

While this works for array constructors in executable statements, `ifx 2024` doesn’t like user-defined operators in initialization.

```auto
repeat.f90(20): error #6973: This is not a valid initialization expression.
integer :: w(5) = [4.r.2, 8.r.3]
--------------------^
compilation aborted for repeat.f90 (code 1)

```

And `gfortran 8` says it can only use intrinsic functions in initialization expressions.

```auto
repeat.f90:20:23:

 integer :: w(5) = [4.r.2, 8.r.3]
                       1
Error: Function ‘rep’ in initialization expression at (1) must be an intrinsic function

```

---

<div class="post-metadata">

**Author:** ![septc](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/septc/32/77_2.png) [@septc](https://fortran-lang.discourse.group/u/septc)\
**Post date:** [July 25, 2024, 11:25pm UTC](https://fortran-lang.discourse.group/t/repeat-count-for-modern-style-initializations/8386/7 "2024-07-25T23:25:46Z")

</div>

I’ve also tried a similar approach, here using a usual function (`ones()`). But even if it is made `pure`, the compiler (here gfortran) rejects it as illegal, because `ones()` is not an intrinsic function. Because this function has no side effect, I wonder why it cannot be used at compile time…

```fortran
module mylib
    implicit none
contains
    pure function ones(n) result(arr)
        integer, intent(in) :: n
        real :: arr(n)
        arr(:) = 1
    end
end module

program main
    use mylib
    real :: y(20) = [ones(5)*0, ones(5)*1, ones(5)*2, ones(3)*3, ones(2)*4]
    print *, y(:)
end

$ gfortran test.f90
   19 | real :: y(20) = [ones(5)*0, ones(5)*1, ones(5)*2, ones(3)*3, ones(2)*4]
      | 1
Error: Function 'ones' in initialization expression at (1) must be an intrinsic function

```

---

<div class="post-metadata">

**Author:** ![FortranFan](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@FortranFan](https://fortran-lang.discourse.group/u/FortranFan)\
**Post date:** [July 26, 2024, 1:55am UTC](https://fortran-lang.discourse.group/t/repeat-count-for-modern-style-initializations/8386/8 "2024-07-26T01:55:05Z")

</div>

> [@Machalot](#):
>
> One of the common suggestions for modernization is to replace
> 
> ```auto
> real var
> data var / 0.0 /
> 
> ```
> 
> with
> 
> ```auto
> real :: var = 0.0
> 
> ```

That is unlikely a “common suggestions for modernization”.

What might be `FORTRAN` code as

```Fortran
     REAL VAR
     DATA VAR /0.0/

```

will require analysis to ascertain whether the **“implied SAVE”** is really necessary. The [**refactoring**](https://en.wikipedia.org/wiki/Code_refactoring) decision will depend on this analysis.

More often than not, the **modern Fortran** replacement will be

```Fortran
   real, parameter :: VAR = 0.0

```

In a few cases, it might call for an object definition in the executable section of the code separate from the variable declaration:

```Fortran
   ..
   real :: var
   ..
   var = 0.0

```

In a few unfortunate situations, the modern Fortran replacement may need to

```auto
   real, save :: var = 0.0 !<-- inform the reader explicitly the object has the SAVE attribute

```

---

<div class="post-metadata">

**Author:** ![urbanjost](https://avatars.discourse-cdn.com/v4/letter/u/0ea827/32.png) [@urbanjost](https://fortran-lang.discourse.group/u/urbanjost)\
**Post date:** [July 26, 2024, 2:17am UTC](https://fortran-lang.discourse.group/t/repeat-count-for-modern-style-initializations/8386/9 "2024-07-26T02:17:58Z")

</div>

Integer :: ints(100)=[spread(50,1,49).0.0,spread(-50,1,49)]

As mentioned implied do is more general but that is as close to a matlab ones function that I know of. Would be nice to initialize data like with nameless data with repeat and skips and even user defined type support as mentioned but I actually like data statements but appreciate when the compiler warns not all values are initialized when it is not intentional

---

<div class="post-metadata">

**Author:** ![FortranFan](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@FortranFan](https://fortran-lang.discourse.group/u/FortranFan)\
**Post date:** [July 26, 2024, 2:30am UTC](https://fortran-lang.discourse.group/t/repeat-count-for-modern-style-initializations/8386/10 "2024-07-26T02:30:40Z")

</div>

> [@Machalot](#):
>
> … the throwaway integer variable.

If the throwaway index is a bother, a coder can always resort to various **verbose** options of fast decreasing levels of elegance:

```Fortran
   real, parameter :: zero(50) = 0.0, one(50) = 1.0, two(50) = 2.0, three(50) = 3.0
   real :: y(200) = [zero, one, two, three] !<-- Note y has implied SAVE attribute

```

or an object definition in the executable section:

```Fortran
   real y(200)
   ..
   associate ( i => 1 ) 
      y = [[( 0.0, i = 1,50 )], [( 1.0, i = 1,50 )], [( 2.0, i = 1,50 )], [( 3.0, i = 1,50 )] ]
   end associate

```

or a similar one with a `BLOCK` construct as opposed to `ASSOCIATE`.

And the `NAMELIST` option with the repeat specification!

```Fortran
   real :: y(200)
   namelist / dat / y
   character(len=:), allocatable :: s
   s = "&dat y=50*0.0,50*1.0,50*2.0,50*3.0 /"
   read( s, nml=dat )
   print *, y(1), y(51), y(101), y(151)
end

```

---

<div class="post-metadata">

**Author:** ![urbanjost](https://avatars.discourse-cdn.com/v4/letter/u/0ea827/32.png) [@urbanjost](https://fortran-lang.discourse.group/u/urbanjost)\
**Post date:** [July 26, 2024, 3:21am UTC](https://fortran-lang.discourse.group/t/repeat-count-for-modern-style-initializations/8386/11 "2024-07-26T03:21:14Z")

</div>

The old way of doing that on a single line  
‘  
Real arr(100)/50\*1.0,50\*3.0/

Which I remember as an extension that I remember as being different from data in that the size had to fit but now I am thinking there is a chance that was std? It seems like I remember everyone had it but everyone had real\*8 too

---

<div class="post-metadata">

**Author:** ![urbanjost](https://avatars.discourse-cdn.com/v4/letter/u/0ea827/32.png) [@urbanjost](https://fortran-lang.discourse.group/u/urbanjost)\
**Post date:** [July 26, 2024, 4:12pm UTC](https://fortran-lang.discourse.group/t/repeat-count-for-modern-style-initializations/8386/12 "2024-07-26T16:12:52Z")

</div>

Another nice thing about DATA is it will fill multi- dimensional variables easily without calling RESHAPE. Ifx and gfortran support the inline data syntax too and ifx allows the vector to fill multi-dimensional arrays without reshaping.

```
Integer :: Ii(3,4)=[1,2,3,4,5,6,,8,9,10,11,12]
Integer kk(3,4)/3*1,9*0/
```

Work in ifx

---

<div class="post-metadata">

**Author:** ![Machalot](https://avatars.discourse-cdn.com/v4/letter/m/ebca7d/32.png) [@Machalot](https://fortran-lang.discourse.group/u/Machalot)\
**Post date:** [July 26, 2024, 4:31pm UTC](https://fortran-lang.discourse.group/t/repeat-count-for-modern-style-initializations/8386/13 "2024-07-26T16:31:57Z")

</div>

> [@urbanjost](#):
>
> Another nice thing about DATA is it will fill multi- dimensional variables easily without calling RESHAPE. Ifx and gfortran support the inline data syntax too and ifx allows the vector to fill multi-dimensional arrays without reshaping.

Is this standard or an extension?

---

<div class="post-metadata">

**Author:** ![Machalot](https://avatars.discourse-cdn.com/v4/letter/m/ebca7d/32.png) [@Machalot](https://fortran-lang.discourse.group/u/Machalot)\
**Post date:** [July 26, 2024, 4:41pm UTC](https://fortran-lang.discourse.group/t/repeat-count-for-modern-style-initializations/8386/14 "2024-07-26T16:41:38Z")

</div>

> [@FortranFan](#):
>
> That is unlikely a “common suggestions for modernization”.
> 
> What might be `FORTRAN` code as
> 
> ```auto
> REAL VAR
> DATA VAR /0.0/
> 
> ```
> 
> will require analysis to ascertain whether the **“implied SAVE”** is really necessary. The [**refactoring**](https://en.wikipedia.org/wiki/Code_refactoring) decision will depend on this analysis.

I’m confused by this comment. Doesn’t a `data` statement imply `save`?

As I searched google for the answer to that question I found one of your [posts saying that it does](https://fortran-lang.discourse.group/t/the-data-statement/5954/4).  
[Edit: The [Fortran 2003 draft](https://j3-fortran.org/doc/year/04/04-007.pdf) includes this language:]

![image](https://global.discourse-cdn.com/free1/uploads/fortran_lang/original/2X/9/9b2502261cddfcb87c99ad49f150030bbbb459cf.png)

If true, why would this be an “unlikely” suggestion if it’s semantically equivalent?

> [@FortranFan](#):
>
> More often than not, the **modern Fortran** replacement will be
> 
> ```auto
> real, parameter :: VAR = 0.0
> 
> ```

I would certainly _not_ assume most `data` initialized variables should be treated as parameters. Some might have been used that way, but `parameter` has been part of the language for a long time and many developers would have used it where it was needed.

---

<div class="post-metadata">

**Author:** ![urbanjost](https://avatars.discourse-cdn.com/v4/letter/u/0ea827/32.png) [@urbanjost](https://fortran-lang.discourse.group/u/urbanjost)\
**Post date:** [July 26, 2024, 5:18pm UTC](https://fortran-lang.discourse.group/t/repeat-count-for-modern-style-initializations/8386/15 "2024-07-26T17:18:39Z")

</div>

Both are extensions. Breaking the declaration and the data into two lines is standard

```
Integer :: ii(3,4):data ii /12*55/
```

Another one that might be wasteful

```
Integer,parameter:: ones(100)=1
Integer :: jj(10)=[ones(:10)*44]
```

That is, make a big vector of one or zero values and multiply or add values to subsections. Sort of a version of the matlab functions zeros and ones. Making an array big enough for your largest arrays would get wasteful depending on how clever the compiler is.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [July 26, 2024, 6:43pm UTC](https://fortran-lang.discourse.group/t/repeat-count-for-modern-style-initializations/8386/16 "2024-07-26T18:43:08Z")

</div>

> [@Machalot](#):
>
> Some might have been used that way, but `parameter` has been part of the language for a long time and many developers would have used it where it was needed.

There is still much legacy code written before f77 (where PARAMETER was introduced to the language) that used DATA initialization. In those cases, the “modernization” to f77 would have consisted either of changing to PARAMETER or to DATA with a SAVE statement. So the same issue remains with this legacy code when modernizing to post-f77 standards. The difference now is that SAVE is implicit, where it was not in f77. In hindsight, that implicit save has turned out to be a poor choice in the language, and many programmers, including me, prefer to add the SAVE attribute explicitly even though it is now redundant.

---

<div class="post-metadata">

**Author:** ![jwmwalrus](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/jwmwalrus/32/4483_2.png) [@jwmwalrus](https://fortran-lang.discourse.group/u/jwmwalrus)\
**Post date:** [July 26, 2024, 7:36pm UTC](https://fortran-lang.discourse.group/t/repeat-count-for-modern-style-initializations/8386/17 "2024-07-26T19:36:05Z")

</div>

I was asked once at a (Go-related) job interview for the best and worst features of the language (goroutines and enums, respectively).

In the case of Fortran, I would choose `allocatable/allocate` for best feature, and implicit `SAVE` as the worst one.

It seems to me that implicit `SAVE` often conflicts with the possibility of adding certain other features to the language… and it’s also a “gotcha” for newcomers.

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [July 26, 2024, 7:48pm UTC](https://fortran-lang.discourse.group/t/repeat-count-for-modern-style-initializations/8386/18 "2024-07-26T19:48:06Z")

</div>

You can upvote the issue

> <https://github.com/j3-fortran/fortran_proposals/issues/40>
>
> Currently, if you do:
> \`\`\`fortran
> integer :: x = 5
> \`\`\`
> Fortran implicitly add…s a \`save\` attribute:
> \`\`\`fortran
> integer, save :: x = 5
> \`\`\`
> This is a common gotcha (https://www.fortran90.org/src/gotchas.html#variable-initialization-using-initialization-expression). I would like this behavior to get deprecated somehow, then removed, and instead use the syntax \`integer :: x = 5\` to mean that the variable gets initialized to \`5\`. Because this implicit \`save\` behavior is used extremely rarely in modern Fortran codes.
> 
> One approach would be that when you declare a module, you do something like:
> \`\`\`
> implicit save(.false.)
> \`\`\`
> Right next to \`implicit none\` (we should find a better syntax), and then this behavior is disabled. There are other approaches.

---

<div class="post-metadata">

**Author:** ![Machalot](https://avatars.discourse-cdn.com/v4/letter/m/ebca7d/32.png) [@Machalot](https://fortran-lang.discourse.group/u/Machalot)\
**Post date:** [July 26, 2024, 10:21pm UTC](https://fortran-lang.discourse.group/t/repeat-count-for-modern-style-initializations/8386/19 "2024-07-26T22:21:42Z")

</div>

> [@RonShepard](#):
>
> There is still much legacy code written before f77 (where PARAMETER was introduced to the language) that used DATA initialization. In those cases, the “modernization” to f77 would have consisted either of changing to PARAMETER or to DATA with a SAVE statement. So the same issue remains with this legacy code when modernizing to post-f77 standards. The difference now is that SAVE is implicit, where it was not in f77.

Is it reasonable to assume anyone who is running the F77 codes today is using a modern compiler in which `data` comes with implicit `save`? Or are people still using compiler options to force F77 semantics and turn off implicit `save` on `data` statements? Barring that kind of compiler option, I think the first two code snippets in my original post are semantically identical and should not change any current behavior of legacy codes.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [July 26, 2024, 11:59pm UTC](https://fortran-lang.discourse.group/t/repeat-count-for-modern-style-initializations/8386/20 "2024-07-26T23:59:01Z")

</div>

> [@Machalot](#):
>
> Or are people still using compiler options to force F77 semantics and turn off implicit `save` on `data` statements?

In f77, the behavior was undefined when an unsaved variable was modified, so there isn’t really a meaning to “F77 semantics” in this case. The decision by the standard committee for implicit save was a way to bring such previously nonconforming code into conformance. It was the tail wagging the dog. And along with that, it complicated the issues of recursion and parallel execution. That was the trade for that decision. But, since implicit save has been part of the standard for over two decades (f2003, I think), it is unlikely to change.

[Next page](https://fortran-lang.discourse.group/t/repeat-count-for-modern-style-initializations/8386.md?page=2)
