8 ms·
Some of the terse variable names are the result of my adherence to a GMP-like naming convention, which I find easy to read and aesthetically pleasing. The GMP
by chjj 5y ago
Some of the terse variable names are the result of my adherence to a GMP-like naming convention, which I find easy to read and aesthetically pleasing.
The GMP naming convention is something like:
- Pointer/Data - single letter followed by a "p"
- Size/Length - single letter followed by an "n"
So a function declaration might look like:
static void
process_bytes(uint8_t *zp, const uint8_t *xp, size_t xn);
The above function would do some processing on `xn` bytes at `xp` and store the result in `zp` (assuming there are `xn` bytes also allocated here).
A function which accepts more inputs might have `yp` and `yn` also, so conceptually: `zp = func(xp, xn, yp, yn);` or to simplify: `z = func(x, y)`.
- optymizer 5y agoWhich code is clearer? void f(int c) { l.c = c; ... } or void setColor(int color) { label.color = color; ... } Names are more important than matching data types and sizes because they convey intent and meaning better than types.
- matvore 5y agoI just did this grep for single-character function names on the Mako codebase: grep -r '\<[a-z](' . And there were no matches. There were some one-character macros but they were macros repeated dozens of times in a localized area. It seems like what's being proposed is descriptive function names with simple variable names. If the function bodies are short enough (e.g. fit on a single screen) then this seems like a good trade-off to me. IOW, the variable names are symbolic but the function names are descriptive. The short variable names should be clear enough if you understand the purpose of the function.
- jrop 5y ago"Clean code reads like prose" (Uncle Bob C. Martin) This is quickly becoming my goto standard for measuring how clean my code is, and in my case this means ultra-descriptive variable names. I usually code in two passes: first rough things out using single-character/short names, and then go back and use LSP features to rename the variables using the language-aware tools in any modern code editor.
- smt88 5y ago> The short variable names should be clear enough if you understand the purpose of the function. I shouldn't have to read the function implementation to understand its purpose. Code is buggy! If the function has no name or comment explaining what it's supposed to do, I only have the (often buggy) implementation to go by. There is no reason to use terse, non-descriptive names in 2021. It's an awful practice that guarantees easy-to-avoid bugs.
- matvore 5y agoI am saying you indeed should have descriptive function names. I also agree that if the function's name leaves something to be desired then it should be commented. You are conflating function names--global and relatively non-contextual--with variable names--which have limited scope and rely on the function name for their meaning. In the setColor example, I would use setColor for the function name and c for the parameter name (with the caveat that C language doesn't have method names, so my reasoning about context has limited applicability to non-C languages)
- ZephyrBlu 5y agoI don't understand why you chose to prefix your variables with x and y rather than something more descriptive. It seems like x and y are completely arbitrary, which is confusing.
- sanderjd 5y agoThis is a bad convention. Instead of `x` and `z`, you should describe what those pointers are meant to represent. I get that everything is subjective, but some things are actually just bad due to illegibility, and I think it is worth being frank about this.
- chjj 5y agoI disagree. The function name gives context as to what they're meant to represent if you understand the convention. One of the conventions in mako is something like: int btc_tx_import(btc_tx_t *z, const uint8_t *xp, size_t xn); This function deserializes a raw transaction of `xn` bytes at `xp` and stores the result in the transaction `z`. Zero is returned on failure. What would be the alternative here? I suppose I could rename `xp` to `data`, `transaction_data`, `raw_tx_data`, or something like that? I don't think it adds any value and it just takes up extra space, making the code less readable.
- defgeneric 5y ago> I don't think it adds any value and it just takes up extra space, making the code less readable. I agree here. What they want is to be able to get a superficial understanding at a glance of what the code is doing--in other words they want to give the absolute minimum effort in terms of reading. But when you actually read/write the code and understand it, the shorter names are an advantage. IMO it comes down to who the names are really important for--the reader/reviewer who will likely move on to something else in the next hour, or the person who has actually given some attention to the meaning of the code? I think the short names also have the advantage of making the logic of the function body understandable at a glance.
- sanderjd 5y agoYour english language description of it gives some good clues to the alternative: int btc_tx_import(btc_tx_t *transaction, const uint8_t *raw_transaction, size_t raw_transaction_size); Or since clearly `tx` is already a convention for "transaction", it could be `tx`, `raw_tx`, and `raw_tx_size`. And sure, I have no problem with the `p` and `n` stuff, so it could be `txp`, `raw_txp`, `raw_txn`. But from your description, the input is a "raw transaction" and the output is a "transaction". Using `x` to mean "raw transaction" and `z` to mean "transaction" is obtuse. You know that the input is a "raw transaction" and the output is a "transaction", but I as a fresh reader, don't, and your code does not help me understand.
- gregschlom 5y agoThis is silly. The variable types are already giving you exactly this information. Why would you add a "p" when you already have the "*"? Likewise, size_t tells you that this is a size, no need for the "n". Instead, the variable names should be used to convey information that the types alone can't convey.
- chjj 5y ago> Likewise, size_t tells you that this is a size, no need for the "n". How do you differentiate the two input lengths? If I were to rename `xp` to `x` and `xn` to `n`, what should `yn` be renamed to? At the very least, there's going to need to be a `yn` somewhere. It's very common for code to include the type when there are two inputs to a function (even when written more verbosely): e.g. `thing_len`, and `other_thing_len`. The `p`-suffix convention can also save you in a situation like this: int x = 1; int *xp = &x; int y = 1; int *yp = &y; It avoids naming collisions, and further down in the function, you'll be able to differentiate the pointer and the value. I find it very useful. If you write multi-precision integer code in C[1] without this convention, you will end up with an unreadable mess. I certainly wish Torbjörn Granlund were here to testify to this. [1] https://github.com/chjj/mako/blob/master/src/mpi.c https://github.com/chjj/mako/blob/master/src/mpi.c