I saw people saying that the percentage sign should be replaced with the dot sign for derived types. I want to ask if this has been a serious discussion or it is unlikely to happen.
I strongly prefer the percentage sign since dots are already used in other places, such as .true. and .gt… I think Fortran should learn from C++ to add more functionalities instead of mimicking its syntax. Moreover, such a breaking change would be disastrous for tons of existing codes.
Hey @fortran4r, welcome to the forum! I don’t think you have reason to worry, while many people (including me) really don’t like the ‘%’ sign, I think there’s widespread acknowledgement that the dot doesn’t work well in Fortran, for the exact reason you specify.
I also don’t think that if any change did happen, it would be a “breaking” change. If anything, a new syntax might be inlcuded as equivalent to the % sign, but even I would be against changing the percent sign and breaking old code.
Edit: just for the benefit of any other people who might see this forum topic but not previous discussions about the percent sign, it’s worth mentioning that even if you don’t like %, there are some good workarounds. The main objection to the percent sign is that since it’s a fairly “busy” looking character and takes up a lot of vertical space (compared with a dot, or even ->), it makes expressions that it appears in harder to read and visually parse. One way around this is to adjust your editor’s syntax hilighting so that the percent sign is printed in a lighter shade - then the fact that it is a “space” between symbols and not part of a symbol name is more evident at quick glance. Also, certain editors like vim allow you to display one character as another, while still saving the “proper” charactedr in the actual source file. So you could have “%” appear as some smaller character that does a better job of visual separation, but “%” is still in the underlying file so there’s no issue with the compiler or sharing the file with other users (this feature is called “concel” in vim).
FWIW, I like the fact that % takes vertical space: it helps in distinguishing the tokens of the expression. My criticism against it, is that it is not as quick to type as the dot (requiring to hold the shift key) and somehow “breaking the flow” while you’re coding.
Not a fan of the %. The only way I can make it readable to me is to surround it with a space, e.g., sometype % someattrib instead of sometype%someattrib. I hate to waste 3 characters on it, but gotta make do.
I am not a big fan of % either (just my preference), and in my case I eventually settled to put one space on the right side of % (like foo% baa% hello()). I remember some codes on the net put spaces on both sides of %.
More recently, I started to put color on %, which was very nice to me. Because I use Emacs, I include a setting into .emacs like
I agree with this. This point got me thinking about a possible workaround.
There are at least three or four keys on my regional Nordic keyboard that are “useless”, at least when it comes to typing code. Keys such as “ä”, “ö”, “å”, “§” are always left untouched during a typical Fortran coding session. I wonder if it would be possible to re-map one of those keys to produce a “%” instead of the assigned letter?
@certik and anyone interested in a long-term vision for Fortran,
The statement by @certik “That is very unlikely to happen” is spot on.
But I have long wondered about something and it will be useful if you too can contemplate about the same and try to explain why Fortran standard cannot eventually support both object designators i.e., both % and . symbols?
Then envision a scenario where Fortran standard is somehow freed from the shackles of fixed-form source.
Then consider the following non-conforming code that makes use of part of “DEC Structure” syntax:
module m
type :: t
integer :: a = 0
end type
interface operator(.add.)
module procedure add_a_b
end interface
contains
function add_a_b( lhs, rhs ) result(r)
type(t), intent(in) :: lhs
type(t), intent(in) :: rhs
type(t) :: r
r.a = lhs.a + rhs.a
end function
end module
use m
type :: u
type(t) :: x
end type
type(u) :: foo, bar, foobar
foo.x.a = 1 ; bar.x.a = 2
foobar.x = foo.x .add. bar.x
print *, "foobar.x.a = ", foobar.x.a, "; expected is 3"
print *, "Is foobar.x.a .gt. foo.x.a? ", foobar.x.a .gt. foo.x.a, "; expected is T"
end
Now see the responses by 2 processors used quite a bit by Fortranners: gfortran and Intel Fortran.
C:\Temp>gfortran -fdec-structure s.f90 -o s.exe
C:\Temp>s.exe
foobar.x.a = 3 ; expected is 3
Is foobar.x.a .gt. foo.x.a? T ; expected is T
C:\Temp>ifort s.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.3.0 Build 20210609_000000
Copyright (C) 1985-2021 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 14.29.30038.1
Copyright (C) Microsoft Corporation. All rights reserved.
-out:s.exe
-subsystem:console
s.obj
C:\Temp>s.exe
foobar.x.a = 3 ; expected is 3
Is foobar.x.a .gt. foo.x.a? T ; expected is T
C:\Temp>
Then can you please try to post here why the support of dot (.) as an alternate option for object designator cannot be added to the Fortran standard?
program main
type :: t
logical :: y
end type
type :: u
type(t) :: eq
end type
interface operator(.eq.)
procedure eq_u
end interface
type(u) :: x, y
logical :: l
l = x.eq.y
contains
logical function eq_u(x, y)
type(u), intent(in) :: x, y
eq_u = .true.
end
end
It seems that x.eq.y is ambiguous, either eq_u(x, y) or x%eq%y.
Using that proposal, x.eq.y would mean x%eq%y. If you want the other meaning, you would have to write it as (x).eq.(y), then it would mean eq_u(x, y).
@FortranFan as you can see, I have put a great deal of thought into this. It definitely can happen, it’s just that it seems highly unlikely given the large opposition to this.
In some sense, it might be a good thing: I don’t like %, and for that reason I do not use derived types or classes much, unless I have to. And that I personally consider a good thing. I also do not like .something. syntax for custom operators, and so I don’t use those either. Again, a good thing for me. (I am half joking here, but there is also a lot of truth for me personally in this paragraph.)
Now the += operator on the other hand, that one I would use. So rather than burning capital on %, I would rather push for +=.
Not really, a long established precedent with many extensions during the tumultuous 1980s, many of which later converged to official Fortran 90, has been defined-binary-op has the lowest precedence, as shown in Table 10.1 in the standard document. There is reason for that, to avoid ambiguity in various circumstances. And it has worked reasonably well thus far, I reckon. And the same can apply going forward.
Note DEC Structure facility that employed dot(.) as object designator preceded the Fortran 90 standard and it gave precedence to object designator reference in structure components. Thus with both the Intel Fortran and gfortran compilers now, x.eq.y will be equivalent to x%eq%y.
I think this change is extremely unlikely to happen if it can be done in a backward compatible way. But if it potentially breaks existing code there is no way the committee will approve it, and rightly so.
% is not an operator so precedence of operators is not relevant. The ambiguity is syntactical. Operator precedence is about what meaning is applied to a syntactically correct expression.
Right, and so when that extension is enabled they are not conforming Fortran 2018 implementations.
If there was a referendum on “%” or “.”, I’d always vote for “.”, but I have to admit that it’d be only for the aesthetic reasons. I wonder how “%” was chosen in the first place?
As someone wrote above, ifort apparently understands “.” as “%”. I’ve found it by chance - copied some code from IDL (where it is “.”) to fortran and forgot to change it in several places. With ifort worked with no problem.
I remember this had been discussed and possibly rejected a few years ago by the committee. The most obvious problem that I can see with this syntax is the issue of /= which already has a meaning in Fortran.