Wouldn't it be a cool idea to add to the "get" functions capital functions in the juce codebase?

This! Anything else is just an attempt to change the technical standard carved already in stone :wink:

1 Like

This goes both ways.

If you make a clearly ridiculous proposal, expect ridiculous responses. Life is serious enough already, why not have a little fun once in a while?

ps. I know it’s not “fun” to be the butt of jokes, but if you can’t laugh at yourself then one should consider if it’s fair to laugh at anything.

5 Likes

I don’t think it was a clearly ridiculous proposal (as long as it didn’t mean the juce team should go refactor their whole codebase) even if I don’t agree.
Lot of workplaces have this discussion.

@daniel Yeah, you convinced me a while back already. Still in a larger sense it’s good to think about code readabilty.

1 Like

I am surprised nobody yet mentioned the real reason why we have get/set prefixes in the first place! In other languages you can have getters and setters use the same name, but in C++ it is impossible to write, for example:

String userName();
void userName (const String& name);

Which is roughly how it works in Objective-C and Smalltalk. It makes sense because method names (selectors) are sorted alphabetically in most development tools. I sorely miss this with C++, where not a single IDE provides any meaningful class navigation and refactoring.

Why is that impossible to write?
The return types can differ on an overload set (that’s how templates work) and the argument will determine what function will be called.

Am I overlooking something obvious?

That’s what I also expected.

I don’t remember exactly the circumstances that made me come to the conclusion, but it definitely didn’t work with bindings, i.e. taking the address of a member function requires the name to be unique (unless you know a better solution). That was while working on a GUI framework that needed getter/settter bindings.

It also didn’t work for some other reason I can’t remember right now, apart from a clash with the member variable name (can be prefixed).

So “impossible” is too strong here. Thanks for pointing out.

Well I can’t think of anything wrong with it if you were to use modern C++ and std::function etc. to bind things: Compiler Explorer

regarding the binding, you just need to do a static cast of the function with its signature

for example
static_cast<void (Path::*)(float, float, float, float, float, float)>
or
static_cast<void (Path::*)(Point<float>, Point<float>, Point<float>)>

so you can disambiguate overload

Thank you.

if anyone thinks this looks modern and cool, nice, we agree:

class ListComponent : public juce::Component, public juce::ChangeListener
{
public:
    ListComponent();

    size_t Size() const;
    float RowHeight() const;

    void setRowHeight (const float& newH);

private:
    std::vector<std::unique_ptr<RowComponent>> rows;
    float rowHeight = 0;

    void changeListenerCallback (juce::ChangeBroadcaster* source) override;
};

If not, I won’t argue espacially with people using an inappropriate language.

For those nice people interested in new styles:
The capital comes in because the lower one does not work with the member (here rowHeight). Set is fine so we make clear that we change the state of something, it can stay lowercase. Arguments against get I allready dropped. list.RowHeight() has less noise than list.getRowHeight(), it looks nice.

We know now that changing this in the JUCE Codebase would trigger a shitstorm, so from that point of view it’s a bad idea to do so (even so the old getters could stay in for some time and changing this would not take that much time).

Setting aside the dispute about lower/upper case, the reason why I’m not particularly fond of the idea, is that to me the member variables should be nouns that express what their value represents, while member function names should have a verb in them, that expresses what the function does on the object it’s called upon.

I know that there are exceptions to this rule, even in JUCE codebase, but having a member function called XYZ() to obtain the value of xyz, and a function setXYZ() to set it, seems like introducing by design an inconsistency in that naming scheme.

On the other hand, I think that rowHeight() wouldn’t be out of place as the name of a free function that accepts a ListComponent as argument and returns the height of its rows. But that’s because it would be more in the spirit of how a “mathematical” function is written: like cos(angle) returns the cosine of a given angle, then also rowHeight(list) would return the height of rows of that given list.

Following this last reasoning, a while ago I implemented some free functions called height(), width(), bottom(), etc. with overloads to accept Components as well as Rectangles, to make code more readable in certain parts, for example:

right (padding) + width (button)

looks more readable to me than

padding.getRight() + button.getWidth();
4 Likes

and this is the convention for C++ in nigh on every codebase out there.

Someone could try to change this, but it feels a little bit “old man yells at cloud” pointless. Curmudgeonly old timer coders won’t change their ways. Having to constantly change mental mode depending on which style is being used in the code you happen to be working on adds needless friction, even worse would be using the “new” style along with a library that uses the “old” style. This is why there are conventions and people stick to them.

Probably the most pragmatic approach would be a “linter” that changes these method names for you. This is why I’ve never got into arguments about how code should be formatted; just write the code however the hell you please and apply the linter to make it fit whatever style the team you’re working with has arbitrarily chosen.

1 Like

I’ve always disliked pure getters (pure setters barely need to exist). The get prefix makes it seem to me that something is done, when it’s merely an access mechanism. I don’t like verbosity, especially when it’s purely grammatical -to my cognition, it obfuscates structures and makes it all more noisy. So in my own stuff, I do avoid the prefix (I still start the name in lowercase), but then I’d have a clash with the variable name, so I usually suffix all privates with underscore, which I find less obtrusive. Still, I wouldn’t do this in a shared project, let alone a public API. What works for a single person doesn’t necessarily work for a lot of them -a public interface needs to be clearly communicative.

1 Like