The first professor who I took a programming class from told us that anytime we needed to indent something we should be asking ourselves if we needed to create a new function and most times the answer would be yes.
Depends on the context/language I think. Splitting a block of code into a function gives it a greppable name that (ideally) succinctly describes the point of the block. You can have that block just headed by a comment inline to try and do the same thing, but comments are extremely prone to getting ignored and left to grow outdated when the purpose of the code around them changes. It's easier for the reader to just mentally abstract away that block if it's separated into a function. And if that block is worth testing, it's much easier to do when it's isolated into its own function.
There's reasons to keep the block inline too--like if you're working in a more resource constrained environment, or if the block isn't really isolated/self-contained enough to cleanly abstract away, or if the block in question isn't really doing anything substantial. But I wouldn't say that you should only abstract away code into functions to save yourself from literally copy/pasting the lines in multiple places.
You could argue that it's better to make the function; the compiler will probably inline it if it's only used once, and it helps avoid having the logic duplicated if it's needed again (or by lazy copy/paste programmers).
My point is not performance but that a function used only once is likely just contributing to one conceptual block of code. But now it's artificially divided up and one has to jump around to understand that code as a whole. There are exceptions of course but blindly adding functions to avoid indenting is probably going to lead to a harder to follow solution.
in js you can just leave the named function inline. i sometimes create functions that call themself so that i can just move it out if the code needs to be repeated, and i dont have to clutter the scope with more variables. with es6 js got bracket scoping, but i still prefer function scope and closures.
I think it is a bad idea to apply that rule to all programming languages though. If you are doing Java, for example, and have a function inside of a class, and a loop in the function, putting a condition inside of the loop would violate the rule, and that is a pretty common thing to do.
Because Java is a kingdom of nouns, and for the most part (method handles, which are just fancy reflection objects, aside), you can't name a function without creating a closure.
Anonymous callback:
Foo.foo(() -> bar());
Named callback:
private final class MyFooDelegate implements FooDelegate {
@Override
public void doFoo() {
bar();
}
}
...
Foo.foo(new MyFooDelegate())
several indentations in js is most of the time linear async flow, while in other languages it usually means branching complexity. while an experienced js programmer can deal with async code and avoid the so called callback hell, nesting the callback doesnt make it any harder to understand, just harder to test, debug and refactor.
I think these guidelines are something every C programmer should atleast have read and reflected about.
I've been coding according to these guidelines for quite a while with some minor modifications:
Always use curly braces (especially when you're not alone coding in the codebase as it allows for easy modification without code ending up out of the intented scope).
80 char width; well I don't follow this one as I really do prefer long lines over broken lines for readability.
Other than that I think these guidelines are great and offer consistency and easy to read code, in my opinion.
Depending on the verbosity of the name, even a no arg function might exceed 80+ chars. We have a few instances of test convenience functions in our non-C code base, though they're exceedingly rare.
Ahhhh I see. Nortel had that coding guideline actually. Just in their case, the first argument followed the parenthesis. The second argument (and the rest) followed the first argument column.
Those are good reasons. The reason I accept an 80 char limit, even if I prefer longer lines, is because it affects everyone else. Short lines will always fit, in every editor, in every terminal, over ssh, etc.. Long lines, anything over 80, will compromise some workflow somewhere. Long lines will generally mess with someone's flow, and they become more inconvenient for more people the longer the lines get.
True, thanks. Did you not know what I meant? "in every terminal, over ssh". Line length can affect my use of grep as much as it can affect remote vi sessions. I'm not talking about the protocol, I'm talking about the existence of multiple workflows that are all affected by line length conventions. The edit/compile cycle in your favorite IDE isn't the only consideration, and I'm not the only person to consider when I decide how long my lines should be.
SSH is only relevant in that it might provide an additional motivation for operating in the terminal, in some cases.
That said, yes, I was picking a nit mostly because the nit itself amused me (and I hoped it would amuse others) - it wasn't meant as significant criticism of your post.
You can say that enforcing an 80 character line is outdated, but I often find myself looking at code reviews in GitHub on my smartphone, and it dramatically improves readability in that environment.
I haven't said it's outdated though just that I don't always follow it. Desktop Github version seems to show 125 chars (including -+) and on my iphone I'm below 50 char width by default.
I just prioritize to have "readable" code in my editor as first prio, second would be sites like Github on desktop and if it works good on a mobile phone that's a plus but not high prio for me.
(To be honest though I do actually glance through some Github reviews on my phone, but since it's pretty limited I do find myself thinking that I should get to a computer and do a real review there instead.)
Are there any languages where code-style is required to be a certain way? or it won't compile. I mean full authoritarian about everything, not just based around white-space like python.
Some have little that can differ, such as assembly, but not that I know of at least. Some define a "proper" way, though (PEP-8, gofmt, and doesn't rust also have a rustfmt?).
I think the original question was about full-on enforcement of style rules as grammatical rules, by the compiler, as proposed by Ken Arnold in his 2004 essay Style is Substance [1]. AFAIK nothing like that is remotely on the cards for rustfmt.
Yes, old fixed-format languages like FORTRAN and RPG (the older versions). Everything had to be written in specific columns, due to their punched card heritage.
Fixed-format FORTRAN isn't actually that rigid. The first six columns have special semantics, but apart from that, the compiler is not going to enforce a certain style.
Go uses gofmt, which pretty much achieves what you're looking for. Lisp code, emacs generally will generally just clean up idiomatically though that's less what you're looking for.
This is where Go really dropped the ball. They had the perfect opportunity to move lint and fmt (and vet and the rest) into the compiler. I don't for the life of me understand why they did not.
Many teams configure their CI systems to fail builds if they don't pass style checks. This can be great if there's some situational flexibility since no autoformatter is smarter than a human that knows the code, but terrible if there's a formatter (like prettier) that defines only one true format and sometimes gets things horribly wrong.
> A C programmer would call that variable tmp, which is much easier to write, and not the least more difficult to understand.
Yuck. Abbreviations are usually bad. For one thing, people tend to pick different ways to abbreviate things so an hour later when you're trying to grep for where the variable was used you have to try to remember whether the variable was written tmp, temp, or temporary.
In this example, "temporary" is probably the least useful thing to know about the variable, since most variables are temporary. How about "counter"?
Short idioms are essential for concision in specific domains though.
My favorite example: I was writing some graphics code recently, and some reviewer said: "I don't understand this uv abbreviation that appears all over the code. Please expand it."
headdesk.gif
(For those who aren't familiar: u and v are conventional names of texture coordinates, like x, y, and z are conventional names of spatial coordinates. There's no abbreviation to expand.)
I used to use x and y as my generic loop iteration variables until I worked on code that involved two-dimensional coordinates, and suddenly x and y had very specific meaning.
I skipped to i and j, but I am certain there are mathematicians out there who find that confusing, too.
I guess, it's about context, too, at least a little.
> I skipped to i and j, but I am certain there are mathematicians out there who find that confusing, too.
IME it's pretty standard in most of mathematics to use "i" and "j" as index variables when e.g. doing sums and products over indices/sets. (Though I suppose you could be talking about the use of i, j, k as axes?)
I think abbreviations make sense if the abbreviation is better known than the full name, or if it's standard jargon in the problem domain, or it's used so frequently in the program that it can be considered a convention. But using abbreviations just to save some typing makes life difficult for newcomers to a project and can be a source of bugs.
Not really. Go also encourages short, concise names, and it seems to work pretty well... or at least not be causing significant headaches so far as I can tell.
Why would one be forgetting and grepping for tmp? That's the kind of variable that would be inside a function (so max one or two screenfuls, according to the guidelines here), and more realistically would usually be declared and used entirely within the same block of a dozen or so lines of code. Nobody is going to forget whether it is temp or temp while reading those 12 lines of code. And using temporary is just silly -- I can't think of a single time I've ever seen that used in any language.
Maybe grepping for the variable is a bad example. I have seen bugs where a variable has been accidentally defined twice though due to inconsistent abbreviations.
I'm struggling to think of any case where "tmp" couldn't be replaced by a better name. It's always going to be a temporary something.
I'm not arguing against short, concise names where they won't cause problems. Variable names of e.g. x, y, i all have their place.
You should not need to grep for the local temporary variable, whether it's named tmp or temp or anything else -- because it should be right there in front of you since your functions should not be more than about a screen page in length.
If you have a variable tmp that's defined 6 pages back or worse, is global -- consider refactoring first, not just a more descriptive name.
> Encoding the type of a function into the name (so-called Hungarian notation) is brain damaged - the compiler knows the types anyway and can check those, and it only confuses the programmer. No wonder MicroSoft makes buggy programs.
This refers to systems hungarian, the brain-dead twin of apps hungarian. The latter can be useful in C.
> First off, I’d suggest printing out a copy of the GNU coding standards...
Which suggests this was written from the point of view of a specific person. In which case, it should attribute the author somewhere. I couldn't find a byline anywhere. Also, no date.
I think it's just trying to emulate a colloquial tone, actually being written by a number of individuals (or at least being updated by multiple people).
It was originally written by Linus and is quite old (the line about burning the GNU coding standards was there in the first Git import [1], but IIRC it's way older).
I can not find proof right now, but I've read some version of this in the early 2000s and the (initial) author is Linus Torvalds. You should be able to tell by the style :)
Yes, for pointer types for example type qualifiers (e.g., const or volatile) cannot penetrate typedef of pointer types. So if you use typedef with pointers you are stuck.
It varies a bit by context; Linus's call is likely the right one in the context of the kernel, though to be sure it's not so big a deal that other approaches can't be made to work fine.
You call out one upside - decreased verbosity. The accompanying downside is usually - as in this case, for both structs and pointers - that potentially relevant information is made less visible. Whether it's a good idea depends on how likely that information is to be actually relevant, weighed against the upsides.
Where performance is relevant, you want to be aware of where you're potentially passing large structs around. Putting this info in the type name instead is an option (eg _s), and can reduce verbosity a bit. I don't know of any good reasons to call out structs that are sized like primitives.
The case against hiding pointers is much stronger. Level of indirection can be relevant to performance, and is often relevant to correctness, particularly where mutation is involved. You can put it in the type name, but it's not going to be any less verbose - a star is already one character. I allow a possible exception here for where an opaque type is allocated by a library and passed around as a handle and the client really doesn't need to ever know whether it's a pointer or an int index or what.
This coding style works, sure. But so does the NT kernel style, which is the opposite of Linux kernel style in many ways. For example, in NT, all structs and pointers are typedefs. So what? There's a certain elegance to type names being one token long.
People bikeshed source code formatting. They make arguments about developer portability and visual minutiae, usually without any sort of evidence, when in reality the higher-level organization of the code matters a lot more. Optimizing code for readability quickly runs into diminishing returns and begins hurting a lot more than it helps.
In general, I'm strongly against rules and ceremony and centralization when it comes to coding. Ostensibly, it's all about hygiene and best practices and whatever, but in practice this kind of discipline amounts to "I like it this way and you're going to like it too". It's far more important to let developers make decentralized, rapid decisions about the best approach for a particular task than to enforce some kind of useless Procrustean uniformity on everyone.
That’s sort of what the parent is saying: “the only code formatting rule that matters is consistency, everything else is bollocks”. But people want to think there’s some kind of higher justification for their preferred style, so they come with these just-so stories that don’t have any real evidence behind them.
Also, it's local consistency is what matters, not global consistency. Developers can adjust to slightly different coding styles when they move to a new project. They're going to have to learn new abstractions, new bits of domain knowledge, and new coworker-interaction approaches anyway. Style is a very minor concern.
The word consistent is an issue in and of itself. You probably mean you think it's best when a style is applied consistently. But probably don't care that the style itself values consistency. The style linked above is not remotely consistent. Braces in different columns. Braces styles for functions different from non functions. if statement can have or into have braces. All extremely inconsistent
I always "preach" the value is in uniformity ! Weather you camelCase or kebab-style or using my-super-foo-style as long as everyone on the team uses the SAME style. Thats a WIN ! THATS where the value is !! Not in the RIGHT style but in the SAME style.
Amen to that! I have my preferences on where I place my curly braces, and I have strong opinions on camelCasing versus using_underscores. But for a given code base, consistency outweighs any advantages any given coding style might have.
Also, emacs has glasses-mode, so when I have to work on a code base that uses camel case, at least I don't have to squint really hard. ;-)
The biggest take-away from this, in my opinion, is that it's better to just type `struct foobar` instead of typedefing `foobar_t`. Structs should be treated differently than scalars, and therefore you should write them differently. The #1 principle of any coding style should be to optimize for readability and clarity over writability and convenience.
More practically, a lot of people (myself including) will split their monitor vertically to consider lots of code at once, and talk about code in emails via patches on mailing lists and such where 80 columns is the norm.
98 comments
[ 3.2 ms ] story [ 158 ms ] threadI hope some JS programmers read this
It was good advice.
There's reasons to keep the block inline too--like if you're working in a more resource constrained environment, or if the block isn't really isolated/self-contained enough to cleanly abstract away, or if the block in question isn't really doing anything substantial. But I wouldn't say that you should only abstract away code into functions to save yourself from literally copy/pasting the lines in multiple places.
The kernel guideline doesn't mention this due to being C specific. C++ can exhibit similar issues.
Anonymous callback:
Named callback:I've been coding according to these guidelines for quite a while with some minor modifications:
Always use curly braces (especially when you're not alone coding in the codebase as it allows for easy modification without code ending up out of the intented scope).
80 char width; well I don't follow this one as I really do prefer long lines over broken lines for readability.
Other than that I think these guidelines are great and offer consistency and easy to read code, in my opinion.
But I agree, after a few levels of indentation (which is sometimes unavoidable) you end up struggling.
That said, it's certainly a concern worth being aware of where it's relevant.
int usb_control_msg(struct usb_device * dev, unsigned int pipe, __u8 request, __u8 requesttype, __u16 value, __u16 index, void * data, __u16 size, int timeout);
So it is kind of hard to avoid going over the limit.
What we end up doing is break each argument into one line, like this (I hope the formatting comes out all right):
int res = usb_control_msg(
);It's not so much of an eye-sore.
Line length isn't going to have much impact on what fits over ssh...
That said, yes, I was picking a nit mostly because the nit itself amused me (and I hoped it would amuse others) - it wasn't meant as significant criticism of your post.
I just prioritize to have "readable" code in my editor as first prio, second would be sites like Github on desktop and if it works good on a mobile phone that's a plus but not high prio for me.
(To be honest though I do actually glance through some Github reviews on my phone, but since it's pretty limited I do find myself thinking that I should get to a computer and do a real review there instead.)
And, yes, if any meaningful comments are needed I wait until I'm back at my laptop.
[1] http://www.artima.com/weblogs/viewpost.jsp?thread=74230
indent wrong and it doesn't run.
Yuck. Abbreviations are usually bad. For one thing, people tend to pick different ways to abbreviate things so an hour later when you're trying to grep for where the variable was used you have to try to remember whether the variable was written tmp, temp, or temporary.
In this example, "temporary" is probably the least useful thing to know about the variable, since most variables are temporary. How about "counter"?
My favorite example: I was writing some graphics code recently, and some reviewer said: "I don't understand this uv abbreviation that appears all over the code. Please expand it."
headdesk.gif
(For those who aren't familiar: u and v are conventional names of texture coordinates, like x, y, and z are conventional names of spatial coordinates. There's no abbreviation to expand.)
I skipped to i and j, but I am certain there are mathematicians out there who find that confusing, too.
I guess, it's about context, too, at least a little.
IME it's pretty standard in most of mathematics to use "i" and "j" as index variables when e.g. doing sums and products over indices/sets. (Though I suppose you could be talking about the use of i, j, k as axes?)
What does one for index variables in that notation? Or is the main point of q notation that you don't need index variables? ;)
It's all about knowing what should be abbreviated and what shouldn't.
Why would one be forgetting and grepping for tmp? That's the kind of variable that would be inside a function (so max one or two screenfuls, according to the guidelines here), and more realistically would usually be declared and used entirely within the same block of a dozen or so lines of code. Nobody is going to forget whether it is temp or temp while reading those 12 lines of code. And using temporary is just silly -- I can't think of a single time I've ever seen that used in any language.
I'm struggling to think of any case where "tmp" couldn't be replaced by a better name. It's always going to be a temporary something.
I'm not arguing against short, concise names where they won't cause problems. Variable names of e.g. x, y, i all have their place.
If you have a variable tmp that's defined 6 pages back or worse, is global -- consider refactoring first, not just a more descriptive name.
1. always use curly braces
2. 4 spaces instead of a tab character
> Not using braces for conditions followed by single line statements.
> Using abbreviations.
This is enough for me to say fuck this guide.
This refers to systems hungarian, the brain-dead twin of apps hungarian. The latter can be useful in C.
https://www.joelonsoftware.com/2005/05/11/making-wrong-code-...
> First off, I’d suggest printing out a copy of the GNU coding standards...
Which suggests this was written from the point of view of a specific person. In which case, it should attribute the author somewhere. I couldn't find a byline anywhere. Also, no date.
You could look in one of the historical trees.
is the original history from the BitKeeper repo.
[1] https://github.com/torvalds/linux/blame/master/Documentation...
C programmers tend to forget this wise recommendation.
Is that the thinking or is it something else?
You call out one upside - decreased verbosity. The accompanying downside is usually - as in this case, for both structs and pointers - that potentially relevant information is made less visible. Whether it's a good idea depends on how likely that information is to be actually relevant, weighed against the upsides.
Where performance is relevant, you want to be aware of where you're potentially passing large structs around. Putting this info in the type name instead is an option (eg _s), and can reduce verbosity a bit. I don't know of any good reasons to call out structs that are sized like primitives.
The case against hiding pointers is much stronger. Level of indirection can be relevant to performance, and is often relevant to correctness, particularly where mutation is involved. You can put it in the type name, but it's not going to be any less verbose - a star is already one character. I allow a possible exception here for where an opaque type is allocated by a library and passed around as a handle and the client really doesn't need to ever know whether it's a pointer or an int index or what.
People bikeshed source code formatting. They make arguments about developer portability and visual minutiae, usually without any sort of evidence, when in reality the higher-level organization of the code matters a lot more. Optimizing code for readability quickly runs into diminishing returns and begins hurting a lot more than it helps.
In general, I'm strongly against rules and ceremony and centralization when it comes to coding. Ostensibly, it's all about hygiene and best practices and whatever, but in practice this kind of discipline amounts to "I like it this way and you're going to like it too". It's far more important to let developers make decentralized, rapid decisions about the best approach for a particular task than to enforce some kind of useless Procrustean uniformity on everyone.
Also, emacs has glasses-mode, so when I have to work on a code base that uses camel case, at least I don't have to squint really hard. ;-)
Also, please limit your lines to 80 characters. https://sr.ht/toyc.jpg
Assuming indentation is counted against those 80, why not use a bigger monitor?
More practically, a lot of people (myself including) will split their monitor vertically to consider lots of code at once, and talk about code in emails via patches on mailing lists and such where 80 columns is the norm.