protocolbuffers / protobuf

Protocol Buffers - Google's data interchange format
http://protobuf.dev
Other
65.92k stars 15.53k forks source link

Add camelcase support to C++ #971

Closed zefyrr closed 8 years ago

zefyrr commented 9 years ago

I understand that the C++ bindings that protoc generates are google C++ style guide conformant. There are other style guides that recommend camel-casing for member variables.

Would be good to have an option to generate camel-cased C++ code.

xfxyjwf commented 8 years ago

We would like to the library simple and efficient. An alternative API style is obviously the opposite. I see no practical value from it as well.

minyor commented 8 years ago

I disagree (((

targodan commented 8 years ago

As far as I can tell this would only affect the code generation, so not a big deal right? Or does the protobuf lib rely on the naming of the setters and getters in any way?

Assuming the lib does not rely on setter-naming, all you'd have to do is not convert message members to lowercase, capitalize the first letter and remove that nasty underscore. I don't think this would be a lot of complexity added and it would make programmers with different style preferences much more comfortable using protobuf.

After all I am pretty certain you guys are very strict on you style guidelines. So, if you want your project to have both strict guidelines but also use camel case for getters and setters, you basically can't use protobuf right now.

fileoffset commented 7 years ago

I also fail to see how this would make the library less 'simple and efficient' xfxyjwf.

Snakecase is a lesson in how to make your code unreadable. It's a pretty terrible style to enforce on all of your C++ users.

There should definitely be an option to enable camel case, it is hardly a difficult and breaking change and wouldn't require more than a footnote in the C++ Protobuf docs explaining the option.

The practical value is that people wouldn't have to adjust their code formatters and saniters for a different set of styles to their local coding standard just so they can use protobuf. Oh, and all the users who don't use snakecase by default (everyone I've ever worked for) wouldn't have to mix the two styles together.

xfxyjwf commented 7 years ago

@fileoffset It's probably not a big problem for small projects, but for Google where we have all teams working on a single code base, even a single added accessor could have a significant cost of engineering time. That's because many engineers will have to learn an alternative style of naming. It becomes even worse when different parts of the code base use different styles with many people wasting time on protos when they call the wrong accessors. It's much better to enforce a single consistent naming style and as such we generally don't want to introduce any option that can affect public APIs.

Whether snake_case is good or bad is a subjective matter. In Google we universally use snake_case for accessors/mutators. I don't think that will be changed any time soon.

For code formatters and sanitizers, they should be taught to honor existing convention for third-party code. That's how they work in Google. We depend on a lot of third-party libraries, and we do not try to force others to follow our style.

fileoffset commented 7 years ago

xfxyjwf I understand your position but I think we have a misunderstanding. I wasn't suggesting that everyone in Google suddenly change their coding style. I was merely asking that you add the option to output camel case accessors in protobuf3.

This wouldn't affect Google code, or Google projects, since you have a different style requirement and could enforce the option being set to false for all internal usage (through pre-commit hooks, auto formatters/sanitizers, review tools, and CI tools). Unless you think the camel case option would be too enticing for Google coders to resist? :)

"We depend on a lot of third-party libraries, and we do not try to force others to follow our style." - unfortunately, that's exactly what you are doing with protobuf.

xfxyjwf commented 7 years ago

As I said in my previous comment, we don't want to introduce more options that can change public API. We care about consistency more than whether it's snake_case or CamelCase. If we start with CamelCase, I will be objecting adding support for snake_case right now. Assuming this won't affect Google is just a wrong assumption. Any public API/option added in protobuf will eventually be used by someone in Google even when there are better alternatives. Also as Google owns lot of opensource projects, there is no way a change in protobuf can avoid affecting Google even after we strip it from our internal code base.

Whether to use snake_case or CamelCase in your own code is up to you. I don't see how protobuf can force you to define your own methods in snake_case. If you are saying you don't want to call any snake_case methods even when they are provided by third_party libraries, I guess you will have a hard time using C++.

fileoffset commented 7 years ago

All good points.

"If you are saying you don't want to call any snake_case methods even when they are provided by third_party libraries, I guess you will have a hard time using C++."

Usually when I integrate a third party library, i wrap its functionality in a small library to make it easier to swap out at a later date. This gives a lot of flexibility and can usually be done with little effort. You can adjust your linters and formatters specifically to handle that library, while your main application can stick to it's stricter rulesets with no modification. Using this method, I can swap out, say, a zlib compression library with an lzham one, with only a small, localised library rewrite. If the interface is well designed, you can often get away without any modifications to your application code. Just recompile and link.

The one type of library where this mechanism falls down, is de/serialization libraries. Due to their nature they tend to wrap accessors and the actual de/serialization of messages. Messages that usually get passed around. Sometimes it is possible to wrap them at a high level, but trying to do the same for every accessor method is not feasible. This is why Protobuf does code generation.

If you, at a later date, decide that your serialization format isn't working well, or the schema format is clunky, or it isn't as efficient as you thought, or you just want to test another out, you can't easily do that. Even if you can easily convert the schema from one to another, you then have to find every single message reader/writer/accessor and update the call sites, usually by hand or with a bunch of tricksy regex.

As an example, try converting any non trivial project from using, say, Cap'n Proto to Protobuf. If the two serialization formats generated similar accessor code, the amount of code changes required would be vastly minimized. As it is, if you try that today, every single line of code has to be updated, despite the similarities of the two libraries.

Imagine swapping serialization libraries without changing your client code! I realize this is a pipe dream but it is a real life problem that is felt by developers (and their managers) every day.

samsta commented 11 months ago

If consistency is paramount, how can this be explained, then:

image

(taken from https://protobuf.dev/programming-guides/style/)

Java already does what the OP is asking, so it's a little frustrating we can't get the same for C++. We might just have to write our on extension using a plugin for protoc !