diff --git a/content/2009/running-legacy-code/index.md b/content/2009/running-legacy-code/index.md
index c1074924..3816a38d 100644
--- a/content/2009/running-legacy-code/index.md
+++ b/content/2009/running-legacy-code/index.md
@@ -8,7 +8,7 @@ tags=["dev"]
This short article deals with a severe problem in software development: bit rot.
When switching to a new platform (for instance from Windows XP to Windows Vista/7), the programmers need to make sure that old bits of code run flawlessly. There are several ways to achieve this goal that will be discussed in the next paragraphs:
-## Porting the code
+## Porting the Code
This is generally considered a hard path to follow. For non-trivial legacy code-blocks, chances are high that they contain side-effects and hacks to make them work in different environments. Porting code means replacing parts of the program that use functions and methods that don't exist anymore with new ones which make use of the modern libraries and routines of the new platform. The significant advantages are maintainable software and sometimes faster running programs. But it may be needed to hack the new platform libraries in order to preserve the whole functionality of an old application. When changing an algorithm inside legacy code, the ported version may become unstable. Thus there may be better ways of maintaining obsolete code today.
@@ -16,7 +16,7 @@ This is generally considered a hard path to follow. For non-trivial legacy code-
Emulators work much the same like porting the code. You replace old function calls with new ones to make everything work again. However you don't alter the old codebase itself (because you may not have the source code available) but you create a new compatibility layer that "translates" the communication between the underlying operating system and software (our new platform) and our old software. Emulation can also be very fast and run stable for many years but writing an emulator can be even harder than porting the code because an educational guess may be needed to figure out how the program works internally. Additionally, the emulator itself may become obsolete in the future and might eventually be replaced by a new one.
-## Virtual machines
+## Virtual Machines
During the last years, a new approach was gaining popularity. The idea is simple: Don't touch anything. Take the whole platform and copy it in order to run old software. The old software runs on top of the old operating system within a virtual machine that runs on the new platform.
diff --git a/content/2010/howto-sort-a-vector-or-a-list-in-c-using-stl/index.md b/content/2010/howto-sort-a-vector-or-a-list-in-c-using-stl/index.md
index f1be98f7..6fbeb0b9 100644
--- a/content/2010/howto-sort-a-vector-or-a-list-in-c-using-stl/index.md
+++ b/content/2010/howto-sort-a-vector-or-a-list-in-c-using-stl/index.md
@@ -1,5 +1,5 @@
+++
-title="Howto Sort a Vector or a List in C++ using STL"
+title="How to Sort a Vector or a List in C++ Using STL"
date=2010-01-27
[taxonomies]
tags=["dev"]
@@ -104,7 +104,7 @@ int main() {
}
```
-## Compilation and execution
+## Compilation and Execution
Save the above code inside a file, e.g. `list_vector.cpp` and compile it like so:
@@ -118,7 +118,7 @@ To run it, execute the resulting binary.
./a.out
```
-## Program output
+## Program Output
```
Vector: 12 5 1
diff --git a/content/2011/are-you-a-programmer/index.md b/content/2011/are-you-a-programmer/index.md
index f6ef10e7..c6004ff3 100644
--- a/content/2011/are-you-a-programmer/index.md
+++ b/content/2011/are-you-a-programmer/index.md
@@ -1,5 +1,5 @@
+++
-title="Are you a Programmer?"
+title="Are You a Programmer?"
date=2011-10-20
[taxonomies]
tags=["culture", "dev"]
diff --git a/content/2017/boxes-and-trees/index.md b/content/2017/boxes-and-trees/index.md
index d2c7889f..e5121411 100644
--- a/content/2017/boxes-and-trees/index.md
+++ b/content/2017/boxes-and-trees/index.md
@@ -122,13 +122,13 @@ Therefore we would need to add lifetime parameters here. This can make it tediou
}
```
-## Putting the tree into a box
+## Putting the Tree into a Box
All three options are totally valid. Which one you should choose, depends on your use-case.
A rule of thumb is to keep it simple.
In my case, I chose to use a `Box`, because I did not need any special guarantees.
-## Making subtrees optional
+## Making Subtrees Optional
The next problem I faced was that I could not instantiate a tree structure.
The left and right subtree have the type `Box`, but at some
@@ -241,7 +241,7 @@ root(15)
);
```
-## Why did it just work in Python?
+## Why Did It Just Work in Python?
Now you might be wondering why our tree implementation worked so flawlessly in Python.
The reason is that Python *dynamically* allocates memory for the tree object at *runtime*.
diff --git a/content/2017/digitial-clocks/index.md b/content/2017/digitial-clocks/index.md
index 3178d46f..c4696a38 100644
--- a/content/2017/digitial-clocks/index.md
+++ b/content/2017/digitial-clocks/index.md
@@ -16,7 +16,7 @@ As a result I didn't set the correct time, instead, I set a cooking timer... and
{{ }}
-## Let's add a clock to the microwave!
+## Let's Add a Clock to the Microwave!
On occasions like these, I wonder why there's a digital clock on every single household device these days.
They're integrated into microwaves, fridges, ovens, dishwashers, dryers, mixers — and that's just the kitchen!
@@ -44,7 +44,7 @@ That's why I constantly need to look after those clocks.
Let me tell you a secret:
When I'm not warming stuff in the oven, I don't want it to tell me the local time. I want the stove to be _off_.
-## Why I have trouble setting the clock on our oven
+## Why I Have Trouble Setting the Clock on Our Oven
Our oven has three buttons related to time: plus, minus and a clock symbol.
To set the time, you push the clock symbol. An arrow appears and the display changes to 00:00. You press time again and another arrow appears.
diff --git a/content/2017/future-of-rust/index.md b/content/2017/future-of-rust/index.md
index d67ed4b4..ce1dca17 100644
--- a/content/2017/future-of-rust/index.md
+++ b/content/2017/future-of-rust/index.md
@@ -40,7 +40,7 @@ It is not unthinkable that Rust is going to be some healthy competition for C++
The benchmarks of [leaf](https://github.com/autumnai/leaf), a machine learning library written in Rust, are already nothing short of
impressive.
-## Blockbuster games
+## Blockbuster Games
[Games](https://www.reddit.com/r/rust_gamedev/comments/4qlftu/look_our_game_writen_entirely_in_rust/d4tz4r3/) are another area where Rust might shine.
It's financially attractive for Game Studios to support multiple platforms without much
@@ -57,7 +57,7 @@ That said, the first AAA Rust game might still be far in the future. [Here's Bli
Maybe — eventually — we will also see formal verification of the Rust core. Projects like [RustBelt](https://plv.mpi-sws.org/rustbelt/) would then open new opportunities in safety-focused industries like the Space industry. Wouldn't it be nice to safely land a Spacecraft on Mars that is controlled by Rust? (Or by one of its spiritual successors.)
I wonder if [SpaceX](https://www.spacex.com/) is experimenting with Rust already...
-## Integrating with other languages
+## Integrating with Other Languages
There are many other areas I haven't even mentioned yet. For example, financial and medical software or Scientific Computing, just to name a few.
In all cases, Rust might be a good fit. Right now the biggest barrier to entry
diff --git a/content/2017/go-vs-rust/index.md b/content/2017/go-vs-rust/index.md
index 7cff7f2c..a71435a6 100644
--- a/content/2017/go-vs-rust/index.md
+++ b/content/2017/go-vs-rust/index.md
@@ -36,7 +36,7 @@ Shuttle 🚀
Both languages seem to be competing for the same user base and they both seem to be
_systems programming_ languages, so there must be a clear winner, right?
-## Go: practical, pragmatic, plain
+## Go: Practical, Pragmatic, Plain
{{ }}
@@ -47,7 +47,7 @@ But with Go, you _get things done_ — fast.
Go is one of the most productive languages I've ever worked with.
The mantra is: solve real problems today.
-## Rust's strong guarantees come at a cost
+## Rust's Strong Guarantees Come at a Cost
{{ }}
@@ -70,7 +70,7 @@ That's because these guarantees come with a cost: ramp-up time.
You'll need to unlearn bad habits and learn new concepts.
Chances are, you will [fight with the borrow checker](https://m-decoster.github.io/2017/01/16/fighting-borrowchk/) a lot when you start out.
-## Case-study: Primality by trial division
+## Case-Study: Primality by Trial Division
Let's say, you want to check if a number is [prime](https://en.wikipedia.org/wiki/Prime_number).
The easiest way is to check if we can divide the number by any smaller natural number (without a remainder). If not, we found a prime number! This approach is called [trial division](https://en.wikipedia.org/wiki/Trial_division).
@@ -136,14 +136,14 @@ It might seem a little alien at first, but it will become second-nature after a
This was just a quick example, of course. I suggest, you browse some code on [Rosetta Code](https://rosettacode.org/wiki/Rosetta_Code) to get a better feeling for both languages.
-## Case study: Finding duplicate words in text files
+## Case Study: Finding Duplicate Words in Text Files
If you're more like a visual type, here is a video where I write a simple
concurrent program in Go and Rust to compare both languages:
{{ }}
-## Some things I prefer in Go
+## Some Things I Prefer in Go
- Fast compile times
- Pragmatic problem-solving approach
@@ -153,7 +153,7 @@ concurrent program in Go and Rust to compare both languages:
- Simple error handling
- The mascot 😉
-## Some things I prefer in Rust
+## Some Things I Prefer in Rust
- Safety: No null pointers, no data races,...
- Fine-grained system control
diff --git a/content/2017/hacktoberfest/index.md b/content/2017/hacktoberfest/index.md
index 2f301d4f..f4d7bdc6 100644
--- a/content/2017/hacktoberfest/index.md
+++ b/content/2017/hacktoberfest/index.md
@@ -1,5 +1,5 @@
+++
-title="Learn Some Rust During Hacktoberfest"
+title="Learn Some Rust during Hacktoberfest"
date=2017-10-15
[taxonomies]
tags=["culture", "dev", "oss", "rust"]
@@ -21,7 +21,7 @@ This guide is trying to change that!
Let me show you, how _everybody_ can contribute code to [Rust](https://www.rust-lang.org/), a safe systems programming language.
I was inspired to write this by a [tweet from llogiq](https://twitter.com/llogiq/status/915288482314178560).
-## 1. Find a great Rust project to work on
+## 1. Find a Great Rust Project to Work On
We all want our work to be appreciated.
Therefore I suggest to start contributing to medium-sized projects, because they gained some momentum but are still driven by a small number of maintainers, so help is always welcome. By contrast, tiny projects are mostly useful to the original author only, while large projects can be intimidating at first and have stricter guidelines.
@@ -35,7 +35,7 @@ language:Rust stars:5..100 pushed:>2017-01-01
[Here](https://github.com/search?q=language%3ARust+stars%3A5..100+pushed%3A%3E2017-01-01)'s a list of projects, which match this filter.
-## 2. Install the Rust toolchain
+## 2. Install the Rust Toolchain
To start contributing, we need a working Rust compiler and the cargo package manager.
Fortunately, the installation should be straightforward.
@@ -56,7 +56,7 @@ rustup install nightly
Questions so far? Find more detailed installation instructions [here](https://asquera.de/blog/2017-03-03/setting-up-a-rust-devenv/).
-## 3. Fork the project and clone it to your computer
+## 3. Fork the Project and Clone It to Your Computer
First, click on the little _fork_ button on the top right of the Github project page. Then clone your fork to your computer.
@@ -66,7 +66,7 @@ git clone git@github.com:yourusername/project.git
For more detailed instructions, go [here](https://guides.github.com/activities/forking/).
-## 4. Does it build?
+## 4. Does It Build?
Before we start modifying the codebase, we should make sure that it is in a workable state.
The following commands should work right away from inside the project folder.
@@ -78,7 +78,7 @@ cargo test
If not, you might want to consult the `README` for further instructions. (But feel free to choose another project.)
-## 5. The magic sauce
+## 5. The Magic Sauce
Here's the trick: we use a [linter]() called [clippy](https://github.com/rust-lang/rust-clippy) to show us improvement areas in any Rust codebase.
@@ -138,7 +138,7 @@ Please add a meaningful description and then submit the pull request.
Congratulations! You've contributed to the Rust ecosystem. Thank you! 🎉
-## Trophy case
+## Trophy Case
- [m4b/goblin](https://github.com/m4b/goblin/pull/55)
- [fitzgen/cpp_demangle](https://github.com/gimli-rs/cpp_demangle/pull/100)
diff --git a/content/2017/image-previews/index.md b/content/2017/image-previews/index.md
index 85d3d4d6..3931bf04 100644
--- a/content/2017/image-previews/index.md
+++ b/content/2017/image-previews/index.md
@@ -31,7 +31,7 @@ I could fix that, by hardcoding the image width and height, but that would be te
And there would be no preview.
So I was wondering, what others were doing. 🤔
-## Tiny image thumbnails
+## Tiny Image Thumbnails
I vaguely remembered, that [Facebook uses tiny preview thumbnails in their mobile app](https://code.fb.com/uncategorized/the-technology-behind-preview-photos/).
They extract the quantization table from the JPEG header to render the preview. This information
diff --git a/content/2017/makefiles/index.md b/content/2017/makefiles/index.md
index 9e972a90..625ef8b2 100644
--- a/content/2017/makefiles/index.md
+++ b/content/2017/makefiles/index.md
@@ -1,5 +1,5 @@
+++
-title="Afraid of Makefiles? Don't be!"
+title="Afraid of Makefiles? Don't Be!"
date=2017-08-15
updated=2022-03-01
[taxonomies]
@@ -38,7 +38,7 @@ Along the way, they keep making the same basic mistakes:
These are issues Makefiles were invented to solve.
-## Makefiles are scary!
+## Makefiles Are Scary!
If you think that `make` is scary, you probably think of complicated build machinery for [big](https://community.kde.org/Guidelines_and_HOWTOs/Build_from_source) [software](https://chromium.googlesource.com/chromium/src/+/master/docs/linux/build_instructions.md) projects.
It doesn't need to be that way. Let's hear from the author of `make`, [Stuart Feldman](https://en.wikipedia.org/wiki/Stuart_Feldman) himself:
@@ -47,9 +47,9 @@ It doesn't need to be that way. Let's hear from the author of `make`, [Stuart Fe
>
> — [The Art of Unix Programming (2003)](https://nakamotoinstitute.org/static/docs/taoup.pdf)
-Make was built in _one weekend_ to solve a reoccuring problem in a simple way.
+Make was built in _one weekend_ to solve a reoccurring problem in a simple way.
-## Makefiles are simple!
+## Makefiles Are Simple!
Before I leave the house, I need to get dressed.
I use the same simple routine every time:
@@ -100,7 +100,7 @@ Putting on jacket.
All done. Let's go outside!
```
-## What just happened?
+## What Just Happened?
Noticed how the steps are in the correct order?
By plainly writing down the dependencies between the steps, `make` helps us to execute them correctly.
@@ -130,7 +130,7 @@ target: [dependencies]
Congratulations! You've learned 90% of what you need to know about `make`.
-## Next steps
+## Next Steps
Real `Makefiles` can do much more! They will [only build the files that have changed](https://stackoverflow.com/a/3798609/270334) instead of doing a full rebuild.
And they will do [as much as possible in parallel](https://stackoverflow.com/a/3841803/270334).
diff --git a/content/2017/obsolete/index.md b/content/2017/obsolete/index.md
index 2302e8f1..64c28d7b 100644
--- a/content/2017/obsolete/index.md
+++ b/content/2017/obsolete/index.md
@@ -42,7 +42,7 @@ There was one problem though: The list of pull requests got longer and longer, a
{{ }}
-## Adding contributors
+## Adding Contributors
I always try to make team members out of regular contributors. My friend and colleague [Andy Grunwald](https://github.com/andygrunwald) as well as [Ouroboros Chrysopoeia](https://github.com/impredicative) are both valuable collaborators. They help me weed out new PRs whenever they find the time.
@@ -57,7 +57,7 @@ What needs to be checked for each new tool can be summarized like this:
I guess it's obvious what we should do with that checklist: automate it!
-## A linter for linting linters
+## A Linter for Linting Linters
So why not write an analysis tool, which checks our list of analysis tools!
What sounds pretty meta, is actually pretty straightforward.
@@ -108,7 +108,7 @@ This allowed me to focus on the actual analysis code,
which makes for a pretty boring read. It mechanically checks for the things mentioned above and could be written in any language.
If you want to have a look (or even contribute!), [check out the repo](https://github.com/mre/awesome-static-analysis-ci).
-## Talking to Github
+## Talking to GitHub
After the analysis code was done, I had a bot, running locally, waiting for incoming pull requests.
@@ -247,7 +247,7 @@ Now, whenever a new pull request is coming in, you see that little bot getting a

-## Outcome and future plans
+## Outcome and Future Plans
I am very pleased with my choice of tools: afterparty saved me from a lot of manual work, while zeit made deployment really easy.
It feels like [Amazon Lambda](https://aws.amazon.com/lambda/features/) on steroids.
@@ -266,7 +266,7 @@ If you like, you can compare the [old](https://github.com/mre/awesome-static-ana
Most everything about that project has changed since then.
I now use Github Actions to run the CI checks, and the `README.md` is completely auto-generated from the YAML files for each tool.
-We support specia metadata fields like a list of additional resources (tutorials, videos, etc) or the list of paid plans a tool offers.
+We support special metadata fields like a list of additional resources (tutorials, videos, etc) or the list of paid plans a tool offers.
We have a [fancy website](https://analysis-tools.dev/) now, where we list all 700+ tools and allow people to vote.
The website is built with Next.js and uses Algolia for search.
We also have a bunch of sponsors now, who help us pay for hosting and other expenses.
diff --git a/content/2017/professional-programming/index.md b/content/2017/professional-programming/index.md
index 277881e1..153e772a 100644
--- a/content/2017/professional-programming/index.md
+++ b/content/2017/professional-programming/index.md
@@ -18,7 +18,7 @@ This article aims to save you from a few years of uncertainty.
Before you dig into this, be sure to read the first part of this series titled ["Why I love Programming"](@/2017/why-i-love-programming/index.md).
-## What's the difference between "professional" and "hobby" programming?
+## What's the Difference between "professional" and "hobby" Programming?
In one word: _accountability_.
You are expected to be responsible.
@@ -44,7 +44,7 @@ Eventually, you'll understand that those neckbeards were not slower than you, bu
more careful. You learn how to test your code, how to document it. You even begin to
appreciate UML diagrams.
-## Becoming obsolete
+## Becoming Obsolete
"The world is moving too fast. What you learned today is obsolete tomorrow. Why bother?".
I've heard that saying countless times throughout my career.
@@ -63,7 +63,7 @@ One advice I can give you is not to take it too seriously.
Drop the project, keep the wisdom.
Embrace change.
-## Writing software in a non-perfect world
+## Writing Software in a Non-Perfect World
A professional programmer has to deal with deficiencies all the time. The game is called "balancing constraints". Deadlines, budgets, and code quality are just a few competing constraints we have to consider.
Elegant designs fade away in the face of reality.
@@ -77,12 +77,12 @@ For me, I was always leaning more towards elegance.
That's just a nicer way to say I was a perfectionist.
I needed to learn the pragmatic part through hard work.
-## Mentoring less experienced Programmers
+## Mentoring Less Experienced Programmers
> The better you become at programming, the less you code.
Instead, you will spend more time thinking about Software Architecture,
-high-level designs and splitting up the work into smaller junks for other developers to consume.
+high-level designs and splitting up the work into smaller chunks for other developers to consume.
You will start mentoring Junior Developers. Recruiting will require a lot of your
attention. You will spend your time in Meetings, discussing project goals with
business people.
@@ -107,7 +107,7 @@ Talk to others, listen to their problems. Read books about Software Project
Management, even though you don't want to be a manager yourself. It will help
you understand the role of your boss.
-## A word about money
+## A Word about Money
There are many good reasons to work in IT, but money is not one of them.
@@ -124,7 +124,7 @@ attempts.
Another way is to stop being a programmer and become a manager instead.
I've already shared my opinion on that in the last section.
-## Final words
+## Final Words
While you should learn to read (and maybe write) code, working as a professional programmer is not for everyone.
You might ask: "Is it worth it?".
diff --git a/content/2017/rust-for-rubyists/index.md b/content/2017/rust-for-rubyists/index.md
index cc3a3949..7d74a52f 100644
--- a/content/2017/rust-for-rubyists/index.md
+++ b/content/2017/rust-for-rubyists/index.md
@@ -131,7 +131,7 @@ for lang in ["Ruby", "Rust", "Python", "Cobol"].iter() {
-## Select and filter
+## Select and Filter
Let's say you want to extract only even numbers from a collection in Ruby.
@@ -280,7 +280,7 @@ The `filter_map` is similar to the `select` method in Ruby:
[1, 2, 3, 4, 5].select { |element| element.even? }
```
-## Random numbers
+## Random Numbers
Here's how to get a random number from an array in Ruby:
@@ -351,7 +351,7 @@ With that, we arrive at a solution that rivals Ruby's elegance.
-## Implicit returns and expressions
+## Implicit Returns and Expressions
Ruby methods automatically return the result of the last statement.
@@ -510,7 +510,7 @@ To quote _[The Book](https://doc.rust-lang.org/book/second-edition/ch18-03-patte
> This prints `no` since the if condition applies to the whole pattern `4 | 5 | 6`, not only to the last value 6.
-## String interpolation
+## String Interpolation
Ruby has [extensive string interpolation support](https://ruby-doc.org/docs/ruby-doc-bundle/ProgrammingRuby/book/ref_m_kernel.html#Kernel.sprintf).
@@ -546,7 +546,7 @@ println!("{language} is also a beautiful programming language", language="Rust")
Rust's `println!()` syntax is even more extensive than Ruby's. [Check the docs](https://doc.rust-lang.org/std/fmt/) if you're curious about what else you can do.
-## That’s it!
+## That’s It!
Ruby comes with syntactic sugar for many common usage patterns, which allows for very elegant code.
Low-level programming and raw performance are no primary goals of the language.
@@ -560,4 +560,4 @@ Did I whet your appetite for idiomatic Rust? Have a look at [this Github project
1. Thanks to Florian Gilcher for the hint.↩2. Thanks to masklin for pointing out multiple inaccuracies.↩
-3. In the first version, I sait that `ok()` would convert a `Result` into a `boolean`, which was wrong. Thanks to isaacg for the correction.↩
+3. In the first version, I said that `ok()` would convert a `Result` into a `boolean`, which was wrong. Thanks to isaacg for the correction.↩
diff --git a/content/2017/rust-url-shortener/index.md b/content/2017/rust-url-shortener/index.md
index 9e440003..ab194f2d 100644
--- a/content/2017/rust-url-shortener/index.md
+++ b/content/2017/rust-url-shortener/index.md
@@ -1,5 +1,5 @@
+++
-title="Launching a URL Shortener in Rust using Rocket"
+title="Launching a URL Shortener in Rust Using Rocket"
date=2017-04-09
updated=2020-08-26
[taxonomies]
@@ -58,7 +58,7 @@ report back?
rustup update && rustup override set nightly
```
-## A first prototype
+## A First Prototype
Now we can start coding our little service.
First, let's write a simple "hello world" skeleton to get started.
@@ -134,14 +134,14 @@ Sweet! Let's call our service.
So far so good.
-## Data storage and lookup
+## Data Storage and Lookup
We need to keep the shortened URLs over many requests... but how?
In a production scenario, we could use some NoSQL data store like [Redis](https://redis.io/) for that.
Since the goal is to play with Rocket and learn some Rust, we will simply use an
in-memory store.
-Rocket has a that feature called [managed state](https://rocket.rs/v0.4/guide/state/).
+Rocket has a feature called [managed state](https://rocket.rs/v0.4/guide/state/).
In our case, we want to manage a _repository_ of URLs.
First, let's create a file named `src/repository.rs`:
@@ -184,7 +184,7 @@ By convention, we implement a `new()` method to create a `Repository` struct wit
Note that we convert the string slices (`&str`) to `String` using the `to_string()` method. This way we don't need to deal with [lifetimes](https://doc.rust-lang.org/book/lifetimes.html). As a beginner, don't think too hard about them.
-## Additional remarks (can safely be skipped)
+## Additional Remarks (Can Safely Be Skipped)
A seasoned (Rust) developer™ might do a few things differently here. Did you notice the tight coupling between the repository and the shortener? In a production system, `Repository` and `Shortener` might simply be concrete implementations of traits (which are a bit like interfaces in other languages, but more powerful). For example, `Repository` could implement a `Cache` trait:
@@ -197,7 +197,7 @@ trait Cache {
}
```
-This way we get clear sepration of concerns, and we can easily switch to a different implementation (e.g. a `RedisCache`). Also, we could have a `MockRepository` to simplify testing. Same for `Shortener`.
+This way we get clear separation of concerns, and we can easily switch to a different implementation (e.g. a `RedisCache`). Also, we could have a `MockRepository` to simplify testing. Same for `Shortener`.
On top of that, you might want to use the `Into` trait to support both, `&str` and `String` as parameters of `store`:
@@ -212,7 +212,7 @@ pub fn store>(&mut self, url: T) -> String {
If you're curious about this, read [this article from Herman J. Radtke III](https://hermanradtke.com/2015/05/06/creating-a-rust-function-that-accepts-string-or-str.html).
For now, let's keep it simple.
-## Actually shortening URLs
+## Actually Shortening URLs
Let's implement the URL shortener itself.
You might be surprised how much was written about URL shortening [all over the web](https://blog.codinghorror.com/url-shortening-hashes-in-practice/).
@@ -226,7 +226,7 @@ To use `harsh`, we add it to the dependency section of our `Cargo.toml`:
harsh = "0.1.2"
```
-Next, we add the crate to the top of to our `main.rs`:
+Next, we add the crate to the top of our `main.rs`:
```
extern crate harsh;
@@ -265,7 +265,7 @@ With `next_id` we retrieve a new `String` id for our URLs.
As you can see, we don't pass the URL to `next_id`. That means we actually _don't shorten anything_. We merely create a short, unique ID. That's because most hashing algorithms produce fairly [long URLs](https://blog.codinghorror.com/url-shortening-hashes-in-practice/) and having short URLs is kind of the whole idea.
-## Wiring it up
+## Wiring It Up
So we are done with our shortener and the repository.
We need to adjust our `src/main.rs` again to make use of the two.
diff --git a/content/2017/why-i-love-programming/index.md b/content/2017/why-i-love-programming/index.md
index 7b408afb..909d7ca7 100644
--- a/content/2017/why-i-love-programming/index.md
+++ b/content/2017/why-i-love-programming/index.md
@@ -24,13 +24,13 @@ The [second part][1] will deal with the notion of [being a professional programm
If you're not sure yet whether you want to learn how to program, this article is for you.
-## Automating stuff gives you superhero strengths
+## Automating Stuff Gives You Superhero Strengths
Being able to program is infinitely rewarding. You can help your sister sort a
thousand pictures in a few seconds. You write a little backup
script for your grandma. The possibilities are endless.
-## Coding is fun!
+## Coding Is Fun!
Coding something is more fun than using it. It's even better than playing games.
Why? Learn how to program a computer and get the best games for free — your own.
@@ -38,7 +38,7 @@ You're in total control. It's your idea, your logic, even your laws of physics.
It's like building a house but without paying anything for the
building materials. You can build a mansion for free.
-## Sharing is fun, too!
+## Sharing Is Fun, Too!
To get new inspiration for your next project, read the programs of others.
This will give you an idea of how they think and how they solve problems.
@@ -48,7 +48,7 @@ Watching somebody else use your work is one
of the most satisfying things you will ever experience.
It's very fulfilling to see your tool serve a purpose it wasn't built for.
-## Elegant, creative solutions
+## Elegant, Creative Solutions
It's very appealing to work so hard on your vision that everything unnecessary peels off.
All these little ideas and fundamental insights suddenly fall into place.
@@ -60,12 +60,12 @@ piece of metal how to solve it.
Even the way your program is structured can be a piece of art.
It can be concise, witty and fast all at the same time.
-## Talk to a machine
+## Talk to a Machine
It's fascinating that something is understood by machines and humans using the same language.
I'm baffled when I realize that these circuits can actually "understand" and interpret words - in a way.
-## Standing on the shoulders of giants
+## Standing on the Shoulders of Giants
Talking to other programmers and watching them work is a fascinating inspiration.
The very system you are using to read this text relies on their work.
@@ -74,12 +74,12 @@ But if you get a chance, watch them giving talks at conferences and meet them at
Becoming part of a community is gratifying.
To exchange ideas and to collaborate on projects helps you push your boundaries and learn something new every day.
-## Have fun, forget the rest
+## Have Fun, Forget the Rest
The machine is agnostic to your skin color. It doesn't matter if you're a twelve-year-old girl or a lecturer at University.
If you keep making the same mistake for ten hours straight, your computer won't scream at you. It won't punish you. It will happily await your commands. Also, the hurdles of entry are pretty low. An old computer is enough; even pen and paper and a book will suffice to work on cool programming ideas.
-## Get started!
+## Get Started!
You choose your own projects; nobody else.
Don't let anybody tell you that you're not smart enough for this stuff. Ever.
diff --git a/content/2017/why-type-systems-matter/index.md b/content/2017/why-type-systems-matter/index.md
index 7b71bf76..f23acf08 100644
--- a/content/2017/why-type-systems-matter/index.md
+++ b/content/2017/why-type-systems-matter/index.md
@@ -17,7 +17,7 @@ It began to feel very natural to me; like a totally new way to express myself.
-## Types are here to help
+## Types Are Here to Help
With types, you communicate your guarantees and expectations. Both, to the machine and other developers. Types express intent.
@@ -34,7 +34,7 @@ It gets a little more tricky if the type gets _inferred_ from some other locatio
sentence = x
```
-Is `sentence` still a string? Uhm... we don't know. It depends on the type of `x`. Maybe `x` is a number, and so `sentence` is also a number? Maybe `x`used to be a string but during refactoring it is now a byte array? Fun times had by all. 🎉
+Is `sentence` still a string? Uhm... we don't know. It depends on the type of `x`. Maybe `x` is a number, and so `sentence` is also a number? Maybe `x` used to be a string but during refactoring it is now a byte array? Fun times had by all. 🎉
What about this one?
@@ -54,7 +54,7 @@ total = file1 + file2
print(total) # prints '50003000'
```
-## How can we fix that?
+## How Can We Fix That?
We can safely assume that a file size is always a number.
To be more precise, it must be a positive, natural number.
@@ -89,7 +89,7 @@ Dare I say it: it becomes an extension of your brain.
After some time you start to rely on the type checker. "If it compiles, it runs"
is a powerful mantra.
-## Types improve readability and provide context
+## Types Improve Readability and Provide Context
Consider the following Python snippet:
@@ -131,7 +131,7 @@ In a larger codebase, `FileStatus.OPEN` is much easier to search for than `0`.
**Note:** The native enum type was [introduced very late in the history of Python](https://www.python.org/dev/peps/pep-0435/). It serves as a nice
example of how enhancing the type system can help improve readability.
-## When you combine different types, magic happens.
+## When You Combine Different Types, Magic Happens.
All pieces suddenly fall into place when you choose your types wisely. Out of nowhere, the compiler will start
checking your design decisions and if all your types work well together. It will point out flaws in your mental model.
diff --git a/content/2017/yes/index.md b/content/2017/yes/index.md
index 6989e98b..f4ba32a7 100644
--- a/content/2017/yes/index.md
+++ b/content/2017/yes/index.md
@@ -1,5 +1,5 @@
+++
-title="A Little Story About the `yes` Unix Command"
+title="A Little Story about the `yes` Unix Command"
date=2017-10-10
updated=2021-04-29
[taxonomies]
@@ -222,11 +222,11 @@ Now that's a whole different ballgame!
- We prepare a filled string buffer, which will be reused for each loop.
- [Stdout is protected by a lock](https://doc.rust-lang.org/std/io/struct.Stdout.html#method.lock). So, instead of constantly acquiring and releasing it, we keep it all the time.
-- We use a the platform-native [`std::ffi::OsString`](https://doc.rust-lang.org/std/ffi/struct.OsString.html) and [`std::borrow::Cow`](https://doc.rust-lang.org/std/borrow/enum.Cow.html) to avoid unnecessary allocations.
+- We use the platform-native [`std::ffi::OsString`](https://doc.rust-lang.org/std/ffi/struct.OsString.html) and [`std::borrow::Cow`](https://doc.rust-lang.org/std/borrow/enum.Cow.html) to avoid unnecessary allocations.
The only thing that I could contribute was [removing an unnecessary `mut`](https://github.com/cgati/yes/pull/3/files). 😅
-## Lessons learned
+## Lessons Learned
The trivial program `yes` turns out not to be so trivial after all.
It uses output buffering and memory alignment to improve performance.
diff --git a/content/2018/cargo-inspect/index.md b/content/2018/cargo-inspect/index.md
index 2a178d91..d818a3ea 100644
--- a/content/2018/cargo-inspect/index.md
+++ b/content/2018/cargo-inspect/index.md
@@ -1,5 +1,5 @@
+++
-title="What Is Rust Doing Behind the Curtains?"
+title="What Is Rust Doing behind the Curtains?"
date=2018-12-02
[taxonomies]
tags=["dev", "rust"]
@@ -49,7 +49,7 @@ Motivated by this quick win, I wrapped it up in a cargo subcommand and called it
Let's try cargo-inspect on some real code!
-## Example - Desugaring a range expression
+## Example - Desugaring a Range Expression
The following examples can also be found in the project's [`examples`](https://github.com/mre/cargo-inspect/tree/master/examples) folder.
@@ -83,7 +83,7 @@ To the compiler backend, these are absolutely the same. So this holds:
assert_eq!((1..3), std::ops::Range { start: 1, end: 3 });
```
-## Example - File handling
+## Example - File Handling
_Input:_
@@ -128,7 +128,7 @@ fn main() -> Result<(), Error> {
}
```
-We can see that the carrier operator `?` gets desugared into a `match` on the `Result` of `File::open`. In case of an error, We apply `std::convert::From::from` to convert between error types. Otherwise, we simply return the `Ok` value.
+We can see that the carrier operator `?` gets desugared into a `match` on the `Result` of `File::open`. In case of an error, we apply `std::convert::From::from` to convert between error types. Otherwise, we simply return the `Ok` value.
## Talk
@@ -137,14 +137,14 @@ Here is the recording:
{{ }}
-## Future work
+## Future Work
I'm not planning to rewrite the compiler here. `rustc` is doing a far greater job than I could. All this functionality already existed before; I'm merely trying to make the compiler more approachable for learners like me.
Right now, the tool is quite fragile. It throws ugly error messages when things go wrong.
It mostly shines, when you run it on small, isolated example snippets.
-## Get involved!
+## Get Involved!
Over on Github, I opened up a few issues for others to get involved.
Namely, I wish there were options to:
diff --git a/content/2018/excel/index.md b/content/2018/excel/index.md
index 0a5136f0..e40ad0f8 100644
--- a/content/2018/excel/index.md
+++ b/content/2018/excel/index.md
@@ -86,7 +86,7 @@ they could also manage via Excel. It was just a glorious Excel form for a
spreadsheet that they maintained manually. I spent two weeks of my summer
vacation to finish that tool because they said they would pay me for that, which, of course, they didn't :).
-## Lessons learned
+## Lessons Learned
- Never underestimate the power of Excel macros.
- If you have a boring task at hand, make it more challenging by adding constraints.
diff --git a/content/2018/fastcat/index.md b/content/2018/fastcat/index.md
index 46291c0c..7c741980 100644
--- a/content/2018/fastcat/index.md
+++ b/content/2018/fastcat/index.md
@@ -83,7 +83,7 @@ cat myfile | pv -r > /dev/null
Uh oh, [GNU cat](https://git.savannah.gnu.org/gitweb/?p=coreutils.git;a=blob;f=src/cat.c;h=3c319511c767f65d2e420b3bff8fa6197ddbb37b;hb=HEAD) is **ten times faster** than our little Ruby cat. 💎🐈🐌
-## Making our Ruby cat a little faster
+## Making Our Ruby cat a Little Faster
Our naive Ruby code can be tweaked a bit.
Turns out line buffering hurts performance in the end1:
@@ -244,7 +244,7 @@ fcat myfile | pv -r > /dev/null
Holy guacamole. That's **over three times as fast as system cat**.
-## Operating System support
+## Operating System Support
- **Linux** and **Android** are fully supported.
- **[OpenBSD](https://stackoverflow.com/questions/12230316/do-other-operating-systems-implement-the-linux-system-call-splice?lq=1)**
@@ -265,7 +265,7 @@ Nevertheless, in a production-grade
implementation, the splice support could be activated on systems that support
it, while using a generic implementation as a fallback.
-## Nice, but why on earth would I want that?
+## Nice, but Why on Earth Would I Want That?
I have no idea. Probably you don't, because your bottleneck is somewhere else.
That said, many people use `cat` for piping data into another process like
@@ -287,7 +287,7 @@ In this case, if you notice that `cat` is the bottleneck try `fcat` (but first,
With some more work, `fcat` could also be used to directly route packets from one
network card to another, [similar to netcat](https://nc110.sourceforge.io/).
-## Lessons learned
+## Lessons Learned
- The closer we get to bare metal, the more our hard-won abstractions fall
apart, and we are back to low-level systems programming.
diff --git a/content/2018/functional-mathematics/index.md b/content/2018/functional-mathematics/index.md
index fc165876..3963e0a4 100644
--- a/content/2018/functional-mathematics/index.md
+++ b/content/2018/functional-mathematics/index.md
@@ -10,7 +10,7 @@ Programming languages help us describe general solutions for problems; the resul
**tl;dr:** *I think that functional programming is better suited for mathematical computations than the more common imperative approach.*
-## Using built-in abstractions for Mathematics
+## Using Built-In Abstractions for Mathematics
The ideas behind a language (the underlying programming paradigms) are distinctive for the community that builds around it. The developers create a unique ecosystem of ready-to-use libraries and frameworks around the language core. As a consequence, some languages are stronger in areas such as business applications (one could think of Cobol), others work great for systems programming (like C or Rust).
@@ -18,9 +18,9 @@ When it comes to solving mathematical and numerical problems with computers, For
One reason for its popularity in this area is that it offers some built-in domain-specific keywords to express mathematical concepts, while keeping an eye on performance. For instance, it has a dedicated datatype for complex numbers – `COMPLEX` – and a keyword named `DIMENSION` which is quite similar to the mathematical term and can be used to create arrays and vectors.
-## Imperative vs functional style
+## Imperative vs Functional Style
-Built-in keywords can help expand the expressiveness of a language into a specific problem space, but this approach is severly limited. It’s not feasible to extend the language core *ad infinitum*; it would just be harder to maintain and take longer to learn. Therefore, most languages provide other ways of abstraction – like *functions*, *subroutines*, *classes* and *objects* – to split a routine into smaller, more manageable parts. These mechanisms might help to control the complexity of a program, but especially when dealing with mathematical problems, one has to be careful not to obfuscate the solution with boilerplate code.
+Built-in keywords can help expand the expressiveness of a language into a specific problem space, but this approach is severely limited. It’s not feasible to extend the language core *ad infinitum*; it would just be harder to maintain and take longer to learn. Therefore, most languages provide other ways of abstraction – like *functions*, *subroutines*, *classes* and *objects* – to split a routine into smaller, more manageable parts. These mechanisms might help to control the complexity of a program, but especially when dealing with mathematical problems, one has to be careful not to obfuscate the solution with boilerplate code.
### Specimen I - Factorial
@@ -61,16 +61,16 @@ fact n = product [1..n]
This is an almost direct translation from the problem definition into code. It needs no explicit types, no temporary variables and no access modifiers (such as public).
-### Specimen II - Dot product
+### Specimen II - Dot Product
One could argue that the above Haskell program owes its brevity to the fact, that the language provides just the right abstractions (namely the `product` keyword and the `[1..n]` range syntax) for that specific task.
-Therfore let’s examine a simple function which is neither available in Haskell nor in Java: The dot product of two vectors. The mathematical definition is as follows:
+Therefore let’s examine a simple function which is neither available in Haskell nor in Java: The dot product of two vectors. The mathematical definition is as follows:

For vectors with three dimensions, it can be written as
-
+
First, a Haskell implementation:
@@ -119,7 +119,7 @@ public static class Vector {
For a proper textual representation of Vectors, the toString() Method would also need to be overwritten. In Haskell, one can simply derive from the `Show` typeclass as shown in the code.
-## Creating new abstractions
+## Creating New Abstractions
If functions and types are not sufficient to write straightforward programs, Haskell also offers simple constructs to create new operators and keywords which extend the language core itself. This makes domain-specific-languages feasible and enables the developer to work more directly on the actual problem instead of working around peculiarities of the programming language itself (such as memory management or array iteration). Haskell embraces this concept; Java has no such functionality.
diff --git a/content/2018/github/index.md b/content/2018/github/index.md
index 066a8655..98a9b7ff 100644
--- a/content/2018/github/index.md
+++ b/content/2018/github/index.md
@@ -21,7 +21,7 @@ Github got acquired by Microsoft.
While I think the acquisition was well-deserved, I still wish it didn't happen.
Let me explain.
-## My early days
+## My Early Days
I joined Github on 3rd of January 2010.
Since I was a bit late to the game, my usual handle ([mre](https://github.com/mre/)) was already taken.
@@ -35,7 +35,7 @@ That was the moment I fell in love with Github.
I felt encouraged to collaborate on projects, that everybody could contribute something valuable.
Only later I found out that Chris was one of the founders and the CEO of the company.
-## Living on Github
+## Living on GitHub
Before Github, there was [SourceForge](https://sourceforge.net/), and I only went there to download binaries.
Github showed me, that there was an entire community of like-minded people
@@ -47,7 +47,7 @@ I can still vividly remember getting my [first star](https://github.com/mre/Crea
After so many years, a pull-request still feels like the most personal gift anyone could give to me.
-## Github - the culture
+## GitHub - The Culture
After a while, I started to admire some Github employees deeply:
@@ -62,7 +62,7 @@ The harassment accusations and letting Zach Holman go are only part of the story
It has become a company like any other, maintaining a mature product.
It doesn't _excite_ me anymore.
-## An alternative reality
+## An Alternative Reality
There's still a bitter taste in my mouth when I think that Github has fallen prey to one of the tech giants. I loved Github while it was a small, friendly community of passionate developers.
Could this have been sustainable?
@@ -79,7 +79,7 @@ a front page where you could filter and search for events, a better way to handl
These features would be targeted at the top 10% of Github users, a group of 3 million people.
Would this be enough to pay the bills? Probably. Would it be enough to grow? Probably not.
-## So what?
+## So What?
I don't think the acquisition will kill the culture. Microsoft is a strong partner and [Nat Friedman](https://nat.github.io/hello/) is one of us.
On the other side, I'm not as enthusiastic as I used to be.
diff --git a/content/2018/go-io-testing/index.md b/content/2018/go-io-testing/index.md
index 24656071..c3f9ca42 100644
--- a/content/2018/go-io-testing/index.md
+++ b/content/2018/go-io-testing/index.md
@@ -22,7 +22,7 @@ The idea was to avoid file handling in unit tests without mocking or using tempo
I was surprised that I couldn't find a simple explanation on sites like StackOverflow,
which is why I wrote down some notes myself so that others can refer to it in the future.
-## Our example code
+## Our Example Code
The initial version looked like this:
@@ -58,7 +58,7 @@ func analyze(file string) error {
As you can see, we take a filename as input, and we open that file inside the `analyze` function to do something with its contents.
-## Writing our first test for the code
+## Writing Our First Test for the Code
A typical test harness for that code might look like this:
@@ -98,7 +98,7 @@ In my opinion, mocking should be the last resort when it comes to testing. Befor
Maybe implementing against an interface or using Dependency Injection helps decouple components?
More often than not, a clear separation of concerns is all you need.
-## Refactoring to make testing easier
+## Refactoring to Make Testing Easier
In my case above, we can easily avoid using mocks and temporary files by decoupling file I/O from the analysis.
We do so by refactoring our `analyze` function to call `doSomething`, which takes an [`io.Reader`](https://golang.org/pkg/io/#Reader).
diff --git a/content/2018/keyboard/index.md b/content/2018/keyboard/index.md
index 60110e72..f0405839 100644
--- a/content/2018/keyboard/index.md
+++ b/content/2018/keyboard/index.md
@@ -17,7 +17,7 @@ I was looking for a similar article before jumping the gun, but I couldn't find
{{ }}
-## Why Switch To the US Layout?
+## Why Switch to the US Layout?
I was reasonably efficient when writing prose, but felt like
a [lemur on a piano](https://www.etsy.com/listing/896826954/funny-piano-art-print-leptodactylous-aye) when programming:
@@ -51,7 +51,7 @@ finally make the switch.
{{ }}
-## How Long Did It Take To Get Accustomed To The New Layout?
+## How Long Did It Take to Get Accustomed to the New Layout?
Working as a Software Engineer, my biggest fear was, that the switch would slow
down my daily work. This turned out not to be true. I was reasonably productive
@@ -78,7 +78,7 @@ reason why Vim is using `/` for search or why the pipe symbol is `|`: both are
easy to reach! [It all makes sense!](/2018/ten-years-of-vim)
(For a fun time, try that on a German keyboard!)
-I understand why Mircosoft chose `\` as a directory separator: it's easily
+I understand why Microsoft chose `\` as a directory separator: it's easily
accessible from a US keyboard. On the German layout, it's… just… awful
(`Alt Gr`+`ß` on Windows, `Shift` + `Option` + `7` on Mac).
@@ -109,7 +109,7 @@ me. It allows me to use a single Keyboard layout but insert German umlauts at wi
[Karabiner](https://www.stefanimhoff.de/) rule which does the same. Might come
in handy in case you already use this tool.
-## Is Switching Between Keyboards Painful?
+## Is Switching between Keyboards Painful?
{{ }}
@@ -118,7 +118,7 @@ the internal German and the external English keyboard would confuse me. This
turned out not to be a problem. I rarely look at the print anyway.
(Update: can't remember when I last looked at the print.)
-## How Often Do You Switch Back To A German Layout Now?
+## How Often Do You Switch Back to a German Layout Now?
Never. My Girlfriend has a German keyboard and every time I have to use it, I switch to the US layout. It makes her very happy when I do this and forget to switch back to German when I'm done.
diff --git a/content/2018/ls/index.md b/content/2018/ls/index.md
index 39e01419..8483501b 100644
--- a/content/2018/ls/index.md
+++ b/content/2018/ls/index.md
@@ -18,7 +18,7 @@ As we will find out, `ls` is actually quite a powerful tool under the hood.
I'm not going to come up with a full rewrite, but instead only cover the very basic output that you would expect from calling `ls -l` on your command line.
What is this output? I'm glad you asked.
-## Expected output
+## Expected Output
```
> ls -l
@@ -44,7 +44,7 @@ For more in-depth information, I can recommend reading the manpage of `ls` from
Whew, that's a lot of information for such a tiny tool.
But then again, it can't be so hard to port that to Rust, right? Let's get started!
-## A very basic `ls` in Rust
+## A Very Basic `ls` in Rust
Here is the most bare-bones version of `ls`, which just prints all files in the current directory:
@@ -95,7 +95,7 @@ _Pro Tip_: You can install the binary with `cargo install` and call it like any
But we have higher goals, so let's continue.
-## Adding a parameter to specify the directory
+## Adding a Parameter to Specify the Directory
Usually, if we type `ls mydir`, we expect to get the file listing of no other directory than `mydir`. We should add the same functionality to our version.
@@ -142,7 +142,7 @@ There are tons of configuration options, so it's worth checking out the [project
Also note, that we changed the type of the path variable from `Path` to `PathBuf`. The difference is, that [`PathBuf` owns the inner path string](https://doc.rust-lang.org/src/std/path.rs.html#1107-1109), while `Path` [simply provides a reference to it](https://doc.rust-lang.org/src/std/path.rs.html#1629-1631). The relationship is similar to `String` and `&str`.
-## Reading the modification time
+## Reading the Modification Time
Now let's deal with the metadata.
First, we try to retrieve the modification time from the file.
@@ -222,7 +222,7 @@ It means "right align this field with a space padding of 5" - just like our bigg
Similarly, we retrieved the size in bytes with `metadata.len()`.
-## Unix file permissions are a zoo
+## Unix File Permissions Are a Zoo
Reading the file permissions is a bit more tricky.
While the `rwx` notation is very common in Unix derivatives such as \*BSD or GNU/Linux, many other operating systems ship their own permission management.
@@ -236,7 +236,7 @@ Wikipedia lists a few extensions to the file permissions that you might encounte
That just goes to show, that there are a lot of important details to be considered when implementing this in real life.
-## Implementing very basic file mode
+## Implementing Very Basic File Mode
For now, we just stick to the basics and assume we are on a platform that supports the `rwx` file mode.
@@ -313,7 +313,7 @@ fn triplet(mode: u16, read: u16, write: u16, execute: u16) -> String {
}
```
-## Wrapping up
+## Wrapping Up
The final output looks like this. Close enough.
diff --git a/content/2018/rust-2018/index.md b/content/2018/rust-2018/index.md
index 9f756bab..ed37a58a 100644
--- a/content/2018/rust-2018/index.md
+++ b/content/2018/rust-2018/index.md
@@ -15,7 +15,7 @@ I'm a bit late to the party, but here are my 2 cents about the priorities for Ru
-## Who _is_ this guy?
+## Who _Is_ This Guy?
There's a depressingly high chance that we've never met before — which is a real shame.
For some context: I come from dynamically typed languages like Python and PHP.
@@ -24,7 +24,7 @@ Rust was the first language that allowed me to write _real_ low-level code witho
To me, Rust is not a [fireflower](https://brson.github.io/fireflowers/), it's my own personal [Megazord](https://en.wikipedia.org/wiki/Power_Rangers)1.
I want Rust to win, but for that, we need to tick a few points off the list.
-## Compiler documentation for easier contribution
+## Compiler Documentation for Easier Contribution

@@ -39,7 +39,7 @@ Hence my first wish is, that contributing to the language will become easier.
That could be achieved by providing extensive mentorship, more entry-level tickets, and [better compiler documentation](https://internals.rust-lang.org/t/so-you-want-to-hack-on-the-rust-compiler-a-plan-for-a-book/6497).
All of that was already [suggested by Niko](https://smallcultfollowing.com/babysteps/blog/2018/01/05/lessons-from-the-impl-period/).
-## More resources for intermediate programmers
+## More Resources for Intermediate Programmers
On a related note, I'd like to see more talks/guidelines/books targeting intermediate Rust programmers.
This includes discussions on how to structure [big projects](https://github.com/servo/servo) in Rust and Rust-specific [design patterns](https://github.com/rust-unofficial/patterns).
@@ -47,7 +47,7 @@ I want to read more about professional Rust usage and see case-studies from vari
For example, there was a startup called snips.ai, which built an on-device voice-assistant using Rust.
They integrated with C and C++ libraries and [I want to hear more about their journey](https://medium.com/snips-ai/snips-big-wish-for-rust2018-libraries-or-portability-pick-two-814d104586d9).
-## Improve the RFC process
+## Improve the RFC Process
I try to follow the RFC process very closely, but my time is limited.
My wish is, that I can open any RFC and immediately get its status:
@@ -62,7 +62,7 @@ Github is great for code, but conversations about new features regularly get out
This is not a problem, that is limited to Rust, either. Just look at other big projects like Docker, Kubernetes, or Node.
Maybe we need a new tool for that.
-## The usual suspects
+## The Usual Suspects
If I could ask for two stable features in 2018, it would be [`?` in main](https://github.com/rust-lang/rust/issues/43301)
and [non-lexical lifetimes](https://github.com/rust-lang/rust/issues/44928).
diff --git a/content/2018/ten-years-of-vim/index.md b/content/2018/ten-years-of-vim/index.md
index 8c43902a..cf3ec5bd 100644
--- a/content/2018/ten-years-of-vim/index.md
+++ b/content/2018/ten-years-of-vim/index.md
@@ -50,7 +50,7 @@ This painful process is what Vim tries to make at least bearable. It helps you k
It does that, by providing you sharp, effective tools to modify text.
The core of Vim is a language for editing text.
-## Vim, The Language
+## Vim, the Language
The Vim commands are not cryptic, you already know them.
@@ -71,7 +71,7 @@ That's why, by default, you are in [normal mode](https://en.wikibooks.org/wiki/L
Once you know this, Vim makes a lot more sense, and that's when you start to be productive.
-## How My Workflow Changed Over The Years
+## How My Workflow Changed over the Years
When I was a beginner, I was very interested in how people with more Vim experience would use the editor.
Now that I'm a long-time user, here's my answer: there's no secret sauce.
@@ -115,7 +115,7 @@ Here are a few things I wish I could do better:
- **Multiple registers for copy and paste**: Right now I only use one register (like a pastebin) for copying text, but Vim supports multiple registers. That's cool if you want to move around more than one thing at the same time. [Let's use more of those!](https://vim.fandom.com/wiki/Copy%2c_cut_and_paste)
- **Tabs**: I know [how tabs work](https://vim.fandom.com/wiki/Using_tab_pages), but all the typing feels clunky. That's why I never extensively used them. Instead, I mostly use multiple terminal tabs or an IDE with Vim bindings for bigger projects.
-## Would I learn Vim again?
+## Would I Learn Vim Again?
That's a tough question to answer.
diff --git a/content/2019/maybe-you-dont-need-kubernetes/index.md b/content/2019/maybe-you-dont-need-kubernetes/index.md
index 85c609e3..c67e98b3 100644
--- a/content/2019/maybe-you-dont-need-kubernetes/index.md
+++ b/content/2019/maybe-you-dont-need-kubernetes/index.md
@@ -68,7 +68,7 @@ required:
- Have a common place to share configurations and secrets.
- Provide an endpoint for metrics and logging.
-## Why Kubernetes Was Not A Good Fit For Us
+## Why Kubernetes Was Not a Good Fit for Us
When creating a prototype with Kubernetes, we noticed that we started adding
ever-more complex layers of logic to operate our services. Logic on which we
@@ -91,7 +91,7 @@ goes on and on. Not all tools are necessary to get started with Kubernetes, but
it’s hard to know which ones are, so you have to be at least aware of them.
Because of that, the learning curve is quite steep.
-## When To Use Kubernetes
+## When to Use Kubernetes
At trivago specifically, many teams use Kubernetes and are quite happy with it.
These instances are managed by Google or Amazon however, which have the capacity to do so.
@@ -136,7 +136,7 @@ vendor lock-in because the functionality it provides can easily be integrated
into any other system that manages services. It just runs as a plain old single
binary on every machine in your cluster; that's it!
-## The Nomad Ecosystem Of Loosely Coupled Components
+## The Nomad Ecosystem of Loosely Coupled Components
The real power of Nomad lies within its ecosystem. It integrates very well with
other - completely optional - products like [Consul] (a key-value store) or
diff --git a/content/2019/tinysearch/index.md b/content/2019/tinysearch/index.md
index f4765726..d8ff6e1f 100644
--- a/content/2019/tinysearch/index.md
+++ b/content/2019/tinysearch/index.md
@@ -1,5 +1,5 @@
+++
-title="A Tiny, Static, Full-Text Search Engine using Rust and WebAssembly"
+title="A Tiny, Static, Full-Text Search Engine Using Rust and WebAssembly"
date=2019-10-17
updated=2022-02-15
[taxonomies]
@@ -68,7 +68,7 @@ creates a tiny, self-contained search index using this magical data structure
called a
✨*Bloom Filter* ✨.
-## Wait, what's a Bloom Filter?
+## Wait, What's a Bloom Filter?
A [Bloom filter](https://en.wikipedia.org/wiki/Bloom_filter) is a space-efficient way to
check if an element is in a set.
@@ -152,7 +152,7 @@ clue how to package it for the web... until [wasm-pack came along in
February
2018](https://github.com/rustwasm/wasm-pack/commit/125431f97eecb6f3ca5122f8b345ba5b7eee94c7).
-## Whoops! I Shipped Some Rust Code To Your Browser.
+## Whoops! I Shipped Some Rust Code to Your Browser.
Now I had all the pieces of the puzzle:
@@ -405,7 +405,7 @@ If you get something working for your static site generator, [please let me know
website, check out [sonic](https://journal.valeriansaliou.name/announcing-sonic-a-super-light-alternative-to-elasticsearch/).
Also check out [stork](https://github.com/jameslittle230/stork) as an alternative.
-## Try it!
+## Try It!
The code for [tinysearch is on Github](https://github.com/mre/tinysearch).
diff --git a/content/2020/cratesio/index.md b/content/2020/cratesio/index.md
index 9d73b8f1..3583c1ef 100644
--- a/content/2020/cratesio/index.md
+++ b/content/2020/cratesio/index.md
@@ -1,5 +1,5 @@
+++
-title="Name-squatting on crates.io - Do we have a problem?"
+title="Name-Squatting on crates.io - Do We Have a Problem?"
date=2020-08-20
draft=true
[taxonomies]
@@ -31,7 +31,7 @@ and newcomers have to deal with that. And then it gets deprecated. And then you
Using PHP's composer felt like a breath of fresh air in comparison.
Namespaces made these problems go away.
-## What is name squatting?
+## What Is Name Squatting?
Name squatting is like Germans reserving all the loungers near the pool.
It's become a meme: https://www.youtube.com/watch?v=nzHihXOiNqk
@@ -56,7 +56,7 @@ people can still publish stuff under your "namespace"
https://github.com/google/evcxr
-## How many names are squatted?
+## How Many Names Are Squatted?
Squatted names by length
diff --git a/content/2020/folklore/index.md b/content/2020/folklore/index.md
index 32fc2ec2..781cfb2b 100644
--- a/content/2020/folklore/index.md
+++ b/content/2020/folklore/index.md
@@ -167,7 +167,7 @@ line-feed:
{{ }}
-## Command key symbol (⌘)
+## Command Key Symbol (⌘)
_Today's meaning: A meta-key available on Apple computers to provide additional
keyboard combinations._
@@ -195,7 +195,7 @@ down, notably Borgholm Castle.
{{ }}
-{{ }}
References:
@@ -458,7 +458,7 @@ being on the outside, protecting the kernel.
[Reference](https://unix.stackexchange.com/questions/14934/why-was-the-word-shell-used-to-descibe-a-command-line-interface)
-## Slab allocator
+## Slab Allocator
_Today's meaning: An efficient memory allocation technique, which reuses
previous allocations._
@@ -471,7 +471,7 @@ Bonwick](https://www.usenix.org/publications/library/proceedings/bos94/full_pape
> With slab allocation, a cache for a certain type or size of data object has a
> number of pre-allocated "slabs" of memory; within each slab there are memory
> chunks of fixed size suitable for the objects.
-> ([Wikpedia](https://en.wikipedia.org/wiki/Slab_allocation#Basis))
+> ([Wikipedia](https://en.wikipedia.org/wiki/Slab_allocation#Basis))
The name _slab_ comes from a teenage friend of Bonwick. He [tells the
story](https://blogs.oracle.com/bonwick/now-it-can-be-told) on the Oracle blog:
@@ -547,12 +547,12 @@ radio buttons (right). Only a single option can be selected at any point in
time. As a kid, I would push two buttons at once so they would interlock. Good
times." credits="Images by [Matt Coady](https://twitter.com/themattcoady)" /> }}
-## Uppercase and lowercase
+## Uppercase and Lowercase
_Today's meaning: Distinction between capital letters and small letters on a
keyboard._
-Back when typesetting was a manual process where single letters made of led were
+Back when typesetting was a manual process where single letters made of lead were
"type set" to form words and sentences, upper- and lowercase letters were kept
in separate containers — or cases — to make this rather tedious process a little faster.
@@ -560,7 +560,7 @@ in separate containers — or cases — to make this rather tedious proc
survivals' by Updike, Daniel Berkeley, 1860-1941. [Freely available on
archive.org](https://archive.org/details/printingtypesthe01updi/)." /> }}
-## Honorable mentions
+## Honorable Mentions
### 404
@@ -576,7 +576,7 @@ This, however, seems to be a myth and the status code was chosen rather
arbitrarily based on the then well-established FTP status codes.
[Reference](https://knowyourmeme.com/memes/404)
-## Programming languages and Abbreviations
+## Programming Languages and Abbreviations
The etymology of programming language names and common abbreviations would
probably warrant its own article, but I've decided to note down some of my
@@ -607,7 +607,7 @@ Commons](https://commons.wikimedia.org/wiki/File:Treblecsharp5.svg)" /> }}
Officially, PNG stands for _Portable Network Graphics_. It was born out of
frustration over a CompuServe announcement in 1994 that programs supporting GIF
-would have to pay licensing fees from now on. A working group lead by hacker
+would have to pay licensing fees from now on. A working group led by hacker
[Thomas Boutell](https://boutell.dev/) created the `.webp` file format, a
patent-free replacement for GIF. Therefore I prefer the format's unofficial
name: _PNG's Not GIF_. Here's a [great
diff --git a/content/2020/go-is-not-simple/foo.md b/content/2020/go-is-not-simple/foo.md
index 62bd0e31..d8f95bdb 100644
--- a/content/2020/go-is-not-simple/foo.md
+++ b/content/2020/go-is-not-simple/foo.md
@@ -1,5 +1,5 @@
+++
-title="Go is Simple"
+title="Go Is Simple"
date=2020-05-29
draft=true
+++
@@ -241,7 +241,7 @@ In 99% of the cases, you don't **need** enums so it's better to omit that keywor
Here's something real that I have to do from time to time:
-## Finding the unique elements in a slice
+## Finding the Unique Elements in a Slice
```go
import "fmt"
@@ -326,7 +326,7 @@ print(google_search_nightmares)
Oh shut up Python! You share your name with an animal; that won't make searching any easier.
Oh, it's about the `intersection()` method? Yeah we can totally add that, too in Go.
We just have to write a few more lines of code.
-And while we're add it we can add `union()` and `member()` and `difference()`, too!
+And while we're at it we can add `union()` and `member()` and `difference()`, too!
Golang is the only mainstream language that teaches you how to implement basic datastructures yourself.
Wait a sec. Nobody does that in real life. That's what libraries are for!
diff --git a/content/2020/go-is-not-simple/index.md b/content/2020/go-is-not-simple/index.md
index 01ffe725..730e0367 100644
--- a/content/2020/go-is-not-simple/index.md
+++ b/content/2020/go-is-not-simple/index.md
@@ -1,5 +1,5 @@
+++
-title="Go is not Simple"
+title="Go Is Not Simple"
date=2020-05-29
draft=true
[taxonomies]
@@ -237,7 +237,7 @@ Go is the modern C
Leads to bugs and people using Go for projects it was never designed for like Docker.
-The Go standard libary
+The Go standard library
"batteries included"
a terrible builtin json library,
@@ -258,7 +258,7 @@ Go is often misunderstood
- inside the Google team
- microservices
-If thoes assumptions hold, Go is the way to go.
+If those assumptions hold, Go is the way to go.
Things start becoming interesting when one or more assumptions are incorrect.
Writing 100kloc projects in Go will make you miss generics
@@ -276,7 +276,7 @@ I'm just from a different school of thought.
imposing a disproportionate cost on users.o
-inconsistenjt
+inconsistent
repo := &github.Repository{
Name: github.String("migrate-test"),
@@ -300,7 +300,7 @@ on the other side, errors are hidden when they were used "once"
response, err := bla()
response, err := bar() // no new variables
-Sometimes yo don't have a better name for a variable...
+Sometimes you don't have a better name for a variable...
Have to change to `=`
Especially annoying during debugging
Why can't I use `:=` in general?
@@ -365,7 +365,7 @@ Concurrency
Typeclasses carry value with them
-The lazyness is also part of the build system
+The laziness is also part of the build system
`go build` and `go run` behave differently...
```go
diff --git a/content/2020/perf/index.md b/content/2020/perf/index.md
index cfab26e4..c82f6eb5 100644
--- a/content/2020/perf/index.md
+++ b/content/2020/perf/index.md
@@ -8,7 +8,7 @@ tags=["dev"]
excerpt="""Did I mention that this website is fast?
Oh yeah, I did, multiple times.
It's never fast enough, so today I go one step further by adding
-support for the new AVIF image format to the blog. The results were suprising.
+support for the new AVIF image format to the blog. The results were surprising.
"""
+++
@@ -35,7 +35,7 @@ Then again, it's 2020: **everyone** is optimizing their favicons, right? [...rig
Well, it turns out most other sites don't think about their user's data plans as much as I do. Actually, that's an understatement: they don't care at all. But to me, **lean is beautiful**!
-## Wait, What About Images?
+## Wait, What about Images?
I prefer SVG for diagrams and illustrations.
Only if it's a photo, I'll use JPEG or [WebP](https://developers.google.com/speed/webp/).
@@ -89,7 +89,7 @@ If that reads "nope," then you have a few options:
- **On Chrome**: Make sure to update to the latest version.
- **On Safari**: I'm not sure what you're doing with your life. Try a real browser instead. 😏
-## Workaround I: Fallback For Older Browsers
+## Workaround I: Fallback for Older Browsers
HTML is great in that your browser ignores unknown new syntax.
So I can use the `` element to serve the right format to you. (Look ma, no JavaScript!)
@@ -106,7 +106,7 @@ So I can use the `` element to serve the right format to you. (Look ma,
thing](https://github.com/mre/endler.dev/blob/master/templates/components/figure.html)
is a bit more convoluted, but you get the idea.
-## Workaround II: Wrong Content-Type On Github Pages
+## Workaround II: Wrong Content-Type on GitHub Pages
There was one ugly problem with Github and AVIF, though: Their server returned a
`Content-Type: application/octet-stream` header.
@@ -135,7 +135,7 @@ You can read more about modifying response objects [here](https://developers.clo
Another side-effect of Workers Sites is that a production deployment takes [one minute](https://github.com/mre/endler.dev/actions) now.
-## Performance Results After Moving To Cloudflare
+## Performance Results after Moving to Cloudflare
{{ }}
{{ }}
@@ -147,7 +147,7 @@ I don't have to hide from a comparison with well-known sites either:
{{ }}
-## Further reading
+## Further Reading
- [How to Use AVIF: The New Next-Gen Image Compression Format](https://reachlightspeed.com/blog/using-the-new-high-performance-avif-image-format-on-the-web-today/) — Nice introduction that highlights some common pitfalls when integrating AVIF. It inspired me to add AVIF support.
- [AVIF has landed](https://jakearchibald.com/2020/avif-has-landed/) by Jake Archibald — Compares image sizes and qualities of different formats: SVG, JPEG, PNG, WebP, and AVIF.
diff --git a/content/2020/review/index.md b/content/2020/review/index.md
index 4897c36e..847abe16 100644
--- a/content/2020/review/index.md
+++ b/content/2020/review/index.md
@@ -1,5 +1,5 @@
+++
-title="What Happened To Programming In The 2010s?"
+title="What Happened to Programming in the 2010s?"
date=2020-07-02
updated=2021-10-11
draft=false
@@ -25,7 +25,7 @@ don't sue me.
My goal is to reflect on the past so that you can better predict the future.
{% %}
-## Where To Start?
+## Where to Start?
From a mile-high perspective, programming is still the same as a decade ago:
@@ -54,7 +54,7 @@ Pi](https://en.wikipedia.org/wiki/Raspberry_Pi) (which only got released in
{{ }}
-## An Explosion Of New Programming Languages
+## An Explosion of New Programming Languages
The last decade saw the creation of a vast number of new and exciting programming
languages.
@@ -117,7 +117,7 @@ Most languages adopted a quicker release cycle. Here's a list for some popular l
| Swift | 6 months |
| Visual Basic .NET | ~ 24 months |
-## The Slow Death Of Null
+## The Slow Death of Null
Close to the end of the last decade, in a talk from 25thof August 2009,
Tony Hoare described the `null` pointer as his [Billion Dollar
@@ -142,7 +142,7 @@ C++, Go, Kotlin, Swift, and Rust are popular examples with type inference suppor
can only speak for myself, but I think writing Java has become a lot more
ergonomic in the last few years.
-## Exponential Growth Of Libraries and Frameworks
+## Exponential Growth of Libraries and Frameworks
As of today, npm hosts [1,330,634 packages](https://www.npmjs.com/). That's over a million
packages that somebody else is maintaining for you. Add another [160,488 Ruby
@@ -177,7 +177,7 @@ It has held up surprisingly well in the last decade:
There's a catch, though.
Looking at single-core performance, the curve is flattening:
-{{ }}
+{{ }}
The new transistors prophesied by Moore don’t make our CPUs faster but instead
add other kinds of processing capabilities like more parallelism or hardware
@@ -198,7 +198,7 @@ parallel computations, which caused a renaissance of Machine Learning for practi
_Compute_ is ubiquitous, so in most cases, energy efficiency plays a more prominent role now than raw performance (at least for consumer devices).
-## Unlikely Twists Of Fate
+## Unlikely Twists of Fate
- Microsoft is a cool kid now. It acquired Github, announced the [Windows subsystem for Linux](https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux) (which should really be called Linux Subsystem for Windows), open sourced
[MS-DOS](https://github.com/Microsoft/MS-DOS) and [.NET](http://news.microsoft.com/2014/11/12/microsoft-takes-net-open-source-and-cross-platform-adds-new-development-capabilities-with-visual-studio-2015-net-2015-and-visual-studio-online/).
diff --git a/content/2020/sponsors/index.md b/content/2020/sponsors/index.md
index e52b0378..0404b3ec 100644
--- a/content/2020/sponsors/index.md
+++ b/content/2020/sponsors/index.md
@@ -1,5 +1,5 @@
+++
-title = "Launching a Side Project Backed by Github Sponsors"
+title = "Launching a Side Project Backed by GitHub Sponsors"
date = 2020-08-21
[taxonomies]
tags=["oss", "business"]
@@ -183,7 +183,7 @@ functionality was broken (of course). Turns out, we hit the free quota limit on
exchange with Algolia's customer support, and they moved us over to the
open-source plan (which we didn't know existed). We were back on track!
-> Site note: Algolia customer support is top-notch. Responsive, tech-savvy,
+> Side note: Algolia customer support is top-notch. Responsive, tech-savvy,
> and helpful. Using Algolia turned out to be a great fit for our product.
> Response times are consistently in the low milliseconds and the integration
> with Gatsby was quick and easy.
@@ -219,7 +219,7 @@ analysis and he approved. (Thanks boss!)
High fives all around!
-## Now what?
+## Now What?
Of course, we'll add new features; of course, we have more plans for the future,
yada yada yada. Instead, let's reflect on that milestone: a healthy little
diff --git a/content/2020/timelapse/index.md b/content/2020/timelapse/index.md
index 247c8330..f7672483 100644
--- a/content/2020/timelapse/index.md
+++ b/content/2020/timelapse/index.md
@@ -17,7 +17,7 @@ this project's journey. It just took _ten years_ to get here.
{{ }}
-## 2011 - How it all began
+## 2011 - How It All Began
To be honest, I don't remember why I initially wrote the tool. I must have had a
personal need for a screen recorder, I guess...
diff --git a/content/2020/unix-microservices/index.md b/content/2020/unix-microservices/index.md
index 0d2976a6..5062d85a 100644
--- a/content/2020/unix-microservices/index.md
+++ b/content/2020/unix-microservices/index.md
@@ -1,5 +1,5 @@
+++
-title="No, microservices are not embracing the Unix philosophy"
+title="No, Microservices Are Not Embracing the Unix Philosophy"
date=2019-04-01
draft=true
+++
@@ -18,7 +18,7 @@ Glue code between the services: request handling, logging
You're not building small, composable tools, you're building a distributed system!
-I'm pretty sure when Thompson, Ritchie, and McIllroy established the Unix Philosphoy, they didn't have microservices in mind.
+I'm pretty sure when Thompson, Ritchie, and McIlroy established the Unix Philosophy, they didn't have microservices in mind.
From running many microservices in production, they can be very fragile.
Avoid State
@@ -28,7 +28,7 @@ It's true, microservices are easy to write. The hard part is operations.
This is where they differ from Unix tools.
Unix tools: `cat`, `ls`, `rm`.
-Microservices: Account managemer, cache, geoip service, kiosk service.
+Microservices: Account manager, cache, geoip service, kiosk service.
A lot more moving parts. A lot more things that can go wrong.
Other systems instead lump these into a single "account management" service with an internal structure and command language of its own.
diff --git a/content/2021/codeprints/index.md b/content/2021/codeprints/index.md
index ac2366b4..4616c32d 100644
--- a/content/2021/codeprints/index.md
+++ b/content/2021/codeprints/index.md
@@ -1,5 +1,5 @@
+++
-title="Starting A Print-On-Demand Business As A Software Engineer"
+title="Starting a Print-on-Demand Business as a Software Engineer"
date=2021-01-22
[taxonomies]
tags=["business"]
@@ -15,7 +15,7 @@ It's my first "physical" product, so I decided to share my learnings.
of our first customers and we are very thankful for this tweet promoting our
service, which gave us a huge traffic boost." link="https://twitter.com/KrauseFx/status/1348546742644580353" /> }}
-## Launching Is Hard, So Launch Early
+## Launching Is Hard, so Launch Early
Even though I knew that launching early was vital, I still didn't want to
"commit" to the final design shortly before the planned go-live. There was always that last bug to fix or that little extra feature to implement.
@@ -111,7 +111,7 @@ You'll have to say "no" more often than you can say "yes".
entirely built remotely. More people should give [whereby](https://whereby.com/)
a try." /> }}
-## Getting Traction As A Small Business
+## Getting Traction as a Small Business
It has never been easier to launch a shop. Services like Shopify, Stripe, and a
host of suppliers make starting out a breeze. On the other hand, there is a lot
@@ -133,7 +133,7 @@ hang out there that much.
**Lesson learned:** Always know where your customers are and understand their needs.
{% %}
-## Finding A Niche Is Only Half The Job
+## Finding a Niche Is Only Half the Job
[Common market wisdom](https://www.reddit.com/r/startups/comments/53fynp/niche_market_and_peter_thiels_monopoly_theory/) is to find niche and grow from within. With codeprints we definitely found our niche: the audience is very
narrow but interested in our geeky products. There are 56 million developers on
diff --git a/content/2021/first-business/index.md b/content/2021/first-business/index.md
index 2d2fe316..69aceeed 100644
--- a/content/2021/first-business/index.md
+++ b/content/2021/first-business/index.md
@@ -1,5 +1,5 @@
+++
-title = "Spreadsheets Make For Great Business Ideas"
+title = "Spreadsheets Make for Great Business Ideas"
date = 2021-03-10
updated = 2025-04-24
[taxonomies]
diff --git a/content/2021/history/index.md b/content/2021/history/index.md
index b4248daf..e8fe188b 100644
--- a/content/2021/history/index.md
+++ b/content/2021/history/index.md
@@ -1,5 +1,5 @@
+++
-title="How Does The Unix `history` Command Work?"
+title="How Does the Unix `history` Command Work?"
date=2021-05-31
draft=false
[taxonomies]
@@ -17,14 +17,14 @@ in Rust and throw it away again in the end as we uncover the truth.
{{ }}
As the day is winding down, I have a good hour just to myself.
-Perfect time to listen to some [Billie Joel](https://www.youtube.com/watch?v=cJtL8vWNZ4o) (it's either Billie Joel or Billie Eilish for me these days) and learn how the Unix `history` command works.
+Perfect time to listen to some [Billy Joel](https://www.youtube.com/watch?v=cJtL8vWNZ4o) (it's either Billy Joel or Billie Eilish for me these days) and learn how the Unix `history` command works.
Life is good.
Learning what makes Unix tick is a bit of a hobby of mine.
I covered [yes](/2017/yes/), [ls](/2018/ls/), and [cat](/2018/fastcat/) before.
Don't judge.
-## How does history even work?
+## How Does history Even Work?
Every command is tracked, so I see the last few commands on my machine when I run `history`.
@@ -37,7 +37,7 @@ Every command is tracked, so I see the last few commands on my machine when I ru
8685 vim index.md
```
-## Yeah, but how does it _do_ that?
+## Yeah, but How Does It _Do_ That?
The manpage on my mac is not really helpful — I also couldn't find much in the first place.
@@ -312,7 +312,7 @@ We open a new shell and run a few commands followed by `history`:
✨ **Yay.** ✨ [The source code for `past` is on Github.](https://github.com/mre/past)
-## How it _really_ _really_ works
+## How It _Really_ _Really_ Works
Our experiment was a great success, but I since learned that reality is a bit different.
@@ -362,14 +362,14 @@ to prevent the history from getting too big. ([See here](https://github.com/zsh-
That's smart! Without the ring-buffer, a malicious user could just thrash the history with random commands
until a buffer overflow is triggered. I never thought of that.
-## History time (see what I did there?)
+## History Time (See What I Did There?)
The original `history` command was added to the Unix C shell (csh) in 1978.
Here's a link to [the paper](https://web.archive.org/web/20220605000427/http://www.kitebird.com/csh-tcsh-book/csh-intro.pdf) by [Bill Joy](https://en.wikipedia.org/wiki/Bill_Joy) (hey, another Bill!).
He took inspiration from the `REDO` command in Interlisp.
You can find its specification in the original Interlisp manual in [section 8.7](https://larrymasinter.net/86-interlisp-manual-opt.pdf).
-## Lessons learned
+## Lessons Learned
- Rebuild what you don't understand.
- The history file is human-readable and pretty straightforward.
diff --git a/content/2021/oss-money/index.md b/content/2021/oss-money/index.md
index b9b50d6d..ee54a038 100644
--- a/content/2021/oss-money/index.md
+++ b/content/2021/oss-money/index.md
@@ -1,5 +1,5 @@
+++
-title="So You Want To Earn Money With Open Source"
+title="So You Want to Earn Money with Open Source"
date=2021-01-04
[taxonomies]
tags=["business"]
diff --git a/content/2021/sleep/index.md b/content/2021/sleep/index.md
index 2c7198c7..6b165110 100644
--- a/content/2021/sleep/index.md
+++ b/content/2021/sleep/index.md
@@ -26,11 +26,11 @@ I mean, everyone has a solid grasp on how it works, right?
Exactly one second passes.
-## Did exactly one second pass!?
+## Did Exactly One Second Pass!?
Probably? I don't care.
-## Why should I care?
+## Why Should I Care?
If you write a shell script then you probably shouldn't care!
Unless your program depends on precise timing.
@@ -73,7 +73,7 @@ Uh oh.
If you say that this is ridiculous because no one should be depending on such accurate timings in a shell script, **you're correct**!
Let's just say it's fun to test the limits okay?
-## How long does sleep 1 take?
+## How Long Does sleep 1 Take?
```sh
time sleep 1
@@ -82,7 +82,7 @@ sleep 1 0.00s user 0.00s system 0% cpu 1.007 total
Hold on! So both the user time _and_ the system time is 0, but the total time is 1.007 seconds!?
-[Here's refresher on the the output](https://stackoverflow.com/a/556411/270334):
+[Here's refresher on the output](https://stackoverflow.com/a/556411/270334):
- User is the amount of CPU time spent in user-mode code (outside the kernel)
- System is the amount of CPU time spent in the kernel
@@ -101,8 +101,8 @@ ps ax -p 39829 | grep sleep ✘
39829 s011 S 0:00.00 sleep 1000
```
-## How does it work?
+## How Does It Work?
-## How does it really work?
+## How Does It Really Work?
-## How does it really really work?
+## How Does It Really Really Work?
diff --git a/content/2021/uber-of-poland/index.md b/content/2021/uber-of-poland/index.md
index 64bd939f..cb5c8fbc 100644
--- a/content/2021/uber-of-poland/index.md
+++ b/content/2021/uber-of-poland/index.md
@@ -50,7 +50,7 @@ customers. While they start as exact copies of their well-known counterparts,
some of them end up offering better service thanks to their understanding of the
local market.
-## People always find a way
+## People Always Find a Way
With creativity, you can provide great service even without a big budget. The
important part is to know which corners you can cut while staying true to your
diff --git a/content/2022/alloc/index.md b/content/2022/alloc/index.md
index 4799dca2..cab8577a 100644
--- a/content/2022/alloc/index.md
+++ b/content/2022/alloc/index.md
@@ -28,7 +28,7 @@ educational to learn more, however!
So this is for everyone who wants to know more about allocations in
Rust.
-## Table Of Contents
+## Table of Contents
## Why Should I Care?
@@ -41,7 +41,7 @@ isn't that something that the compiler and runtime takes care of?
Indeed it is very convenient to use a language that takes care of memory
management, until you hit a wall:
And it can be frustrating if to wrangle with the language's limitations in the
-face of a performance bottleneck, a memory leak, or a hardward limitation.
+face of a performance bottleneck, a memory leak, or a hardware limitation.
You silently might nod in agreement if you've ever been in such a situation.
Rust, in contrast, never hides any low-level details from you.
@@ -57,7 +57,7 @@ around every corner.
In summary, Rust is a great language to learn more about memory management,
because it's safe but does not hide any details from you.
-## What's An Allocation?
+## What's an Allocation?
The origin of _allocation_ is not widely known, despite being commonly used.
The word comes from _Vulgar Latin_ [_allocare_](https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html), from _ad-_ ("to") + _locus_ ("place").
@@ -338,7 +338,7 @@ Further Reading:
Rustonomicon - The Perils Of Ownership Based Resource Management (OBRM)
https://doc.rust-lang.org/nomicon/obrm.html
-## Deciding Where To Allocate: The `Sized` Trait
+## Deciding Where to Allocate: The `Sized` Trait
In Rust, anything can be put on the heap. However, if a type implements
[`Sized`](https://doc.rust-lang.org/std/marker/trait.Sized.html), it can also be
@@ -386,7 +386,7 @@ rg -e 'String::new' \
On top of that, crates that you use could also allocate, so you have to inspect
that code as well.
-## How Do Allocations Work In Rust?
+## How Do Allocations Work in Rust?
As seen above, there are data structures that implicitly allocate memory on the
heap.
@@ -591,7 +591,7 @@ What if you need to allocate memory but you want to limit the number of
allocations?
In this case you can reuse existing allocations.
-#### Trick 1: Allocate The Right Amount Of Memory Up Front
+#### Trick 1: Allocate the Right Amount of Memory Up Front
The first trick is to use methods like `with_capacity`
if you already know how much memory you'll need.
@@ -614,7 +614,7 @@ fn main() {
`with_capacity` also exists for `Vec`, `HashMap`, `BufWriter`, `PathBuf`, etc.
-#### Trick 2: Cache Values To Avoid Allocations
+#### Trick 2: Cache Values to Avoid Allocations
If you find that you repeatedly allocate the same value, you can cache it to
avoid allocating it multiple times.
@@ -674,7 +674,7 @@ If you need to cache a lot of values, you can use a
[`lru_cache`](https://docs.rs/lru-cache) to limit the number of values that are
cached.
-#### Trick 3: Use A Memory Pool To Reuse Allocations
+#### Trick 3: Use a Memory Pool to Reuse Allocations
If you need to allocate a lot of objects of the same type, you can use a memory
pool to reuse the allocations.
@@ -763,7 +763,7 @@ fn main() {
}
```
-## The Journey Of A Rust Allocation
+## The Journey of a Rust Allocation
TODO
@@ -913,7 +913,7 @@ Furthermore, not all Rust programs are bottlenecked on allocations.
## When Can Allocations Be Bad?
- embedded (writing a gameboy game) - high-perf code - gaming - hard realtime
- code (predicatable performance) like low-latency audio allocations can slow down
+ code (predictable performance) like low-latency audio allocations can slow down
the system or downright fail at runtime That is, panic on failure
https://news.ycombinator.com/item?id=15484323
@@ -923,9 +923,9 @@ allocations while in-flight because malloc can fail
So unless you're in a hot loop, you probably won't notice the difference But
maybe you're just curious
-If you use dynamic memory alloc, you're dependend on the state of the system:
-memory fragementation (if you need one block of memory), garbage collection,...
-Not using allocs can make your code more predicatable. The important thing you
+If you use dynamic memory alloc, you're dependent on the state of the system:
+memory fragmentation (if you need one block of memory), garbage collection,...
+Not using allocs can make your code more predictable. The important thing you
gain is determinism. Malloc can become slow under memory pressure. Calling
malloc can fail, leading to an out of memory condition. Avoiding allocation
reduces the set of scenarios where you can encounter performance degradation.
@@ -937,7 +937,7 @@ inherently unsafe and can lead to catastrophic errors if you don't pay very
close attention. This makes performance optimizations way more fun! See also
https://brson.github.io/rust-anthology/1/where-rust-really-shines.html
-## How To Measure Allocations?
+## How to Measure Allocations?
Before you jump right in and try to avoid all allocations, is crucial to not get trapped by
premature optimization.
@@ -993,12 +993,12 @@ Instructions on tcmalloc https://github.com/jmcomets/tcmalloc-rs
mimalloc by Microsoft https://github.com/purpleprotocol/mimalloc_rust
-## How To Reduce Allocations
+## How to Reduce Allocations
-If you reached this point, you're either curios, or you have a real allocation problem.
+If you reached this point, you're either curious, or you have a real allocation problem.
The easiest way to avoid allocations is to get rid of your code. It sounds obvious, but removing code-paths by cleaning up your codebase is the easiest way to save up on allocations.
-## Built-in methods in the standard library
+## Built-in Methods in the Standard Library
common datastructures (a.k.a [collections](https://docs.rust-embedded.org/book/collections/)): String, Vec, HashMap, PathBuf vs &str, slice, Path
@@ -1167,7 +1167,7 @@ https://github.com/sebastiencs/shared-arena
helpful with frequent, small allocations with short lifespans
-## How To Deny Allocations Altogether
+## How to Deny Allocations Altogether
- cargo plugins to fail on allocs
@@ -1189,14 +1189,14 @@ helpful with frequent, small allocations with short lifespans
String interning https://github.com/servo/string-cache
-## Real world articles / further reading
+## Real World Articles / Further Reading
- [A Journey in Optimizing
- `toml_edit`](https://epage.github.io/blog/2021/09/optimizing-toml-edit/)
- [Making slow Rust code
- fast](https://patrickfreed.github.io/rust/2021/10/15/making-slow-rust-code-fast.html)
-## Can I limit the amount of memory used by my program?
+## Can I Limit the Amount of Memory Used by My Program?
- https://github.com/alecmocatta/cap
- https://github.com/nnethercote/dhat-rs
@@ -1218,12 +1218,12 @@ https://github.com/cmyr/cargo-instruments
Heap memory usage estimation (`data_size(&example)` prints an estimate of the number of bytes used by `example` on the heap):
https://github.com/CasperLabs/datasize-rs
-### Logging allocations
+### Logging Allocations
https://github.com/Geal/tracing_allocator
https://github.com/tobz/tracking-allocator
-### Something fun
+### Something Fun
A Rust allocator which makes sound when active, like a Geiger counter.
https://github.com/cuviper/alloc_geiger
@@ -1232,7 +1232,7 @@ https://github.com/cuviper/alloc_geiger
When a value goes out of scope
-## What is the Rust standard allocator
+## What Is the Rust Standard Allocator
As of Rust 2018 it's the system allocator by default.
On Linux it is
@@ -1241,7 +1241,7 @@ and on macos
Before that it used to be jemalloc, but that...
-## Which one is the fastest alternative to the default allocator?
+## Which One Is the Fastest Alternative to the Default Allocator?
It depends on your use-case
@@ -1269,7 +1269,7 @@ https://github.com/rust-lang/rust/issues/48043
You can try to reserve space for a vector now:
https://doc.rust-lang.org/std/vec/struct.Vec.html#method.try_reserve
(added it Rust 1.57)
-This will retrun a `Result<(), TryReserveError>`, which you can handle.
+This will return a `Result<(), TryReserveError>`, which you can handle.
There is
https://docs.rs/fallible_collections/latest/fallible_collections/
@@ -1290,15 +1290,15 @@ fn main() {
In nightly there is a new [set_alloc_error_hook](https://doc.rust-lang.org/std/alloc/fn.set_alloc_error_hook.html) function that you can use to specify a function to call when an allocation fails.
-## Where Is The Code For Allocators In Rust?
+## Where Is the Code for Allocators in Rust?
https://github.com/rust-lang/rust/tree/master/library/alloc
-## What Is A Memory Leak And Can It Happen In Rust?
+## What Is a Memory Leak and Can It Happen in Rust?
A memory leak is when a program allocates memory but never frees it.
-## Can I "see" memory allocations in Rust?
+## Can I "see" Memory Allocations in Rust?
You can look at the MIR (medium intermediate representation)
https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=27235b1815171c24c6da8d1e7dc04e8f
diff --git a/content/2022/look/index.md b/content/2022/look/index.md
index 4fcf9237..15e3cbae 100644
--- a/content/2022/look/index.md
+++ b/content/2022/look/index.md
@@ -1,5 +1,5 @@
+++
-title="The `look` Unix command"
+title="The `look` Unix Command"
date=2022-08-10
draft=true
[taxonomies]
@@ -163,7 +163,7 @@ if ((front = mmap(NULL, (size_t)sb.st_size, PROT_READ, MAP_SHARED, fd, (off_t)0)
An `mmap` is a read-only memory map backed by a file — - a "view" into memory if you like.
-## We can do that, too! 💪
+## We Can Do That, Too! 💪
...but please without bending pointers along the way.
Enter [Mmap](https://docs.rs/memmap/latest/memmap/struct.Mmap.html)
diff --git a/content/2022/zerocal/index.md b/content/2022/zerocal/index.md
index 4eeae267..540b5893 100644
--- a/content/2022/zerocal/index.md
+++ b/content/2022/zerocal/index.md
@@ -45,7 +45,7 @@ Just let me send out an invite and whoever wants can show up.
- You get the idea:
I just want to send out an invite and get no response from you.
-## The nerdy, introvert engineer's solution
+## The Nerdy, Introvert Engineer's Solution
💡 What we definitely need is yet another calendar app which allows us to create events and send out an invite with a link to that event!
You probably didn't see that coming now, did you?
@@ -58,7 +58,7 @@ That's how I pitched the idea to my buddies last time.
The answer was: "I don’t know, sounds like a solution in search of a problem."
But you know what they say: Never ask a starfish for directions.
-## Show, don’t tell
+## Show, Don’t Tell
That night I went home and built a website that would create a calendar entry
from `GET` parameters.
@@ -93,7 +93,7 @@ You can then save that to a file and open it with your calendar app.
In a sense, it's a "serverless calendar app", haha.
There is no state on the server, it just generates a calendar event on the fly and returns it.
-## How I built it
+## How I Built It
You probably noticed that the URL contains "shuttleapp.rs".
That's because I'm using [shuttle.rs](https://github.com/shuttle-hq/shuttle) to host the website.
@@ -159,7 +159,7 @@ Hello World!
Deploying the first version took less than 5 minutes. Neat!
We're all set for our custom calendar app.
-## Writing the app
+## Writing the App
To create the calendar event, I used the [icalendar](https://github.com/hoodie/icalendar-rs) crate (shout out to [hoodie](https://github.com/hoodie) for creating this nice library!). [iCalendar](https://en.wikipedia.org/wiki/ICalendar) is a standard for creating calendar events that is supported by most calendar apps.
@@ -181,7 +181,7 @@ let event = Event::new()
Simple enough.
-## How to return a file!?
+## How to Return a File!?
Now that we have a calendar event, we need to return it to the user.
But how do we return it as a file?
@@ -235,7 +235,7 @@ impl IntoResponse for CalendarResponse {
We just create a new `Response` object and set the `Content-Type` header to the correct MIME type for iCalendar files: `text/calendar`.
Then we return the response.
-## Add date parsing
+## Add Date Parsing
This part is a bit hacky, so feel free to glance over it.
We need to parse the date and duration from the query string.
@@ -303,7 +303,7 @@ Opening it in the browser creates a new event in the calendar:
And for all the odd people who don't use a terminal to create a calendar event, let's also add a form to the website.
-## Add a form
+## Add a Form
```html