What's your experience with using % for accessing object members?

Hello everyone,

What is your experience with using the % operator for accessing an object’s data and procedure members?

Apologies if my complaints seem rude, that is not my intention. I just didn’t have a good experience with using %, and want to voice my experience.

Instead of %, I configured my IDE to show it as either -> or ::

I personally don’t like %, mainly because it makes the code difficult for me to see.

It might differ from person to person, but I have a hard time finding the % character on screen as in,

this%NumCells = abstractKey%CountTotalCells()

Some devs use a space to make things more legible …

this % NumCells = abstractKey % CountTotalCells()

This is somewhat better, but makes us waste lots of white space, and also complicates things when we have other symbols in the equations such as

this % NumCells = abstractKey % CountTotalCells() + oldCells * 2 + this % CountNewCells()

I don’t know if others have faced the same problem, but since we need to have space around %, the equation becomes more spaced out, and makes it difficult for me to see.

Right now, I just simply use a regex search to replace all occurances of % with -> like in C, so the code becomes more easier for me to read.

In neovim editor I can do this easily with the search and replace command :%s/%/->/g

With the changes, the code becomes for a moment …

this->NumCells = abstractKey->CountTotalCells() + oldCells*2 + this->CountNewCells()

I have also tried with another option :: which looks very good to me, and I prefer it to be the best option for me.

this::NumCells = abstractKey::CountTotalCells() + oldCells*2 + this::CountNewCells()

This is a hack, and is not something that I would’ve wanted to do, but it’s necessary for me to being able to see the code better.

The changes can be reversed with a single key press of u, so they don’t change the code. In future I’m trying to use an overlay technique that would prevent modification of the text, and would simply show -> or :: on top of the % instead of replacing it.

I don’t have anything else to say, as this is just me sharing my own experience with using the symbol, and I don’t know if others also have similar experience to me, or not.

Thanks

2 Likes
autocmd FileType fortran syntax match FortranConceal '%' conceal cchar=→
autocmd FileType fortran  inoremap <buffer> ; %

you can try this in vim/neovim . is a digraph, <C-k>->

For other languages, . is a default one to get members, it is easy to press, but %( <shift>5 ) not. So I map; to %.

2 Likes

Can you configure your editor to change the color of that character?

In fortran, :: is already used for declarations (integer :: i), and . is already used to delimit operators (.and., .or., .my_op.)

1 Like

@aerosayan ,

This has been discussed often over the last few years on several forums but know % part-ref has been a feature of the Fortran language standard since the publication of the Fortran standard since the Fortran 90 revision back in 1991, over 30 years ago.

Thus an IDE option you are trying is your best bet in terms of anything immediate. Perhaps you can force some syntax highlighting with a bigger, bolder font?

The influence of C++ implies the other reference option is . (period) but I am not sure that is any better in terms of visual distinction in an editor?
image

1 Like

@aerosayan that’s a long standing issue that I also have with Fortran. I created an issue with many ideas here:

Some prior discussion at Discourse here and here.

You are bringing some other good ideas to use either -> or :: both of which I also feel are more readable.

Now when LFortran has a full parser (beta quality), we can try some of these ideas and see if it is possible to implement it robustly. I think just using . is the best, but it’s a bit tricky to implement, see the issue.

2 Likes

Not a problem for me as the % character appears in a different color in my text editor (Kate in KDE).

2 Likes

Like many others I don’t like much % for accessing the components. However I don’t feel that this->component or this::component are much more readable than this%component. I mean, they are more readable, but not that much to me, and not as much as this.component. Moreover I’m not sure that :: would not be ambiguous in some cases:
integer::a = 2
could interpreted classically as the initialization (+implied save) of an integer variable a, or as an assignment to the component a of an object integer. Yes, the latter would definitely be a bad practice, but the parser would have to disambiguate that.

I think that the change is worth the effort only if the dot is chosen. A way to solve the ambiguities would be through a directive, similar to implicit:

component_separator dot except(intrinsic,.foo.,.bar.)

at the beginning of a programing unit would mean that . would be interpreted as a component separator, except for the intrinsic operators (e.g. .and.) and for the user defined .foo. and .bar.operators. Other specifiers in except() could be user (all user defined operators) and all (all operators).

That way, it would be the full responsibility of the programmer to define the precedences and remove any ambiguity for the parser.

Edit: still, there is a difficulty… If foo is component , a.foo.b would be broken if a new intrinsic .foo. was added to the language at some point and if except(intrinsic) has been specified

1 Like

Anyone is free at any moment to define:

interface operator (.foo.)
! ...
end interface

And it has been used in a smart way in a couple projects I have seen. Therefore, sadly it seems that dot would be hard to implement in a way that does not clash with custom operators.

% sucks a little bit, you know what, in my opinion, sucks a lot? Inability to do this. While percent is an aesthetics issue, the other largely limits usability of the language.

1 Like

I also think . is best, but if that doesn’t work, how do you feel about ..?

I have noted down few of the ideas I had, and ordered them based on what I think would be the best to worst.

.. is not used in Fortran (AFAIK), and it is extremely easy to type and see.

.. also allows very compact notation, which is good for writing complex equations.

    ! Object
    type(MyType) :: x

    ! Accessors (ordered from best to worst, in my opinion)
    x.y.z     = 123
    x..y..z   = 123
    x::y::z   = 123
    x->y->z   = 123
    x&y&z     = 123
    x & y & z = 123


1 Like

.. is used as a range in many languages (Rust etc.), so I would be against it. x..y looks too much like “range of numbers between x and y”.

Same about &, since it clearly is a reference for most people looking at it.

obj%p%x(3)%result
obj`p`x(3)`result
obj::p::x(3)::result
obj->p->x(3)->result
obj.p.x(3).result – no (can be confused with (obj) .p. (x(3).result))

` is my favorite alternative, but overall I do not think that much can be improved here, dot being out of the game.

I think it would be okay to define semantics of a symbol in a way that clashes with other languages, as long as it solves a problem in the current language.

.. definitely has other meaning in other languages, and so does ** and ::

In C++ :: is used for scopes, but while coding Fortran we can understand that :: is used to declare variables.

Similarly, I would assume that .. will not cause confusion, if Fortran only uses it to access objects, and uses something else for defining ranges.

If both features need to be supported, then accessing objects needs to be more user friendly than defining ranges.

For defining ranges, I would support range(1,n) instead of 1..n

It is not exactly a problem. There is no problem with % other than me and you do not like it. From the objective standpoint it works perfectly. Unlike many features in Fortran that are straight-up broken by design.

:: makes much more sense, since it is used in a sort-of similar way in C++. But worth the effort? In my opinion, no.

2 Likes

I agree.
And introducing a second syntax for the same thing would just add confusion in my humble opinion.

5 Likes

Fortran does have many different syntaxes for the same thing.

The language itself changed from being fixed form to today’s modern free form.

At some point developer experience becomes crucial enough to allow improvement of the syntax and the language.

Although, yes, I agree that this modernization effort should be done in a conservative manner.

2 Likes

@aerosayan ,

When you use " difficult to see" as a basis for your argument but veer toward ., which is quite difficult or worse for anyone facing actual physical visual challenges, then it is not much of an argument.

It’s true that I enjoy using the [ ] array syntax instead of the strange (/ /) :grinning: (although I guess the second one is probably from a period where there was no [ ] on keyboards)

1 Like

Here’s an extremely zoomed view of a section of pseudo-code.

code

It is well known in typography world that we don’t read the words directly.

We read the difference in their height and width.

Even though . is the smallest of them all, it creates a difference in height that makes it easy to see. If it was difficult to see, then many famous languages like C, C++, Python, wouldn’t have used them, and the users would’ve complained about it for years.

Now, consider the % in car%StartEngine()

It creates a block of visible imbalance around r%S that has no space or difference in height, which makes it the worst possible option for visible legibility.

Even though there’s a difference in height between r and S, the % in r%S completely hides it, and makes it difficult to see.

If those of us with good eye sight find % difficult to see, I think it’s fair to say that actually % is the worst for visibility, and . would be an improvement.

1 Like

No, there is no basis for this whatsoever, there is a better argument to be made for an implicit bias given the heavy influence of C-like languages where the C language basis carried forward but there is no evidence there was any inclusivity consideration toward the visually impaired in the design dating back at least to 1970s.

1:n is already the syntax that defines ranges for array slices and in control structures like do concurrent and where.

I’d like to have it to generalized as in Matlab, i.e. x = 1:n would mean x = [(i, i=1,n)]

4 Likes
this_element%foo_bar%val
this_element.foo_bar.val
this_element..foo_bar..val
this_element->foo_bar->val
this_element::foo_bar::val
this_element^foo_bar^val
this_element\foo_bar\val
this_element~foo_bar~val
this_element#foo_bar#val
this_element|foo_bar|val
...

I find that a|b does well

2 Likes