commit ce1e3130f8416487f45db933fdd8594d41777aba
parent 0768d5f4d3e9781f7c595e582315d3b579921fd2
Author: Jake Bauer <jbauer@paritybit.ca>
Date: Sat, 25 Feb 2023 00:32:44 -0500
*
Diffstat:
5 files changed, 85 insertions(+), 74 deletions(-)
diff --git a/content/garden/arboretum/c.md b/content/garden/arboretum/c.md
@@ -5,14 +5,10 @@ Summary: C
[← Back](./)
+* [C Programming Style](programming-style.html#c)
-[A collection of helpers for ANSI C](https://wiki.xxiivv.com/site/defunct.html)
+## More Resources
-
-[Advanced C: The UB and optimizations that trick good programmers.](https://www.youtube.com/watch?v=w3_e9vZj7D8)
-
-
-[How I program C](https://www.youtube.com/watch?v=443UNeGrFoM)
-
-
-^ By the same person who made the "Advanced C" video, this video is way more useful than the title lets on. It goes over a lot of advanced programming concepts and writing good C code.
+* [A collection of helpers for ANSI C](https://wiki.xxiivv.com/site/defunct.html)
+* [Advanced C: The UB and optimizations that trick good programmers.](https://www.youtube.com/watch?v=w3_e9vZj7D8)
+* [How I program C](https://www.youtube.com/watch?v=443UNeGrFoM)
diff --git a/content/garden/arboretum/programming-style.md b/content/garden/arboretum/programming-style.md
@@ -36,6 +36,8 @@ gofmt or Python's PEP 8), abide by that style.
<li><a href="#language-specifics">Language Specifics</a></li>
</ul>
+Also see: [Clean Coders Hate What Happens to Your Code When You Use These
+Enterprise Programming Tricks](https://www.youtube.com/watch?v=FyCYva9DhsI)
## Dependencies
@@ -75,14 +77,14 @@ struct Node *np = &node /* Create a pointer to the node */
```
Comments should also not have annoyingly large banners, and big blocks of
-comments should be avoided. The "doxygen-style" of commenting before a function
-and at the top of a file are quite useless and end up being like the above
-example in practice. Although they can be helpful for generating the skeleton
-of some API documentation, it requires so much additional work and information
-to be useful that you're better off leaving your code clean and just writing
-the documentation separately. I have mainly seen these kinds of comments used
-as an excuse to not write good documentation ("Look, we have doxygen-generated
-documentations; we documented this code!") more than I have seen it be useful.
+comments should be avoided. If you use the
+"[doxygen-style](https://en.wikipedia.org/wiki/Doxygen)" of commenting before
+a function and at the top of a file, you _must_ treat this as writing
+high-quality documentation that you would serve to an end user. Otherwise it
+ends up being as useless as the above example in practice. I have often seen
+these kinds of comments used as an excuse to not write good documentation
+("Look, we have doxygen-generated documentations; we documented this code!")
+which makes these kinds of comments just clutter.
Great uses of comments include:
@@ -100,9 +102,10 @@ optimized for speed, and excessive reliance on external dependencies, where
lines of code is just a symptom of these diseases.
The more code a program has, the more bugs your program can have. The more
-features your code has, the more ways those features can interact in unexpected
-ways and result in bugs. The more clever a program is written, the harder it is
-to spot bugs or debug.
+features your code has, the more ways those features can [interact in
+unexpected ways](https://flak.tedunangst.com/post/features-are-faults-redux)
+and result in bugs. The more clever a program is written, the harder it is to
+spot bugs or debug.
Also, simple algorithms and data structures are often preferable over fancy
ones—even though fancy ones may be theoretically faster for large
@@ -116,30 +119,33 @@ integers that are 10,000 to 40,000 or so decimal digits large. If you're
implementing your own multiplication algorithm for whatever reason and you
don't expect to be operating on numbers that large then it's counterproductive
to implement the more complex algorithm because it will perform worse and be
-harder to understand. Fancier algorithms and data structures are often not only
-buggier, but also harder to debug than their simpler counterparts.
+harder to understand. Fancier algorithms and data structures offer more
+opportunity for bugs, and are also harder to debug than their simpler
+counterparts.
Finally, this is one point that I wish was hammered into every programmer's
head: **measure, don't assume** the performance characteristics of your
program. Too many programs are written in convoluted or confusing ways in an
attempt to chase perceived performance gains without any actual benchmarking or
-measurement. Only tune once you understand how your program behaves. Beyond
-this, there is no point tuning a program for marginal improvements in overall
-speed unless you are specifically targeting a performance metric.
+measurement. Only tune once you understand how your program behaves, because
+only then can you justify the increased complexity that comes along with
+bespoke optimizations. Beyond this, there is no point tuning a program for
+marginal improvements in overall speed unless you are specifically targeting
+a performance metric.
## Naming
Names should be descriptive and clear in context, but not redundant or
excessive. In general, procedures should be named based on what they do and
-functions should be named based on what they return. Variables and types
-should be nouns (e.g. `num_cakes` or `Parser`).
+functions should be named based on what they return. Variables and types should
+be nouns (e.g. `num_cakes` or `Parser`).
```
draw();
-compute();
+blink();
-x = compute_length(x);
-if (valid_length(x))
+len = compute_length(x);
+if (valid_length(len))
```
is better than:
@@ -148,10 +154,13 @@ is better than:
screen_changer();
do_stuff();
-x = length_computer(x);
-if (check_length(x))
+len = length_computer(x);
+if (check_length(len))
```
+Also see: [What is the difference between a function and
+a procedure?](https://stackoverflow.com/questions/721090/what-is-the-difference-between-a-function-and-a-procedure#721107).
+
Names like `maximumValueUntilOverflow` or `EntertainmentProviderViewController`
are bad. They are excessive and make it harder to see what the program is
actually doing. Also, the latter example is annoyingly vague and indirect.
@@ -160,16 +169,25 @@ actually doing. Also, the latter example is annoyingly vague and indirect.
Types, classes, structs or other similar programming structures should be
written in capitalised `CamelCase`, variables and functions in `snake_case`,
and constants in `ALL_CAPS`. If the components of a variable name are short,
-there are a maximum of two, and they are distinct, it is often more readable to
+there are a maximum of two, and they are distinct, it is often fine to just
write the name in all lowercase as opposed to snake case. For example, `maxval`
over `max_val`, but not `percenttrue` over `percent_true`.
+Also, if variables represent specific units of a measurement (e.g. milliseconds
+or kilometers), this should be reflected in its name. This is also why
+`snake_case` is preferable to `camelCase` for variables. `timeMs` or `timeMS`
+looks worse than `time_ms`.
+
Furthermore, it is acceptable to use short names where the meaning is
immediately clear from the context. For example, `np` is better than
`node_pointer` or `nodepointer` as long as you are consistent and it is obvious
what the variable refers to in a given context (e.g. you created it like:
`struct Node *np = &node;`).
+Single-letter names are acceptable only in contexts in which they are obvious
+(e.g. `x` and `y` in mathematics) or a well-understood convention (e.g. `i` and
+`j` for loop iterator variables).
+
Finally, if two variables are related in some way, they should have consistent
naming. For example, if you have a variable representing the maximum and
minimum physical address in memory, choose names like `max_phys_addr` and
@@ -178,7 +196,10 @@ minimum physical address in memory, choose names like `max_phys_addr` and
### Worse
```
-ComputeResult(initial_value, new_value, modifier, even)
+time = 5000
+distance = 5
+
+ComputeResult(initialValue, newValue, modifier)
FileName = "file.txt"
coordinate_pair updatedcoordinate = (ComputeX(x), y)
@@ -187,35 +208,14 @@ coordinate_pair updatedcoordinate = (ComputeX(x), y)
### Better
```
-compute_result(initialValue, newValue, modifier, is_even)
-
-filename = "this-is-a-file.txt"
-CoordinatePair updated_coordinate = (compute_x(x), y)
-```
-
-If variables represent a certain magnitude (e.g. milliseconds or kilometers),
-this should be reflected in its name:
-
-### Worse
-
-```
-time = 5000
-distance = 5
-```
-
-### Better
-
-```
time_ms = 5000
distance_km = 5
-```
-The above is also why `snake_case` is preferable to `camelCase` for variables.
-`timeMs` or `timeMS` looks worse than `time_ms`.
+compute_result(initial_value, new_value, modifier)
-Single-letter names are acceptable only in contexts in which they are obvious
-(e.g. `x` and `y` in mathematics) or a well-understood convention (e.g. `i` and
-`j` for loop iterator variables).
+filename = "file.txt"
+CoordinatePair updated_coordinate = (compute_x(x), y)
+```
## Braces and Parentheses
@@ -306,7 +306,7 @@ more complex. For example:
if (is_logged_in(client)
&& client->assignedAddress
&& strncmp(client->username, "admin", sizeof("admin")) == 0
- && authenticate(client->password, password)
+ && authenticate(client->password, password))
{
render_admin_panel();
}
@@ -318,7 +318,7 @@ is far better than:
if (is_logged_in(client)
&& client->assignedAddress
&& strncmp(client->username, "admin", sizeof("admin")) == 0
- && authenticate(client->password, password) {
+ && authenticate(client->password, password)) {
render_admin_panel();
}
```
@@ -477,18 +477,24 @@ operators) and their operands as well as between elements in a list:
```
array = [1, 2, 3, 4];
-result = (input + (CONSTANT / intermediate));
+int i;
+for (i = 0; i < 10; ++i) {
+ printf("%d", i * i + i);
+}
```
-not
+not:
```
array=[1,2,3,4];
-result=(input+(CONSTANT/intermediate))
+int i;
+for(i=0;i<10;++i){
+ printf("%d",i*i+i);
+}
```
Also, it is acceptable to use spaces to visually align your code if it makes it
-easier to read. Once again, use your judgement. Oftentimes no alignment is
+easier to read (not tabs, their variable width makes them inconsistent for this purpose). Once again, use your judgement. Oftentimes no alignment is
really needed (plus, it makes no difference if you like to program with
a variable-width font).
@@ -510,10 +516,10 @@ That being said, I prefer tabs wherever supported for the following reasons:
On the first point, although disk space is quite plentiful today, bandwidth
still isn't. Even on files that are only a couple of hundreds of lines long,
-using spaces instead of tabs to indent increases file size by a significant
-amount. If you're trying to optimize the size of assets you're delivering over
-the wire (e.g. HTML, CSS, and JS files), this becomes significant. For example,
-this page as a tab-indented HTML file takes up XXXX bytes, but it takes up XXXX
+using spaces instead of tabs to indent increases file size by a decent amount.
+If you're trying to optimize the size of assets you're delivering over the wire
+(e.g. HTML, CSS, and JS files), this is even more pertinent. For example, this
+page as a tab-indented HTML file takes up XXXX bytes, but it takes up XXXX
bytes if indented with four spaces.
On the second point, if a programmer prefers to see a lot of whitespace to
diff --git a/content/meta.md b/content/meta.md
@@ -12,7 +12,7 @@ A page for testing the stylesheet.
<h5>Header 5</h5>
<h6>Header 6</h6>
-<p>This is a paragraph, with <b>bold</b>, <i>italic</i>, <code>code</code>, and <a href="/meta.html">a link</a>.</p>
+<p>This is a paragraph, with <b>bold</b>, <i>italic</i>, <code>code</code>, and <a href="/meta.html">a local link</a> and an <a href="http://example.com">an external link</a>.</p>
<ul>
<li>This is a list, with:</li>
@@ -51,15 +51,22 @@ A page for testing the stylesheet.
</tbody>
</table>
-<pre>This is a pre block, with <b>bold</b>, <i>italic</i>, <code>code</code> and <a href="/meta.html">a link</a>.</pre>
+<pre>This is a pre block, with <b>bold</b>, <i>italic</i>, <code>code</code> and <a href="/meta.html">a local link</a> and an <a href="http://example.com">an external link</a>.</pre>
<label for="input">Label:</label>
<input placeholder="Input field" name="input"></input>
<button>Button</button>
<figure>
- <img src="/img/desktop.png" alt="An example image.">
- <figcaption>This is an image in a figure block, this note is in a figcaption with <b>bold</b>, <i>italic</i>, <code>code</code> and a <a href="/meta.html">link</a>.</figcaption>
+ <img src="/img/desktop.png" alt="An example image.">
+ <figcaption>This is an image in a figure block, this note is in a figcaption with <b>bold</b>, <i>italic</i>, <code>code</code> and a <a href="/meta.html">link</a>.</figcaption>
+</figure>
+
+<figure>
+ <a href="http://ftp.paritybit.ca/cc0raven.jpg">
+ <img src="http://ftp.paritybit.ca/cc0raven-small.jpg" alt="A picture of a raven.">
+ </a>
+ <figcaption>This is an image with an external link to a higher resolution version.</figcaption>
</figure>
<details>
diff --git a/templates/footer.html b/templates/footer.html
@@ -1,3 +1,4 @@
+</article>
</main>
<hr>
<footer>
diff --git a/templates/header.html b/templates/header.html
@@ -7,7 +7,7 @@
<link rel="alternate" type="application/rss+xml" title="RSS feed" href="/feed.xml">
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAABX1BMVEUAAAABAAAAAAAAAAAAAAAAAAAAAAC7amoAAABlPz8AAAAAAAAGAwMAAAAAAAAAAAC7d3cKBwe7d3e7d3eWX1/ny4+WX18CAQGHVlaTXl4BAAApGhpiPj7ny4/ny4/oy4/ozI/qz5Ona2u7d3d4TEzny48MCAhlQEC7d3e7d3cAAAAAAAC7d3e8d3cAAAC8d3fnzI+8dnYAAADpzJC9eHjny4+WX1+TXV13S0u7d3fny492S0vnzI/ny4+EU1PnzI8mFxe7d3cjFhZgPT3ny5AAAAC7d3fny4+7d3cAAADozJC6d3e7d3cAAADozI/my5Dny44AAAAAAAC7d3e4d3fkx5DpzY69c3O7d3eoamroy4+FVVWEVFR0Skq7d3e7d3e8d3cAAAC6eHi7eHi7eHi8dna8dnYAAADozJAAAADkyY28eXnqyJHqzY63eHi/dXXny48AAAC7d3e5dXW2dHSjLYEdAAAAcHRSTlMA9cj58gYaBOrflhjq44MI/ePbaP348u/u6Oba1sW+oosL/Pbv7ejnyLuXlI54RkM8Oy4iG/v38efl4ODf2tfT09LQz87FwbeimJeJf397ZUlIRTQvGxYP9/Xv4ODZz86yk4JxYlRQSjctJiYlJCAYM3tXUgAAAg1JREFUOMttk1V3ImEQRO8MQ3CChACBIHF3l427+7q7Tjfz/88+sNhk67Vuf3K6CuryXo2Yfo/HbwYnvDxW25EldVnBNpfdHjVErO2dJ9nsk51tS8SItreMmyLxV46qakxVndW4iNl0yExEjHxFEyfTcz7f3PT7La0EDInM1PxQRMJZTSQbE5OvtbNLuv6d0W5K1zM99DXf6RvTnrCY1XdExcjqKcD9RbFQKF7cAyS105AoQJsheT0EyqWUbdu2badKZeBEA2KFgCOJVxI+uNu169q9A4YqAxIEryWr+hnKG3aTNsowrX2S9vJFLGcLOLZbdAwMO4ZMMCKbegq/5luB+VlIak6CmJLXGzi3XTqHOQ2IiV9e6gMU3EABeJoRPx7p7AXW3cA6kOgQTw1YcwNrNcAvL/QBut1AN9CbET+m5PUWSm6gBH90UEyCsqnjMOUGvsJHzckoV2I4Q8BBq38AvHUMucZryZJOwmx/s98/C7exPkl7YUTilTc+mHre5E8Bw5UBGa2uO6BjwPf6T7p/AuM6WF03UTEWNQlwWVxJpVaKlwCfYgseOatFLtyjYy2RYzzWE5Y9byO0izo02bBv9nUhXA9tNfaBiu5/+OED3+/ksFYGPRL55irOkqOqy8sxVadvQGQv9Kh6Ri6Q6ejIBHKGiHXmLnAomG6UNz0a+k+/vRPBav3fXTdN/wUXrszXABeiEwAAAABJRU5ErkJggg==">
<title></title>
-<style>body{background-color:#fcfcfc;color:#111;line-height:1.5rem;max-width:660px;margin:0 auto;padding:0.5em 0 3em;font-family:"IBM Plex Serif", serif}header{text-align:center;margin:0.7em auto;font-size:2em;font-weight:bold}h1{font-style:oblique;margin-bottom:0;line-height:1.1em;font-size:1.7em}h2,h3,h4,h5,h6{margin:1.4em 0 -0.3em;line-height:1.1em}nav{text-align:center}nav a{padding:0 0.5em;font-size:1.1rem;font-weight:bold;text-decoration:none}nav a:hover{text-decoration:underline}a,nav a:visited{color:#134799}a:hover{text-decoration:none}a:visited{color:#551a8b}img,video{max-width:100%}figcaption{margin-bottom:1.5em}blockquote{border-left:3px solid #134799;padding-left:0.5em}details{margin-left:1.5em}details p:first-of-type{margin-top:0.5em}summary:hover{cursor:pointer;background-color:#ddd}table{width:100%;text-align:left}table,td,th{border-collapse:collapse;margin-top:1em;padding:2px 4px;vertical-align: top}th{background-color:#ddd}tr:nth-child(even){background-color:#eee}pre{background-color:#ddd;overflow:auto;padding:0.5em;line-height:1.1rem;border:1px black solid}code{background-color:#ddd;font-family:"IBM Plex Mono", monospace;font-size:0.9rem}.note{border:3px solid #134799;padding:10px 15px}.date{font-size:smaller;color:#565151}#icons{float:right}@media print{pre{white-space:pre-wrap}nav{display:none}}@media only screen and (max-width: 1000px){body{max-width:90%}#icons{float:none}}</style>
+<style>body{background-color:#fcfcfc;color:#111;line-height:1.5rem;max-width:660px;margin:0 auto;padding:0.5em 0 3em;font-family:"IBM Plex Serif", serif}header{text-align:center;margin:0.7em auto;font-size:2em;font-weight:bold}h1{font-style:oblique;margin-bottom:0;line-height:1.1em;font-size:1.7em}h2,h3,h4,h5,h6{margin:1.4em 0 -0.3em;line-height:1.1em}nav{text-align:center}nav a{padding:0 0.5em;font-size:1.1rem;font-weight:bold;text-decoration:none}nav a:hover{text-decoration:underline}a,nav a:visited{color:#134799}a:hover{text-decoration:none}a:visited{color:#551a8b}article a[href^="http"]:where(:not([href*="www.paritybit.ca/"]))::after{content:"⬈"}figure a::after{content:"" !important}img,video{max-width:100%}figcaption{margin-bottom:1.5em}blockquote{border-left:3px solid #134799;padding-left:0.5em}details{margin-left:1.5em}details p:first-of-type{margin-top:0.5em}summary:hover{cursor:pointer;background-color:#ddd}table{width:100%;text-align:left}table,td,th{border-collapse:collapse;margin-top:1em;padding:2px 4px;vertical-align: top}th{background-color:#ddd}tr:nth-child(even){background-color:#eee}pre{background-color:#ddd;overflow:auto;padding:0.5em;line-height:1.1rem;border:1px black solid}code{background-color:#ddd;font-family:"IBM Plex Mono", monospace;font-size:0.9rem}.note{border:3px solid #134799;padding:10px 15px}.date{font-size:smaller;color:#565151}#icons{float:right}@media print{pre{white-space:pre-wrap}nav{display:none}}@media only screen and (max-width: 1000px){body{max-width:90%}#icons{float:none}}</style>
</head>
<body>
<header>paritybit.ca</header>
@@ -22,3 +22,4 @@
</nav>
<hr>
<main>
+ <article>