Archive 17/01/2023.

Math :: shorter aliases for public fields of core classes

freegodsoul

Motivation: When I write a math-intensity code, I want to write it as fast as possible.
Problem: Oftenly-used math classes such as Vector3, Rect, Color, etc, have underscore-postfixed public field names. Instead of writing just “x” or “min”, in addition I have to press a key once or even twice. It’s not big issue, but annoying thing. It slows me down and final code looks ugly little bit.

For example, the code

closest_corner.x = dmin_abs.x < dmax_abs.x ? rect.min.x : rect.max.x; closest_corner.y = dmin_abs.y < dmax_abs.y ? rect.min.y : rect.max.y; closest_delta.x = dmin_abs.x < dmax_abs.x ? dmin_abs.x : dmax_abs.x; closest_delta.y = dmin_abs.y < dmax_abs.y ? dmin_abs.y : dmax_abs.y;
looks mush better for me than

closest_corner.x_ = dmin_abs.x_ < dmax_abs.x_ ? rect.min_.x_ : rect.max_.x_; closest_corner.y_ = dmin_abs.y_ < dmax_abs.y_ ? rect.min_.y_ : rect.max_.y_; closest_delta.x_ = dmin_abs.x_ < dmax_abs.x_ ? dmin_abs.x_ : dmax_abs.x_; closest_delta.y_ = dmin_abs.y_ < dmax_abs.y_ ? dmin_abs.y_ : dmax_abs.y_;

There are many reasons to eliminate underscores in public field names of widely-used core math classes:

  1. The code is shorter
  2. Beautiful
  3. Faster writing and refactoring
  4. Conventional naming (Most of engines and libraries are using simple notation: lowercased without underscores. Examples: Unity, glm, glsl, hlsl)

So I found simple solution for me:
In Urho3D’s class headers I’ve cover the public fields by union statements, e.g. Vector3 member definitions look like this:

/// X coordinate. union { float x_; float x; }; /// Y coordinate. union { float y_; float y; }; /// Z coordinate. union { float z_; float z; };

download: http://gdurl.com/AamL (modified headers only)

Now I can write math code in Unity-style without using external library! Happy coding :smiley:

codingmonkey

but annoying thing
yep, this is pain for me too )
thanks for showing how this may be solved in elegant manner

franck22000

Yes :slight_smile: That change should be pushed in masterbranch !

1vanK

I think, various code style in one project is bad idea

freegodsoul

I’m glad to hear it =)

In one project maybe. But there are two projects:

  1. [Explicit] Urho3D engine
  2. [Implicit] End-User’s project, using the engine

;D

1vanK

In one project maybe. But there are two projects:

  1. Urho3D engine
  2. End-User’s project, using the engine

I just expressed my opinion about sending of PR :slight_smile:

freegodsoul

Ok, i get it)

Enhex

I don’t see what purpose suffixing every member with “_” serves.

codingmonkey

I don’t see what purpose suffixing every member with “_” serves.

this is just rule for member variables
urho3d.github.io/documentation/H … tions.html

then you looked into code you are know what of these variables are member for this class or struct and what not

Enhex

A rule isn’t a valid reason.

When you access member vars you have the class instance prefixing them, f.e. position.x.
When you look inside a member function it’s obvious that it is member var if it isn’t a parameter.
It carries no semantic value.

The only possible case in which it makes “sense” is when you have failure you properly express parameter name in a member function, f.e.:

MyClass::setX(float x)
{
    x = x; // bad. "setting x to x" doesn't make sense.
    x_ = x; // hack
    x = x_; // hack (paramter is x_)
    mX = x; // hack
   [random prefix]x[random suffix] = x // same hack, different string
}

In that example naming the parameter “x” is bad, it’s unexpressive and collides with the class’s x.
Instead it should be something like this:

MyClass::setX(float new_x)
{
    x = new_x; // Setting x to the new value of x. Much better semantics, makes perfect sense
}

Instead of prefixing/suffixing every member var with something, which is a kludge and doesn’t carry any semantic value.
Marking a member variable as a member variable is redundant because the information is already there.

freegodsoul

What you think about using this keyword?
Example:

MyClass::setX(float x) { this->x = x; }

Enhex

While using “this->” is only required inside member functions, it’s still marking member var as a member var and kludging around proper semantics.

TikariSakari

Aren’t underscores used on member names mostly to avoid coding errors. Isn’t that purpose of most coding conventions to write less buggy code.

Something like after doing tons of iterations to a function:

void classA::functionA()
{
   x = 0; // <--- after modifying code for several times, you might accidentally fiddle members value, because you used
            // to create new x-variable in here.
   for( int x = 0; x < WIDTH; ++x) // Do something
   {}
}

edit: Altho this kind of error could be avoided by using const keyword on declaring functions

Enhex

[quote=“TikariSakari”]Aren’t underscores used on member names mostly to avoid coding errors. Isn’t that purpose of most coding conventions to write less buggy code.

Something like after doing tons of iterations to a function:

void classA::functionA()
{
   x = 0; // <--- after modifying code for several times, you might accidentally fiddle members value, because you used
            // to create new x-variable in here.
   for( int x = 0; x < WIDTH; ++x) // Do something
   {}
}

edit: Altho this kind of error could be avoided by using const keyword on declaring functions[/quote]

How does it changes anything? If you forgot to delete test code, you forgot to delete test code. Having a suffix won’t magically send you emails to remind you.

freegodsoul

Good news! I have posted a proposal in “Developer Talk” section, which might to improve math library’s usability: http://discourse.urho3d.io/t/math-library-improvement-proposal/1558/1

Modanung

There may be a valid reason for the rule.

[quote=“Enhex”]
Instead of prefixing/suffixing every member var with something, which is a kludge and doesn’t carry any semantic value.
Marking a member variable as a member variable is redundant because the information is already there.[/quote]
When you learn the underscore is a conventional way of marking member values it receives its semantic value. To me removing the underscore would remove the name’s very semantics.
Also adding accessing member values without underscore postfix as an option makes them unavailable as parameter names.

I like that I can write:

Class::Class(const int a, const int b): a_{a}, b_{b}
…as the constructor’s head.

This can make parameter lists longer than is required.
The way it is works perfect for me and I apply the same logic in my own code.

Enhex

There’s 0 semantic value. Does hgfdsaughdasX mean anything to you? It carries exactly the same semantic value as _x.
The fact you have meta information about the variable doesn’t mean the information is there.

Initialization list works with using the same name, the following code is valid:

MyClass::MyClass(const int a, const int b) :
a(a),
b(b)

[quote=“Modanung”]
This can make parameter lists longer than is required.[/quote]
It doesn’t make anything longer than it needs to be.

yushli

Variable names has semantics. Definitely not 0 semantics with the underscore. Otherwise why not just name every variable a1, a2 ,a3…? underscore at the end means that (at least to me) this variable belongs to a class, not a temporary one. Here I agree with Modanung, it is good to be able write code like he mentions.

Modanung

But ambiguity is maintained in the constructor?s body. Also at first glance this looks like some circular initialisation to me.

rikorin

This code is perfectly normal, I always write it that way in my personal projects. The thing is, good IDE shows local variables in a different color, so there is no ambiguity.
To be honest, I really hate underscores, but sadly there is no better solution for public projects.

Enhex

“_” doesn’t mean anything. You fail to realize that meta information isn’t information.
And in your example I could say “a” means belongs to a class. Is the information there? No.

yushli

As long as you are consistent with using a at the beginning of variables to mean they are members of a class, there is meanings there. That is why we need a coding rule to guide the coding style. As long as they are consistent, there is meanings.
Coding style is very different from people to people, even the same person would prefer different style with time goes. So just pick what one likes most.

Enhex

The information isn’t there, it’s external to the code thus meta.
Coding style isn’t code.

Modanung

You appear to be stating metaphysical impossibilities. Or is it doublethink?

Exactly, but since we’re dealing with shared code: here’s a link to the Urho3D coding conventions.

Also note that the C++ Core Guidelines are “…less concerned with low-level issues, such as naming conventions and indentation style.” for exactly this reason.

yushli

I am quite satisfied with Urho3D’s coding convention. I will stick with it.