New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
style guide: switch to snake case for functions #1097
Comments
There are actually quite a few places where the std lib breaks formatting guidelines or is generally inconsistent. For example, many fields in the structs produced by I think it is just a case of being pretty low on everyone's priority list until zig nears 1.0.0. |
I would also want to standardize names (printAlloc vs allocPrint, isXXXX setXXXX getXXXX findXXXX) and common param orders (ie is alloc always the first param except when passing self). Also the stdlib should set a good example and use enums judiciously even for simple flags. |
I am amending this proposal with how to handle initialisms and acronyms in TitleCase things. In summary: Don't mix-mangle the case of initialisms or acronyms. Before:
After:
If those things were functions:
Reasoning: Our previous camelCase style has flaws:
This is unfortunately a widely breaking change and feels annoying to update code just for an arbitrary style decision, so my suggestion for how to roll this out, if accepted, would be to wait until we have the ability to do identifier-renaming (the feature that some IDEs provide) and it works well. That feature would ease the burden of transitioning a codebase from one style to the other, and we could even provide a script for people to run which would make the changes automatically (the script would have listed all the std lib identifiers that changed; it would not arbitrarily change users' own identifiers). |
I came here to issues hoping to find there was a plan to fix the style guide. Awesome to see this will be addressed. |
The ayes would seem to have it (good, IMHO). @andrewrk For those of us busy building Zig libraries, it would be rather helpful to know soonest whether this proposal--per the examples you gave above--will be accepted or not, so as to not have to frustrate downstream users with massive renames later on. |
Note to future self in about 2 weeks: don't postpone this one to 0.8.0 make a decision!! |
Right now the style guide helps to see when something is a function or a variable or a namespace, with this only |
That's true, and was the main motivation for status quo style, but it doesn't work for functions with only 1 word in them, so there was always that cognitive dissonance. BTW did you know that ZLS+vscode has semantic highlighting? It makes functions a different color, so you don't even have to hover. |
I haven't tried ZLS yet. Before i mostly used Java which has similar preferred style to Zig and i not even once had a problem naming a function that has an acronym or an abbreviation (for me |
While semantic syntax highlighting is nice it requires editor support and the experience for non LSP users is degraded. Basic completion methods work rather well the minute the second word is hit which would be made less effective by snake_case matching functions, variables, and so on. The shape change is, in my opinion, much easier to follow as TitleCaseTypes clearly separate from regularFunctions and variables_with_snake_case. On the topic of semantic highlighting, switching highlighting based on what you want to focus on as in https://buttondown.email/hillelwayne/archive/syntax-highlighting-is-a-waste-of-an-information/ would (arguably) be better with a shape difference since the highlight focus changes based on the task and removing the difference between functions and other things for the other modes. |
FWIW I'm a fan of |
Talked with @andrewrk and @thejoshwolfe. We decided to keep approximately the current naming conventions, but clear up any ambiguous cases with the following specific algorithm: To produce a name, first write out the name all lowercase with spaces. Then, consider the type of variable:
If at any time you would delete a space and the character to the right of the space is a number, instead replace the space with an underscore. Some examples: This transformation is both unambiguous and invertible. |
@SpexGuy any recommendations for if the name starts with a number? |
Uh, taking off my "official" hat for a second, but maybe don't? I don't think it's unreasonable to disallow identifiers which start with numbers in the standard library. |
@SpexGuy one such example might be crypto functions; at the moment we are going to have: pub const aead = struct {
pub const aegis = struct {
pub const Aegis128L = @import("crypto/aegis.zig").Aegis128L;
pub const Aegis256 = @import("crypto/aegis.zig").Aegis256;
};
.....
}; It would make a lot of sense to have |
AEGIS128l is the name of the algorithm, not "128l". Splitting that name wouldn't make sense, and would break grepability as well. |
Oh, yeah, if you would capitalize a word and it starts with a number, leave it as is, and the space to the left of it will always become an underscore because it's a number to the right of a space. So under these rules it would be |
Identifiers can't start with numbers unless you use
|
I realize this proposal has been closed, but I started zig a while ago and I find the I don't want to start a debate, but I'll just share my experience as a developer. In short, I can read Apparently, I am not alone, I found a study about this https://ieeexplore.ieee.org/document/5521745 but I do not know how significant this is. Again, I do not want to start a debate, nor even think of changing anything in zig. But I do use |
Whatever is the end result, what I can't deal with is the mixing of the two concepts. It's too hard on the eyes to beReadingThis and_suddenly_this and it's specially weird_when_they_are.combinedTogetherAndWhatnot. Just the code samples have enough examples of cases where the two are mixed together and it's very visually confusing. |
agree, i support snake_case or go all out with CamelCase since those two are the main two styles followed by many c programmers, mixing 3 styles is bad idea What i don't agree is with delaying this much more, since the refactor won't be automatic since sometimes what seems good in camelCase doesn't with snake_case, like for example getters, which usually are |
If you allow me to bikeshed a bit here, here's my take on it :) One of Zig's primary goals is to interop with C and be another system's programmming language. As such I think adopting conventions that are compatible with those would be beneficial since snake_case is the de facto standard for C, C++, Rust and their standard libraries (even though some C/C++ libraries have opted to use another style). I personally would propose the following style:
// Functions
fn LinkedList(comptime T: type) type;
fn remove_duplicates() T;
// Variables
const MAGIC_NUMBER = 0x4e93fd;
const immutable_value = get_value();
var mutable_value = get_value();
// Enums and Unions
const MyEnum = enum {
OptionOne,
OptionTwo,
};
// becomes pascal case cause you have to unwrap it like an enum
const TaggedUnion = union(enum) {
FirstValue: i32,
SecondValue: f32,
};
// just plain old unions so no PascalCase
const RegularUnion = union {
first_value: i32,
second_value: f32,
}; |
Enums are constants. I'd rather see them use SCREAMING_SNAKE_CASE instead. |
@RaphGL also, constants should use SCREAMING_SNAKE_CASE (or snake_case, whatever, a single style is what I mean) no matter whether they're known at compile time or not. Outside code shouldn't know what your implementation is like and shouldn't have to change if you change your implementation either. That's also likely a good thing for your own internal code too. I'd hate to review an MR with 200 changed lines where the only actual change was making COOL_CONSTANT into cool_constant because it was a literal but now it's taken from a function or something. And that's just for stuff you don't export. For stuff you do, that'd be an instant compile error for anything that uses your library and, except for specific cases, external code really shouldn't care where you took the value from. A constant is a constant. |
The problem with having different styles for different classifications of things is that it becomes very unstable under refactoring and whatnot too. Made a variable inside a Union constant? Change its casing, now change every place that uses it, etc. now remember you broke every external thing that touches that variable (now a constant) because of that. Or don't, and now you have an inconsistent style and it doesn't make things obvious anymore. |
Yeah but zig makes no distinction between constant and immutable value and most of the learning resources recommend making things immutable whenever possible so using SCREAMING_SNAKE_CASE would litter your code with capitalized variables.
Yeah that might be a possibility if it were a comptime function. This is also only an annoyance because ZLS does not support bulk renaming yet and for people that don't use an LSP (in the future).
If you're exporting it, people don't care how that constant is built just that it's one, so making it screaming case is ok. I only made this distinction for constants because seeing screaming case everywhere would be too noisy. I'd be fine with that distinction personally but your criticism is very valid, I'm not sure how often this would be an issue if you just make all user facing constants SCREAMING_CASE. Feel free to point out more flaws in my suggestion :) |
I think the screaming vs snake case thing is getting a little bit off topic (but I'll pitch in that I prefer snake case for all the constants, enum variants etc). This issue is about function names. |
It seems there some consensus on renaming functions to For constants, I think further discussions is necessary, especially when we consider zig notion of constant to be different than it is in other languages because of |
Ok, to sum up, what could be said that most of us agree to
Let's close this and start discussion over how to do it, which in my opinion there is no painless way |
@cdecompilador I don't think this issue needs any further summaries, @kuon did it well. Types in particular are out of scope, and I don't think there is agreement on |
This comment was marked as spam.
This comment was marked as spam.
Has anyone guesstimated the breaking change impact on std lib if it itself were to reflect the proposed changes? I think it’s standard practice to seek inspiration from std libraries when trying to understand what good looks like. left unchanged it would be weird to have a recommendation that the std lib itself doesn’t follow. |
Guesstimated |
I just threw together a little script which automatically converts all |
It would be a nice feature of |
I think that after 5 years this issue should be closed. It is hard enough already getting Zig code samples out of the various LLMs / GPTs, and such a fundamental change this late in the project is going to set us back a long way. |
Optimizing Zig to be a language LLMs can write effectively is quite possibly our single lowest priority. Zig is a language written for humans; not for glorified autocompletion engines. To be frank, if one is seriously trying to get ChatGPT or the like to output good Zig code, naming conventions will be the least of their concerns. I'm not sure what comment gave you the impression that this proposal exists "to try to copy Rust". The proposal exists because a lot of people believe this change would improve readability of Zig code and/or simplify the style guide. Being in v0, Zig is currently an unstable language. Once it reaches v1, the intention is that it becomes highly stable, both technically and in terms of conventions; but for now, major changes to the language, style guide, conventions, etc are all perfectly allowed, and even encouraged if they are clear improvements. |
Closing again. I toyed with this in https://github.com/andrewrk/autodoc and found it to tend to cause unfortunate shadowing that was not really the case before. That said, it's just what we're going to do in the standard library - individual projects can obviously do their own naming conventions. And sometimes projects doing their own naming conventions can be handy in its own way, the human understands that one area of code has this vibe, another has that one. I'll also consider changing the naming conventions of builtin functions. For whatever reason, camelCase in builtin functions just feels wrong. I often mistype |
I suppose with comptime it's possible to convert function and constant names (but not globals) from one convention to another when |
While I understand @andrewrk choice, I think that if there are naming conflict in the std lib that are prevented only by different case it can be a little bit confusing and feels "brittle", and maybe it should be addressed in another issue.
At any rate, it is the only important thing to me. I use snake case in JS and I have no problem with std lib and DOM lib being camelCase. As long as zig makes no technical decision on the name, it is OK. I know I did push a bit hard for this to be implemented, and I am sorry if it was too much. In the end it is only a personal preference. Cheers. |
It is a preference but beyond personal as the comments and reactions in this thread show. I fail to see the current resolution being consistent with it all or your summary/meta-analysis. (My personal opinion is that there should be no camelCase at all; and no SCREAMING_SNAKE_CASE either on a side note). |
ziglang#1097 is closed. > it's just what we're going to do in the standard library If it's what we're going to do in the standard library these two functions should probably follow suit.
I understand the general rule does not use
snake_case
for function. Why doeql_slice_u8
andhash_slice_u8
break this rule?The text was updated successfully, but these errors were encountered: