Compare commits
10 commits
7ad089a3a9
...
68c64da4fe
Author | SHA1 | Date | |
---|---|---|---|
68c64da4fe | |||
b27fe6cac0 | |||
2e9c9b3849 | |||
3fbc592618 | |||
5da2f358e9 | |||
9cc66e83af | |||
c77d11e1ab | |||
512d50ac42 | |||
f54c56024f | |||
8b0c15b61c |
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
||||||
.hugo_build.lock
|
.hugo_build.lock
|
||||||
|
public/
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
aliases = ["posts", "articles", "blog", "showcase", "docs"]
|
aliases = ["posts", "articles", "blog", "showcase", "docs"]
|
||||||
title = "Blog"
|
title = "Blog"
|
||||||
author = "Ethan Marshall"
|
author = "Ethan Marshall"
|
||||||
tags = ["index"]
|
|
||||||
+++
|
+++
|
||||||
|
|
||||||
This is a collection of my personal blog posts.
|
This is a collection of my personal blog posts.
|
|
@ -2,11 +2,11 @@
|
||||||
title = 'Hello World'
|
title = 'Hello World'
|
||||||
date = 2024-08-01T04:21:56+01:00
|
date = 2024-08-01T04:21:56+01:00
|
||||||
author = 'Ethan Marshall'
|
author = 'Ethan Marshall'
|
||||||
draft = false
|
categories = ['tech']
|
||||||
|
tags = ['personal', 'web']
|
||||||
+++
|
+++
|
||||||
|
|
||||||
Hello, world! This is my first testing post to see if this system will work. Nothing to see here!
|
Hello, world! This is my first testing post to see if this system will work. Nothing to see here!
|
||||||
<!--more-->
|
|
||||||
|
|
||||||
**But,** whilst I'm here, I might as well do some describing of what this site is and where I will be taking it. Exciting stuff...
|
**But,** whilst I'm here, I might as well do some describing of what this site is and where I will be taking it. Exciting stuff...
|
||||||
|
|
Before Width: | Height: | Size: 169 KiB After Width: | Height: | Size: 169 KiB |
8
content/blog/old/2015/a-great-book-to-get/index.md
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
title: "A great book to get"
|
||||||
|
date: "2015-08-18"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
If you want to learn to code in your own time then there is a great book called Computer Coding For Kids by Carol Vorderman. You can get it cheaply on Amazon.
|
8
content/blog/old/2015/delays/index.md
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
title: "Delays"
|
||||||
|
date: "2015-12-01"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
Sorry for the delays on updates, updates will continue promptly.
|
22
content/blog/old/2015/hello-world/index.md
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
---
|
||||||
|
title: "Hello, World!"
|
||||||
|
date: "2015-08-05"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
Hello, world and welcome to ethanjmarshall.co.uk! This website is going to be about programming and the development of the future. It will have links to good websites, quick lessons, and mini tips you can follow to become a boss at programming.
|
||||||
|
|
||||||
|
Our ambition is to create a generation where any person can open Visual Studio and make a UWP app without even thinking. We think with a bit of elbow grease and brain power, we can create that generation.
|
||||||
|
|
||||||
|
But, it's not all learning. You can't say you can cook until you cook, so you can't code until you...well...code! This is why we include links to editors and development environments to give you hands-on experience with the world of programming.
|
||||||
|
|
||||||
|
Our community is a small, yet fast expanding, community of expert instructors, programmers, teachers, geeks and learners. They all work together to deliver this website and all the content that goes with it. We have mailing lists and member areas to allow you to learn what you want to learn, and nothing more. And, if you change your mind, you can simply join another of our lists. We will welcome you to whatever you want to learn next! Our instructors community is made up of expert programmers and geeks who really have the know-how. This is why we (and they) aim to keep our site fully up to date and in line with the new stuff going on in the world of code. If you read something here, you can probably trust it as it has been passed through at least three developers, two geeks and a guy from Microsoft!
|
||||||
|
|
||||||
|
So, you've found our site, along with all the benefits. Keep visiting and you might just be part of our instructor community one day!
|
||||||
|
|
||||||
|
All the code in the demonstrations is free for you to use. We welcome you to copy our code to see it in action. Just, make sure you understand it before moving on!
|
||||||
|
|
||||||
|
Last of all, we welcome you to ethanjmarshall.co.uk and hope you have fun learning to code with our thriving network of fellow geeks.
|
||||||
|
|
||||||
|
So the only thing I can say here is to **have fun coding!**
|
22
content/blog/old/2015/top-tip-2/index.md
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
---
|
||||||
|
title: "Top tip 2!"
|
||||||
|
date: "2015-12-06"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
Using parameters in a function is a good way to get values to use. For example:
|
||||||
|
|
||||||
|
`def helloworld(message):`
|
||||||
|
|
||||||
|
`print('hello', message, 'world!')`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
If I called this function like this:
|
||||||
|
|
||||||
|
helloworld('minecraft')
|
||||||
|
|
||||||
|
It would output
|
||||||
|
|
||||||
|
hello minecraft world
|
9
content/blog/old/2015/top-tip/index.md
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
---
|
||||||
|
title: "Top tip!"
|
||||||
|
date: "2015-12-05"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
A top tip for any program is build it in bits. In Python use classes and functions. For the online version of scratch you con create your own block by putting other blocks inside the DEFINE block in the corner.
|
12
content/blog/old/2015/tutorials-explained/index.md
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
---
|
||||||
|
title: "Tutorials explained"
|
||||||
|
date: "2015-08-05"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
Every week I will release another step in learning each programming language. If you happen to miss a weeks **DON'T PANIC** the posts will be available any time any place(provided you have internet). First, I will post about getting the software, then about the basics and then we will move on to more advanced stuff like making windows appear and drawing shapes. I recommend that you start on the Scratch corse then Python then Swift. Please do note than all these languages are very different!
|
||||||
|
|
||||||
|
> Everyone should learn to program a computer because it teaches you to think.
|
||||||
|
>
|
||||||
|
> Steve Jobs
|
30
content/blog/old/2018/feedback/index.md
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
---
|
||||||
|
title: "Feedback"
|
||||||
|
date: "2018-05-16"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
**Feedback needed**
|
||||||
|
|
||||||
|
Do you have a problem with this site?
|
||||||
|
|
||||||
|
Is there something you want to have added?
|
||||||
|
|
||||||
|
Do you just want to contact us about something you love?
|
||||||
|
|
||||||
|
Do it here! This is a free for all area where everyone can have their say about this site.
|
||||||
|
|
||||||
|
**Rules**
|
||||||
|
|
||||||
|
1. Please stay on topic. This is a feedback area, not a discussion thread
|
||||||
|
2. No insults, personal jokes or bad language. Please keep it clean and just about the site.
|
||||||
|
3. Be realistic. If your feedback is to cure world hunger, don't bother taking part.
|
||||||
|
4. Be honest. Do you really want something fixed or are you agreeing with your best friend?
|
||||||
|
5. Most important to less important. If you want your comments to be heard, put your most important feedback first.
|
||||||
|
6. No Javascript. Any requests which appear to contain Javascript will be immediately discarded
|
||||||
|
7. Put whatever you need. No need is too small. We will manually review all feedback which fits these rules. Put whatever matters to you and we will listen.
|
||||||
|
|
||||||
|
Any comments which do not fit these rules will be discarded and will not be considered.
|
||||||
|
|
||||||
|
But apart from that, please put what is important to you and remember, keep coding!
|
BIN
content/blog/old/2018/rejoice-subscribers/celebration.png
Normal file
After Width: | Height: | Size: 46 KiB |
20
content/blog/old/2018/rejoice-subscribers/index.md
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
title: "Rejoice, subscribers!"
|
||||||
|
date: "2018-06-01"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
**Rejoice all subscribers, readers and constant visitors!**
|
||||||
|
|
||||||
|
Hello there, everyone! This is a celebratory post as today we are celebrating the fact that our site has just achieved **100 total hits!**
|
||||||
|
|
||||||
|
This news comes with the arrival of our Swift, C and C# tutorials. We hope that our popularity continues to grow. But, for now, let's celebrate and rejoice! We're going up in the world.
|
||||||
|
|
||||||
|
![Celebrate](celebration.png)
|
||||||
|
|
||||||
|
We hope you continue to visit and enjoy our content here on ethanjmarshall.co.uk. Please share you messages below if you want to show your support. Thanks!
|
||||||
|
|
||||||
|
Sincerely,
|
||||||
|
|
||||||
|
ethanjmarshall.co.uk team
|
20
content/blog/old/2018/top-tip-4/index.md
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
title: "Top Tip 4!"
|
||||||
|
date: "2018-07-12"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
Imagine you have developed a large app in Python that consists of over 1,000 lines of code. But wait! You have noticed a bug. But where is the offending code? All you see is a lake of confusing code.
|
||||||
|
|
||||||
|
Do you see a problem? To make your code easier to read, it is important to include code comments. These are parts of your code which can be human readable. The computer just ignores these when it sees them, so you can put whatever you want in them.
|
||||||
|
|
||||||
|
In addition, comments can help you to organise your code and make it clearer. For example, if you have a large operation with many steps, you could split it up with comments labelling each step and what it does. That way you can identify where something is going wrong if you notice a bug in the program.
|
||||||
|
|
||||||
|
In python, any line which begins with a hashtag is a comment. In Java, you can make a line a comment with a double forward-slash. For example:
|
||||||
|
|
||||||
|
//This is a comment
|
||||||
|
|
||||||
|
In most editors, comments are highlighted green. In IDLE, they are highlighted red.
|
||||||
|
|
||||||
|
So, there you have this week's top tip. So now, go and get coding, and don't you forget those comments!
|
24
content/blog/old/2018/top-tip-number-3/index.md
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
---
|
||||||
|
title: "Top Tip 3!"
|
||||||
|
date: "2018-06-03"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
Hello guys! It's been a long time since we posted a top tip, so let's go in with a big one.
|
||||||
|
|
||||||
|
**Are you waiting eagerly for the next Java tutorial?**
|
||||||
|
|
||||||
|
**Do you feel addicted to Java?**
|
||||||
|
|
||||||
|
We have a website for you. Edu4java.com is a site dedicated to the teaching of all versions of Java, for many different purposes. If you want more Java, come here. They cover material we could never cover. Does the thing you want to learn have the word "Java" in the title? They've got it!
|
||||||
|
|
||||||
|
Also, courses such as game development and the development of Java Applets which we will only touch on in this course, so it can act as an exemplary extension course to our material.
|
||||||
|
|
||||||
|
Finally, do you speak Spanish? If so, you will love this site. It has a Spanish and English version. Just what all you Spanish learners need.
|
||||||
|
|
||||||
|
So, go to this site, and your Java world will get a bit bigger.
|
||||||
|
|
||||||
|
[Take me to edu4java.com (English)](http://www.edu4java.com/en/index.html)
|
||||||
|
|
||||||
|
[Take me to edu4java.com (Spanish)](http://edu4java.com/)
|
18
content/blog/old/2018/were-back-in-business/index.md
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
---
|
||||||
|
title: "We're back in business!"
|
||||||
|
date: "2018-05-26"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
Dear faithful readers, subscribers and users,
|
||||||
|
|
||||||
|
We would just like to apologise for the lack of new content for a while. This was due to updates, framework contributions and maintenance.
|
||||||
|
|
||||||
|
You will, however, be happy to hear updates will continue promptly with new content such as Java, C/C++ and C#.
|
||||||
|
|
||||||
|
Also, we are now moving toward being GDPR compliant. If you receive an email, it is just a notification of our new privacy policy.
|
||||||
|
|
||||||
|
Thank you all,
|
||||||
|
|
||||||
|
ethanjmarshall.co.uk team
|
143
content/blog/old/2020/gpg-mistakes/index.md
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
---
|
||||||
|
title: "Don't be like me with GPG"
|
||||||
|
date: "2020-12-19"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
Ah, public key cryptography; where would we be without you? I mean, probably somewhere at least, but nowhere near where we are technically today.
|
||||||
|
|
||||||
|
And, despite being probably one of the most interesting and cool applications of computer cryptography (and indeed mathematics) that exists, it can be a real bloody pain to you if you use it wrong.
|
||||||
|
|
||||||
|
_Which is what I did_
|
||||||
|
|
||||||
|
You see, in theory, asymmetric cryptography is perfect - with the "in theory" part being key. If nobody ever gets your private key, nobody can ever read your mail, encrypted files or pretend to be you. But that's why this is theory.
|
||||||
|
|
||||||
|
You see, in practice, a large part of PKI management is trying to account for human error. Humans messing up, giving out the private key, using the wrong email with the wrong key, making typos and the like. All these things are weak points in this kind of cryptography. And, as the title of this post suggests, I have learnt this through acting as my own worst enemy.
|
||||||
|
|
||||||
|
So, to save everybody else from the hardships I have gone through whilst managing my PKI, this post will go through all the ways I was bad at using asymmetric cryptography and the ways you can avoid doing what I did. Now, although I do have hands on experience with this, I am, by no means, an expert. The way I could have approached these problems could have been better - in some ways, _should_ have been better. But, please keep in mind that this was just me struggling to find a solution to a problem that was starting to get on my nerves. In that mind set, my solutions tended to be more along the lines of "nuke the whole thing and start over" than "let's just calmly attempt to get people to re-import the key".
|
||||||
|
|
||||||
|
## Chapter 1: Key management
|
||||||
|
|
||||||
|
### Mistake 1: Not using keyservers
|
||||||
|
|
||||||
|
When I first generated by key pairs, I was still an amateur to the whole concept of encryption and key management.
|
||||||
|
|
||||||
|
So, when I read the FAQ on the MIT keyserver page that read "We cannot delete your key after it has been uploaded", I decided that I wanted to safely control the propagation of my key. **And that was really stupid.**
|
||||||
|
|
||||||
|
At this point I hadn't discovered (mostly owing to my never having needed to use them) _revocation certificates._ In my strange, inexperienced world of key management, I thought the only way to get rid of a key was to delete it or let it expire. So, in my mind at least, the only logical thing to do would be to email a load of people with the key as the attachment and tell them all to import it. Then, I could just tell them to delete it if anything ever went wrong. "Perfect!", I thought, as I sent this key to all my friends and people I needed to communicate with.
|
||||||
|
|
||||||
|
This mistake would be one which came back to bite me.
|
||||||
|
|
||||||
|
In subsequent mistakes, mistake number one caused so many possible routes of rectification to be invalidated that I had to opt for low-tech solutions instead. Need to add an email to my key? Well, I'm not using keyservers, so I will instead have to either edit the key and re-send it to everybody or generate a new one and revoke the old one. If I had just decided to send the keys to a server, it would have taken me less than a minute to add a new email to my key. But, no. Instead, I had to...
|
||||||
|
|
||||||
|
- Revoke the old key
|
||||||
|
- Send the revocation certificate to everybody who could possibly have the old key
|
||||||
|
- Make a new key with updated details
|
||||||
|
- Send that key to everybody who could need it
|
||||||
|
- Update anything on my system (such as _pass)_ which required the GPG key to use a new one
|
||||||
|
- Change the GPG config to use the proper key
|
||||||
|
|
||||||
|
You can probably see why I later kicked myself for not **just using a damn keyserver.**
|
||||||
|
|
||||||
|
Don't be like me, use a public server.
|
||||||
|
|
||||||
|
### Mistake 2: No expiration, no hassle - right?
|
||||||
|
|
||||||
|
You've probably got the idea that, at this point, I was kind of incompetent at the diligent task of managing these keys. But I'm just getting started, as the worst is, really, still to come.
|
||||||
|
|
||||||
|
Now, this is another one of those slip-ups that has come back around to bite me, as this has closed many routes of fixing problems too. If only my personal key had been programmed with an expiry date, I could have just rotated the old key out of use and naturally began using the new keys I generated.
|
||||||
|
|
||||||
|
But, no. At the time I was creating the keypairs, I decided that I would generate all of them with no expiry date. After all, it would be "so much of a hassle to just circulate a new key every couple of years" - said nobody, ever. This piece of logic has cost me so much time that it outweighs the time I could possibly have ever spent re-circulating keys to people who need them. Come on, it's not that hard.
|
||||||
|
|
||||||
|
If you are generating your keys for the first time, dear God, please program in an expiry date. It's not that difficult of a thing to send new keys to people.
|
||||||
|
|
||||||
|
### Mistake 3: Keys, keys, as far as the eye can see
|
||||||
|
|
||||||
|
If you ever have the need to export your key and are copying it into multiple places, chances are you are doing something wrong.
|
||||||
|
|
||||||
|
I had decided, like the incredibly stupid person that I was (and somewhat still am), that I was going to just export my key and hard-copy it across to other machines. **No -** this is a bad solution.
|
||||||
|
|
||||||
|
For example, let's paint the picture. You're on your desktop and you decide that you want to add a new user ID to one of your keys. So, you go through the GPG edit key wizard and get back a nicely edited key. No issues so far.
|
||||||
|
|
||||||
|
However, on your laptop computer, your key is now out of date and lacking in certain, probably critical, information. So, what do you do? Well, therein lies the problem. And, although this is less of a problem in my management and more of a difficulty in the encryption system itself, I have found a solution. Keep **one** propagation key: basically, keep one export of your key on a thumb drive, memory stick or server location that you can plug in or connect to on any machine. Then, when you make an edit, export it again to this key. _Don't do what I did where I exported the key multiple times on all machines and then proceeded to make the edit on all those machines and update the individual export on each machine._ Use on authoritative key export.
|
||||||
|
|
||||||
|
Now, obviously, it can't hurt to keep backups - nobody is suggesting that backups are bad in any way. But make the backups from the authoritative key. Backups != keeping multiple authoritative key copies.
|
||||||
|
|
||||||
|
## Chapter 2: Key use
|
||||||
|
|
||||||
|
### Mistake 4: Inconsistent and unreliable
|
||||||
|
|
||||||
|
I think it is safe to say that my standards for key use were inconsistent at best.
|
||||||
|
|
||||||
|
Whether it was accidentally encrypting my mail with the wrong key (and really worrying/confusing friends) or sending signatures in different ways every other week, I needed to get it together. Some weeks I would be sending clearsigned, attached signatures, other days I would be sending detached signatures as an attachment.
|
||||||
|
|
||||||
|
Please, for the sake of the sanity of the person you are corresponding with, just attach a signature.
|
||||||
|
|
||||||
|
In emails, don't use a clearsign as the email itself: it's difficult to read around, it looks ugly and it doesn't work particularly well with most email clients. Attach a regular signature as an attachment, preferably called "signature.asc"
|
||||||
|
|
||||||
|
### Mistake 5: UUIDs (not so) built to last
|
||||||
|
|
||||||
|
When you generate a GPG key, you are asked to specify your name and an email. This is for more than aesthetics. One of the core components of GPG is making sure that you are using the right, trusted key for the right person. So, to make sure you can do that, each key has at least one UUID attached, which contains information which will allow you to identify the person who it belongs to.
|
||||||
|
|
||||||
|
When you create a key, you are, essentially, filling in this information for the person who will import your key. So, it's safe to say that it's quite important that you get this right. Now, in theory, you have a safety net, in that if you edit the UUID, anybody using the key can just re-import the key (or pull an updated key from the server, but we have already established that I made that impossible through my own stupidity).
|
||||||
|
|
||||||
|
So, who would be surprised that I somehow managed to mess this part up too.
|
||||||
|
|
||||||
|
When generating my keys, I not only used an email address that I was using temporarily, but also one that I didn't want anybody I didn't know to have. So, basically, I picked a terrible choice for email. Now, I have a key with a bad email which nobody should use but which my key is stuck with because I sent that key to loads of people. Really stupid move, saying as I had also made this key never expire, meaning that people now had not only a key that was doomed to become invalidated or out of date but one that would never become naturally obsolete. Not a good situation.
|
||||||
|
|
||||||
|
This is more of a complicated point, but make sure that, if you want a key to last, the UUID needs to last - assuming you're not using keyservers and the like. Even so, it is just plain, good practice to make people's lives easier by making that ID a constant. Don't use a throwaway email like I did and make sure that you have actually typed it correctly.
|
||||||
|
|
||||||
|
Final thing related to the above: **DO NOT under any circumstances use a git signature key and committer email which is your GitHub noreply email.** This email is generated based on your UserID and username - both of which can change. I learnt the hard way that, if you use this email for both your key and your committer identity, things go south fast, which led to the...
|
||||||
|
|
||||||
|
### Mistake 6: Don't just leave that lying around!
|
||||||
|
|
||||||
|
Although, at this point in my career, I didn't fully understand how any of this "encryption stuff" even worked, you would have thought I had a bit of a better understanding of how to secure my keys.
|
||||||
|
|
||||||
|
Not only did I, on several occasions, accidentally give people media with my private key encrypted but present on it, I also, occasionally, just left revocation certificates lying around.
|
||||||
|
|
||||||
|
I know that I said earlier that I didn't know what a revocation certificate was or that I may need one, and that was, actually, what led me to think it was valueless. "Surely, it's just a key export", I probably thought to myself, as I just left a file that could make my private and public key permanently unavailable on an unsecured flash drive.
|
||||||
|
|
||||||
|
Seriously, what I was thinking and the risks I took will probably never leave me.
|
||||||
|
|
||||||
|
## Chapter 3: The GitHub Commit Massacre
|
||||||
|
|
||||||
|
On the 20th of November 2020, over 500 commits on my GitHub account were massacred into the "unverified" state by GitHub due to a severe oversight on my part relating to how I signed my commits.
|
||||||
|
|
||||||
|
This massacre occurred because of a combination of all the mistakes mentioned above and my own poor handling of security and robustness. But how could things have gone so wrong? Well, funny you should ask...
|
||||||
|
|
||||||
|
### Temporary Email Address
|
||||||
|
|
||||||
|
Please, for goodness's sake, don't use your GitHub noreply email address for your signing key.
|
||||||
|
|
||||||
|
In case you are unaware, your GitHub noreply address is an address generated by GitHub for people who want to add a committer email address but who don't want to expose an actual address. The only reason this needs to exist (and why I used it) is because GitHub will only accept signed commits if the committer email matches the GPG email and if both emails are verified on the user account who uploaded the commits. In other words, it is just making sure that it is your key that was used. However, the GitHub noreply address is treated as verified by GitHub to solve the problem above. It basically gave people like me an avenue to hide our email.
|
||||||
|
|
||||||
|
Looking back, I really don't see the issue with giving out my communication email address, saying as it was in the README files for most of my repos anyway But, in any case, I had made the decision to use this email for all my details. This was a huge mistake
|
||||||
|
|
||||||
|
You see, this email completely changes when your username changes. So, when I changed my username (twice!), over 500 commits made on my old username because "unverified", owing to the fact that the GitHub noreply address was no longer valid.
|
||||||
|
|
||||||
|
There was literally nothing I could do about this other than add a message to my repository about unverified commits. So, don't be like me, and please don't use your GitHub noreply address for your GPG key.
|
||||||
|
|
||||||
|
### Botched attempt at mitigation
|
||||||
|
|
||||||
|
Now, as if that wasn't bad enough, my next actions were even worse. You see, I had decided that I really wanted to try and re-verify these commits. So, I did a huge rebase.
|
||||||
|
|
||||||
|
For anybody who has worked with Git, you probably know where this is going. I, basically, rebased the entirety of the master branch - thereby breaking the [No. 1 rule of Git remote management](https://www.daolf.com/posts/git-series-part-2/) - and broke a load of people's local copy of the repositories.
|
||||||
|
|
||||||
|
Looking back upon this whole fiasco, I got nowhere and annoyed a whole load of people. To this day, there are instructions in some project READMEs about how to fix your repository if you got it broken by my terrible signature management.
|
||||||
|
|
||||||
|
### Don't be like me
|
||||||
|
|
||||||
|
The key takeaway from this section is, please, don't use your GitHub noreply address as a committer identity. Emails are effectively free in the modern day and it will take you about ten seconds to set up an anonymous address, if you are concerned. Services like [ProtonMail](https://protonmail.com) don't even ask for any personal info on signing up. Just make a proper email - it's actually really convenient for you to get feedback on commits!
|
||||||
|
|
||||||
|
There is literally no downside. Please, I cannot stress it enough, just use an actual email for your committer identity and signature. It's not that hard.
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
|
So, let's sum up:
|
||||||
|
|
||||||
|
- I used to be terrible at GPG key management
|
||||||
|
- Being terrible at GPG key management will cost you long term
|
||||||
|
- Being terrible at GPG key management sucks
|
||||||
|
|
||||||
|
Thanks for reading and, please, heed my advice and **just don't be like me with GPG.**
|
16
content/blog/old/2020/initial/index.md
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
title: "Initial commit"
|
||||||
|
date: "2020-05-12"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
## Welcome to the new and remastered version of this site
|
||||||
|
|
||||||
|
I've decided to stray away from making programming tutorials, and instead make posts talking about my thoughts on the programming industry, programming in general and lots of computer-related stuff.
|
||||||
|
|
||||||
|
I'm using this more as a traditional blog now. All my previous posts are unlisted. If you had a link, you can still access them. However, as a side effect, all comments made before this date have been unapproved (and some deleted).
|
||||||
|
|
||||||
|
You can soon expect exciting and interesting posts to be made, along with landing pages for my various projects. So, I guess I'll leave it there and keep my commit size small :)
|
||||||
|
|
||||||
|
**Happy programming!**
|
BIN
content/blog/old/2020/me-and-my-dad/dad.jpg
Normal file
After Width: | Height: | Size: 14 KiB |
20
content/blog/old/2020/me-and-my-dad/index.md
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
title: "Me and My Dad"
|
||||||
|
date: "2020-12-19"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
![My Dad](dad.jpg)
|
||||||
|
|
||||||
|
It is a pretty special thing to be able to think back on your time with a person and to have no negative memories of them whatsoever come to mind. In fact, some would say that this is an impossible feat; something which cannot possibly be done by any functioning person.
|
||||||
|
|
||||||
|
My dad was living proof that this is not the case.
|
||||||
|
|
||||||
|
From my perspective, experiences of a person can be built around the feelings between you and the person which manifest themselves into positive and negative experiences. The end result of this philosophy is that, if a person always has your best interests at heart, even experiences which appear to be negative are in fact positivity in disguise.
|
||||||
|
|
||||||
|
This outlook on interactions between people applies wonders to the relation between me and my dad. Although we, undoubtedly, had disagreements, moments of tension or even moments of outright anger - none of these experiences were ever motivated by anything other than my dad's love for me and the rest of the family.
|
||||||
|
|
||||||
|
Ever since his death, I have looked back on my dad's life with new eyes. And, these new eyes caused me to see him in a very different way. As, although many negative memories of him turned positive, absolutely no positive memories of him turned to negative. Initial negative feelings are now seen with a bigger picture, revealing his true motivations of love and care.
|
||||||
|
|
||||||
|
Although I will never speak to him again, my dad will always be there, confined in the newly remastered positive memories of him within all of us. And, if anything is a sign of a great human being, a great dad and a great person in general, it is that they can be looked back upon with pure positivity.
|
50
content/blog/old/2021/10-ways-linux-crash/index.md
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
---
|
||||||
|
title: "Top 10 Ways to Crash Your Linux System"
|
||||||
|
date: "2021-09-29"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
I recently made my collection of personal tools public on GitHub under the name of [EUtils](https://github.com/ethanv2/eutils). These are real tools that I do use in real life to do somewhat useful things. But, about midway through making one of them, I realised just how many of them can be used to crash a linux box...
|
||||||
|
|
||||||
|
I don't know if there are actuall ten different ways in there, but it does make a good title.
|
||||||
|
|
||||||
|
## Allocate too much memory
|
||||||
|
|
||||||
|
I was writing a program to buffer a load of random numbers from /dev/urandom when I realised that, if the user cranked up the amount to buffer really high, they could allocate more memory than the system can handle, making the whole thing freeze up until the kernel finally figures out what is going on and kills the program responsible. Basically, I accidentally created a memory bomb to rival `tail /dev/zero`. So, I actually made a program that is for this and _just_ for this purpose. It is called `mdest`, or Memory Destroyer. This program will, basically, repeatedly call `malloc` until (again) the stupid kernel actually does its job and kills the program responsible for ruining the system's performance. If you really want to suffer, you can run the program as root and the kernel will be even slower to figure out what is going on because "the root is always correct!".
|
||||||
|
|
||||||
|
In any case, running this program will always result in one of three scenarios:
|
||||||
|
|
||||||
|
- Your system goes down after the idiot kernel fails to figure out what is going on before complete OOM and paging deadlock, causing a likely kernel panic or complete softlock
|
||||||
|
- All your programs crash or are swapped out to disk after failed memory allocations. I have known some programs to start dereferencing NULL pointers due to failed allocations and others just completely deadlock waiting for a blocking IO operation that requires memory
|
||||||
|
- `mdest` recieves sig-9 (SIGKILL) instructing it to exit immediately. Sadly, the C runtime library insists that it frees all your memory before the kernel does it anyway (thanks GNU), so even that can lead to a system deadlock or really slow exit time
|
||||||
|
|
||||||
|
Basically, this program really sucks and you shouldn't run it unless you are testing OOM scenarios or you really hate whoever owns the computer you are running it on. But, let's be real: it's probably the second one.
|
||||||
|
|
||||||
|
## Fork too many times
|
||||||
|
|
||||||
|
If you weren't satisfied with memory bombs, how about automated fork bombs! Well, kind of. You see, in UNIX, the way that you create a child process is by doing the _fork-exec sequence_: your program forks into two copies of itself and the second copy simply replaces itself with a new program using the _exec_ system call. However, creating a new process requires CPU time, IO time and memory usage. The footprint of a process descriptor for the kernel is not cheap. The Linux task struct is one of the largest data structures in the entire kernel (plus the overhead for stuff like page tables and it really does not come cheap). So, what if we were to fork ourselves over a million times and just start `sched_yield`ing for the rest of time? Well, eventually you just arrive at either an unresponsive system or an OOM scenario like previously. This is boring - next horrible idea...
|
||||||
|
|
||||||
|
## /dev/random
|
||||||
|
|
||||||
|
For some ungodly reason, some programs out there _still_ use /dev/random in actual production code. /dev/random is a horribly designed interface which completely misunderstands how entropy and pseudorandom cryptographic randomness _actually_ works. It is a lot of fun to abuse though.
|
||||||
|
|
||||||
|
You see, /dev/random will block if there is not enough entropy in the kernel entropy pool to return a truly random answer from this randomness interface. So, if a program is wanting a load of random data, getting another program to hog all the randomness will cause them all to start behaving strangely.
|
||||||
|
|
||||||
|
In eutils, there is a program called `rand` which will just return as many random numbers from the best available source (or whatever source you specify) at any given time. By default, it uses the standard C runtime's `rand` call, which is horrible and just based on your system clock. However, for most shell programs or quick pipeline scripts, it works fine. So, its a useful utility. What it is also useful for, however, is intentionally crashing your Linux system. The program takes in one argument, which is the count: the amount of random numbers to return. So, if you just shove some enormous number in (I like to use 2^64 for fun) and point it at /dev/random, you can make some dark magic happen. One of the best things to try out is creating a GPG key pair at the same time as running rand in this manor. You will notice that both programs start to have a massive scrap over who gets the random data. Meenwhile, the poor kernel is having a heart attack trying to get both programs that they are asking for: loads of random data it doesn't have because `rand` stole it all.
|
||||||
|
|
||||||
|
In the end, what tends to end up happening is that most of the applications that require random data just freeze up forever. Luckily, there is a quick fix to this one: just wiggle your mouse about loads, launch a load of programs and type random keys on your keyboard. The kernel's entropy pool is obtained from a combination of user inputs and random memory locations. So, all the programs will, eventually, end up with the data they asked for and everybody is happy again.
|
||||||
|
|
||||||
|
So, does this count as a crash? Well, eventually the IO operations that the programs that want data might timeout. Either that or some threaded operation in them (this one tends to apply to web browsers) also requests this data, causing a mutual exclusion deadlock and an eventual crash. So, yeah - I'm counting this as a crash anyway.
|
||||||
|
|
||||||
|
## Oversleeping
|
||||||
|
|
||||||
|
The `sleep` system call is incredibly useful for many applications. However, one of the applications where it tends to be a bit less suitable is being actually accurate with time, given that it requires a load of context switches for one call and it is up to the scheduler as to where you actually end up. So, if you are relying upon the sleep system call for accurate time keeping, you may as well give up.
|
||||||
|
|
||||||
|
So, naturally, that is what I chose to program the eutils stopwatch implementation using! Well, to be fair, this one is less egregious, because the program is multi-threaded using Go's cool threading implementation, so the Go runtime is more in charge of sleeping threads. However, a similar situation to the normal sleep syscall applies: it is not designed for accuracy.
|
||||||
|
|
||||||
|
The only issue is that sleeping lots of times (in my case, once every _millisecond_) results in some funky behaviour. In particular, the increased CPU load feeds into a negative feedback loop: as the CPU stress increases, the scheduler compensates by making less context switches. As the CPU makes less context switches, the sleeps become longer, requiring more in a particular time frame to meet the demand for the application's time keeping. And, the cycle continues. In the end, you end up with a dreadfully slow stopwatch which is out of sync by at least a whole second with realtime.
|
||||||
|
|
||||||
|
Luckily, my implementation does not suffer from this due to a specific little piece of threading genius that I used (thanks Rob Pike) and the stopwatch will be accurate to within a few milliseconds (I can't guarantee that the runtime will not be a _tiny_ bit longer than it promised, because it is out of my hands).
|
||||||
|
|
||||||
|
So, basically, sleeping in in Linux is not just being lazy - it actually takes _more_ effort overall.
|
60
content/blog/old/2021/a-bad-movie/index.md
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
---
|
||||||
|
title: "A Bad Movie"
|
||||||
|
date: "2021-09-01"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
There is something deeply saddening and disheartening about a bad movie. Perhaps it is the realisation that somebody infinitely more talented and with more resources than you will ever have has managed to use all of that to create _this._ Or, perhaps, it is the realisation that the entertainment gods are not actually as perfect as they seem, and that not everything they touch turns golden. Or perhaps it's just the wasted ticket fare.
|
||||||
|
|
||||||
|
Picture the scene. You walk into the cinema full of hopes and dreams and aspirations about what the film you are about to watch contains. You smile at the cashier as they hand you your ticket and a complimentary bucket of popcorn (this is a thought experiment, it doesn't have to be realistic). You half skip towards screen five as you get ready for a whole 90 minutes of non-stop entertainment of the highest calabre. In my mind, each cinema-goer is equipped with a few fuel tanks inside their mind and body. One of these is filled with aspiration, one with apprehension, one with hope - and so on. Upon coming into contact with such a hazardous material as a bad movie, one by one, these fuel tanks will be burnt through at an accelerated rate. Some may even catch fire or leach away entirely. A good movie never forces you to burn through even your first tank full of apprehension, as everything the film was cracked up to be it delivers on. A bad movie, on the other hand, may leave you with as little as half a tank of will-to-live - just enough to get you home without jumping in front of a car.
|
||||||
|
|
||||||
|
So, let's return to your imaginary friend in the theatre. You sit down in the comfortable theatre seat and take a preliminary taste of your popcorn. Although the trailers cause your tank of apprehension and irritation to burn down a little, you're still ready and raring to go. As the film starts, your adrenaline tank is pumping at full blast and your entire body is corsing with emotions. Then, the _actual_ film starts.
|
||||||
|
|
||||||
|
To begin with, your levels of anticipation and apprehension drop with every scene that goes by. Nothing too drastic - it sometimes starts out this way. Once the body has exhausted its supply of these two, it moves on to your hope. You begin to clutch at straws: "Well, perhaps the _climax_ will be good!", "Well, it wasn't that bad - the story arc _could_ come to a satisfying close", "Come on, that side character _couldn't_ have just been thrown in for no reason. They wouldn't just hire Elijah Wood just to kill off his character ten seconds later!". Sadly, your entire supply of hope is burnt through with every unanswered question and every unaddressed plot hole. Now at a rate of litres per second, your body's supply of anger and irritation begin to be used up. With a rate of tonnes per frame now, you continue to exhaust your supply of anger. When - and only when - your entire supply of anger has been burnt up, will the slow leakage of your will-to-live start. Unlike the previous, it starts out slowly, with the agonising process of leakage down your legs, through your shoes and finally seeping into the ground like some noxious contaminant. This is usually where the depraved laughter, head in hands or head banging starts.
|
||||||
|
|
||||||
|
By the time that your mind has regained control of the body after the nuclear meltdown in the irritation and anger tanks (and the Chernobyl cleanup efforts have concluded to scrub your body of angered sweat), you finally muster the courage to raise from your seat. Hands and legs shaking, you proceed to the back of the screen. As you do, you glare at the projectionist at the back of the theatre for putting your through the last 90 minutes. He ignores you - it happens every other week. On leaving the screen, you hear the father of the obligotary obnoxious children, who always seem to be present, exclaiming that the film was "really good" and that "we should buy it on DVD". The rest of your will to live empties out as you throw up in a trash can.
|
||||||
|
|
||||||
|
Sound familiar?
|
||||||
|
|
||||||
|
Well, perhaps not. But, a similar feeling will, at the very least, be common to all of us. Bad movies are genuinely traumatic experiences, and yet nobody can pinpoint why. However, the specific features of a bad movie will not be so repetetive, leading to large deviations in reaction based on both the audience member in question and the movie. Let's take a look at some of the most common abominations that Hollywood has spawned on us in its lifetime:
|
||||||
|
|
||||||
|
## Has anybody seen by budget?
|
||||||
|
|
||||||
|
Whoever authorised this film probably didn't ask their boss first, so got stuck with using their own bonus of around $200 to fund the entire film. Cheap, half-baked shots with crappy animation that looks like something from the PS2. Within this category, there are two sub-categories.
|
||||||
|
|
||||||
|
### I'm trying my best!
|
||||||
|
|
||||||
|
This category is where Dreamworks animation lands firmly. Despite films like Shrek clearly having a great deal of effort and heart put into them, they just come off as looking and feeling like some bootleg Disney story. I don't know if I am just a Disney fanatic or not, but whatever animation software they are using is just blowing the competition out of the water. This film is not intentionally bad; the creators were just working with what they had and did a great job with the tools at hand. I actually kind of like this category.
|
||||||
|
|
||||||
|
### Money, money, money
|
||||||
|
|
||||||
|
Step right up to see the next revolution in money saving that the film industry has given to us, starring Illumination studios and Chris Meledandri. Illumination intentionally use filmmaking tactics which make their films incredibly cheap to produce. Re-used sets, character models, sound effects, _visual_ effects, literally anything that can by copied and pasted, this guy will find out how to do it. Stock animations, stock models and generic animation styles make these films look and feel like they were produced by an algorithm or a focus group. Oh wait - they actually were produced by both. Well that explains something. Please see [this](https://www.youtube.com/watch?v=EBe1hXRNi4g). Stop giving these films your money, because they sure-as-hell aren't spending it on making better movies.
|
||||||
|
|
||||||
|
Now, those two categories are rather weird, in that the effect they have is inverted to traditional expectations. A painfully obvious case of budget starving nevertheless makes me love the film more. A case of cost cutting and penny pinching by the likes of Illumination make me want to smash the projector in the cinema. In other words, just putting heart into a production makes it appear that you have a much bigger budget than you have. Speaking of which...
|
||||||
|
|
||||||
|
## Check out this cool budget!
|
||||||
|
|
||||||
|
Who would have thought that throwing money at animators and telling them to work harder doesn't produce better art. I would.
|
||||||
|
|
||||||
|
You see, there are some companies on this earth that just love to show off. Whether it is Disney showing off their CGI skills with a bunch of useless real world remakes of cartoons (Dumbo, Aladin, etc.) or Universal including huge amounts of music in their movies just to show off how much music UMG has the rights to, this production is just a massive ego-trip, but on the part of a company, not an actual person.
|
||||||
|
|
||||||
|
Sadly, despite the enormous amount of technical prowesse usually shown, the movie - in the end - winds up having little to no creative value at all. Sometimes, it can be difficult to even hate the movie because you can see the amount of effort put in, sometimes even leading to guilt about asking for better. The amount of technical work has to be balanced with the amount of creative work, or your film just becomes some kind of tech demo or proof of concept. Not intended for general audiences - because it sucks.
|
||||||
|
|
||||||
|
## Loose lips sink ships
|
||||||
|
|
||||||
|
In case you weren't aware, social justice warriors (in 2021, not renamed "woke people" or "children of the woke") have succeeded in completing their Long March Through The Institutions and have managed to infect Hollywood with their absolute nonsense. Sadly, this means that they see these films (which will be distributed and send out to ordinary people all around the world) as some kind of brainwashing propaganda tool. I was not expecting to be lectured about the patriarchy or white priviledge by a kid's movie about video games, but it has happened on multiple occasions. The sad thing about _these_ movies is that they often have some merit to their story or technical side, but are completely ruined by the SJW infiltration. The humor is trash, the message is trash, the "progressive themes" are awful and don't resonate with non-SJWs. At least they aren't very good propagandists, or more of them might be created. In fact, these messages are often so appauling to the common man that it can cause advanced symptoms of psychosis and clinical depression. No wonder the CIA uses these films as torture weapons at Guantanamo Bay.
|
||||||
|
|
||||||
|
Now, there is another kind of these films. And that is the woke remake. [All that needs to be said already has been by a man much smarter and more articulate than myself.](https://youtu.be/dP6Rq325SIQ)
|
||||||
|
|
||||||
|
## Wiseau films
|
||||||
|
|
||||||
|
Tommy Wiseau is a genius. Not only has he created (or kickstarted) and entire genre of film, he has managed to accidentally create probably one of the greatest advancements in professional humor of the 21st century. Tommy Wiseau's entire collection of films (comprising of a whole one film) are so bad that they are incredibly good. Somehody, the acting would be better if you replaced the entire cast with text-to-speech engines. Everything is so bad, yet so good at the same time.
|
||||||
|
|
||||||
|
I think that the true reason these films are so good in their badness is that the internal scale our brain uses to measure our pleasure in a thing breaks when levels get too high and circles all the way around the intense pleasure in the badness. [Now where have I seen that before](https://en.wikipedia.org/wiki/Integer_overflow)?
|
||||||
|
|
||||||
|
If you can watch the entirety of The Room and tell me there is no value, you are a liar.
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
|
Well, in this day and age, the experience of a bad movie is almost as common to use as a bout of plague would be to our ancestors. Modern humans are just built to resist other kinds of natural tortures. Rather than sores and flu, we have psychological suffering induced by the worst kinds of entertainment on the planet. Hopefully, though, this can serve as your vaccination against bad movies. Whenever you next are forced to watch one, think of this article. Hopefully it can reinforce your imploding anger tank with a chuckle of laughter.
|
50
content/blog/old/2021/accidental-discoveries/index.md
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
---
|
||||||
|
title: "The Joy of Accidental Discoveries"
|
||||||
|
date: "2021-11-01"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
When I was younger, I didn't really communicate at all with the wider programming world. At the time, I was programming on an early 2010s iMac with a stock copy of Python 3 IDLE installed, trying to make games using Tkinter and PyGame. Most of the programs that I created at that time have now been lost. But, I recently did some digging back through many of my old hard drives, and discovered some fascinating things. It seems like the nine-year-old me had accidentally done some very interesting stuff, including some very interesting accidental discoveries. Here is a list of some of the highlights...
|
||||||
|
|
||||||
|
## Object Oriented Programming
|
||||||
|
|
||||||
|
Now, nobody seems to agree on what OOP _actually_ means, so I'll do a quick definition of mine: the encapsulation of application state into re-usable objects with associated public methods to expose ways of mutating state and private methods for internal use of the class only.
|
||||||
|
|
||||||
|
Now, it seems that nine-year-old me had also thought that it might be a good idea to do something like this. I discovered files upon files of large amounts of Python modules containing just functions which would take in a "target" argument. I was intrigued, so I had a deeper dig. I found that the origin of these target objects was almost always a function called "create\_<whatever>". This returned an array which contained data. At the time, I must have thought this was genius. Then, there were functions called things like "destroy\_<whatever>" or "remove\_<whatever>". Basically, we had arrays (which are associative in Python) which were being treated like classes and mutated by what we may call methods. Brilliant!
|
||||||
|
|
||||||
|
Now, not to brag, but I even went as far as to invent singletons. There were some modules which contained an internal variable which contains a reference to the current instance of a "class" and would completely ignore the constructor if needbe and simply return the existing reference. Then, the single reference would be mutated from all around. I don't know if this technically counts as a singleton (these definitions get mutated by corporate "best practices" every other year), but I'm taking credit anyway, dammit!
|
||||||
|
|
||||||
|
You might be thinking "Now, hang on a minute! Python is an OOP language, you liar!". Well, it seems that nine-year-old me either didn't know or didn't understand how to use Python built-in OOP, so I just made my own. Funnily enough, this method is similar to how OOP works in Lua. Turns out that maturing as a programmer really does make you less creative. I could theorise that this is because you begin to expect the tools to do your work for you more than you are expected to just do it yourself.
|
||||||
|
|
||||||
|
## Comma Separated Values
|
||||||
|
|
||||||
|
So, I wrote a program when I was about eleven called the "Turtle Factory. It is loosely based on the Turtle Factory used as one of the activities in the [Carol Vorderman Coding Book](https://www.worldofbooks.com/en-gb/books/carol-vorderman/computer-coding-for-kids/9781409347019) (which is _the_ book from which all by foundation in programming comes from) . However, I decided to take it a step further. It evolved, effectively, into a full on drawing program, with mouse support, scripting support and almost everything else you can think of, except actual good quality drawing. You see, this "drawing program" was using a 640x480 rasterised stock Python turtle canvas. Basically, the quality sucked. However, something that didn't suck was the method of saving the file instructions.
|
||||||
|
|
||||||
|
You see, I couldn't figure out how to save the drawn image as an actual image file. So, eventually, I must have given up and come up with my own solution (this seems to be a recurring pattern). What I was basically doing was saving all the drawing instructions in a file (for example, "down,10" or "goto,100,200"). Does that format look familiar? Well, good, because it's basically just CSV without the column headers. Because Python had some really useful functions for splitting strings, I decided to use it to the best of my ability. I can remember distinctly spending hours debugging the format and accounting for all the errors that can happen and how to inform the user. I can't remember how I initially came up with the format, but I can remember that I was very proud of my work when I was done.
|
||||||
|
|
||||||
|
Looking back, I really would not have done this today. The entire format was _incredibly_ inefficient. Instead of storing the final result, we were instead storing the entire process for _creating_ the file on disk. Imagine if we had to store every single brush stroke that DaVinci made while painting the Mona Lisa. We probably wouldn't have enough storage space in the entire universe. Also, to reload the image, you have to redraw the entire image by going through the sequence of instructions, one at a time and wait for the time it takes for the turtle library to redraw and render the new image. This meant that the image instructions were also read only, or else the entire chain would be broken. So, once an image is saved, it is immutable unless the user suddenly learns to code and edits the file code themselves. It also meant that the image was only accessable _linearly_, making all random access impossible without breaking the entire image.
|
||||||
|
|
||||||
|
Basically, it sucked - **BUT** it was CSV and I invented it. So, again, I am taking credit for a bad invention for all the wrong reasons.
|
||||||
|
|
||||||
|
## IRC
|
||||||
|
|
||||||
|
Now, this one is a bit of a stretch. I was experimenting with my new discovery, UNIX-style sockets! To this day, I am still very good at doing socket programming because of my experience with the Python socket library. At the time, I thought it was so cool that I could send text to other applications or (even!) other users on the network!
|
||||||
|
|
||||||
|
One day, my dad brought home a laptop that he said he wanted me to "road test" for the head of IT at his work. This was my chance! I quickly downloaded Python and wrote a real quick socket program. On my main laptop, I had written a "chat server". This chat server would append your username to the start of your message, followed by a colon, and then the actual message text. Finally, the server would recieve the message and send back a response. Make sense? Well, it worked, but with some glaring flaws. For instance, you could crash the server by pressing Control-C or Control-D during program execution. The former would cause an IOException on attempting to read from a dead socket, the latter would cause an IOError when attempting to read from an EOF'd file stream. Because I didn't really like this, I decided to add a command system. At the time, the only other chat I had ever used was the good old Roblox chat, so I used the same format: a forward slash followed by the command name. One of these was "/quit", which would gracefully close the connection and allow the next person who wanted to chat to enter the server's connection slot. Later, I added admin commands (still in the Roblox style: a colon followed by the command name). For instance, ":stop" would stop the server, ":kick" would clear the socket connection buffer (kick off all pending clients) and stuff like that.
|
||||||
|
|
||||||
|
So, I had basically drafted up my own version of the IRC protocol, but with a stupid, cringe command system and no actual IRC goodness (no channels, user-to-user etc.)
|
||||||
|
|
||||||
|
## Finite State Machines
|
||||||
|
|
||||||
|
Now, you might start to shake your head at this point and wonder "Is he really trying to take credit for finite state machines?". Well, no, of course not. But I sure am going to boast about the fact that I accidentally created one while attempting to do a LeetCode problem that I was not nearly qualified for.
|
||||||
|
|
||||||
|
When I was still learning Python, I was once linked the classic LeetCode ["Simple" Calculator challenge](https://leetcode.com/problems/basic-calculator/). Now, whoever linked me this was probably just messing with me and didn't actually expect me to actually attempt it. A whole load of attempts later, however, and I was there. I distinctly remember that, at the time, I was programming on an early-2013 iMac with a Python 3.4 install on it. Everything I tried seemed to come up false - until, that was, I came up with my revolutionary _context system._ You see, my version of the finite state machine was, basically, a load of variables laid out which I called the "calculator context". Basically, the context would decide as to what was allowed next and what the meanings of numbers were in context. For instance, if the context said that we have just parsed a number, any operation (including subtraction) would require an operand and the context would _shift_ (yes, I did use that terminology) over to "awaiting operand". However, if the context was "awaiting operand" or "nil", a subtraction or addition would modify the signature of the number. Genius! I thought that this was immensely clever. LeetCode, unfortunately, didn't agree. Somewhere on the hard drive of the iMac is the hundreds of lines long solution that I wrote, filled with immense amounts of if, else-if and else statements for every state that wasn't illegal. The solution is probably still at the bottom of the league table in terms of both space and time complexity.
|
||||||
|
|
||||||
|
In theory, the solution should have worked flawlessly. However, I kept finding corner cases based on the fact that _my_ implementation of a finite state machine was completely broken and based around far too much junk. The most common bug in the code was me forgetting to toggle off one of the "state indicators" - as I called them - after a state shift. I could have abstracted this into a function. I _could_ have just used a single state which changed to multiple different values. Instead, I used multiple different booleans.
|
||||||
|
|
||||||
|
A mess. But, I was still learning.
|
||||||
|
|
||||||
|
## In conclusion
|
||||||
|
|
||||||
|
I could try to make some grand philosophical point here about how "nothing is truly unique" or "great minds think alike" or whatever - but, instead, I would just like to leave some words of encouragement for other programmers learning. Once, I could hardly write a simple Python application without it having ten thousand bugs. Now, I get annoyed at myself when my code doesn't work first time. The messy and experimental process of learning is one which can never truly be reasoned with, in that you have to see where it takes you. If that takes you to a horrible re-invention of a finite state machine, a version of OOP that would probably make Bjarne Stroustrup throw up, or a parallel universe version of IRC, all of these things are valuable milestones in your programming journey. As soon as you have some parallel to these famous ideas in your own mind, you have reached your own personal milestone along the path that computer scientists took all those years ago. You stand on the shoulders of giants. One day, someone will stand on your shoulders. And, if that means a few more terrible Python scripts - so be it.
|
20
content/blog/old/2021/autism-pride-day/index.md
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
title: "I do not want an autism pride day"
|
||||||
|
date: "2021-06-18"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
Apparently, the day I am writing this on is "officially" designated as "[Autism Pride Day](https://en.wikipedia.org/wiki/Autistic_Pride_Day)". According to Wikipedia, this day is "designated to celebrating autistic people and recognising the importance of pride for autistic people and its role in bringing about positive changes in the broader society".
|
||||||
|
|
||||||
|
I have been diagnosed with Asperger's Syndrome and I do not want an autism pride day - _at all._
|
||||||
|
|
||||||
|
Now, this day (probably intentionally) is placed in the purview of Pride Month, which is collectively designated to "celebrating" lots of different arbitrary groups in society. Everything which I say about Autism Pride Day is also applicable to this celebration too, but I think it is more impactful if I talk about something which is close to home for me.
|
||||||
|
|
||||||
|
Autism Pride Day is the perfect encapsulation of everything that I despise about modern society. In our never ending quest to try and be as open-minded as possible to lots of different kinds of people (as liberalism, Christianity and general morality tells us to), we have fallen down a very difficult to escape hole: we have begun to value who a person is more over what they have done. I am a strong believer in the principle that a person should be valued based on things they have done and achievements in life (particularly when against all odds or in unlikely circumstances), and that simply being yourself is not an achievement - particularly in modern society. If we wish to truly have a situation where we are open to everybody, our default state should not be re-enforcing the idea that there are certain special classes of person whom are separate and who have a celebration apart from everybody else. The baseline of society should be that these people exist and that we simply have to deal with this. Yes, autism is a real thing. Yes, it sometimes makes life more difficult - but life is hard. Every single person in the world _will_ go through suffering and trials at some point. It just turns out that autistic people have a handy name for the trials in their lives. We have to deal with this just as people have to deal with the losses of family members, those close to them and issues in their social life. It is just another arbitrary obstacle that life throws at people randomly. It happens.
|
||||||
|
|
||||||
|
We do not need celebration for who we are. There is no need for this, and it completely undermines the whole meaning of acceptance. If autistic people are simply accepted as existing in society, then why is there a special celebration for us apart from everybody else? This is not needed.
|
||||||
|
|
||||||
|
Back in the 1960s, Martin Luther King said that he wanted us to be judged by the "content of our character", not the "color of our skin". If you factor out "color of skin" and replace it with any other arbitrary characteristic, (in this case "presence of autism") you have arrived at my conclusion on this whole matter. I do not wish to be reduced to one part of me which I have done nothing to achieve: I was born this way - move along please.
|
||||||
|
|
||||||
|
We do not celebrate people for being white, male, female, having brown hair or blue eyes - and we shouldn't. In the same vein, we should not celebrate a person simply by virtue of having been born autistic.
|
After Width: | Height: | Size: 88 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 51 KiB |
After Width: | Height: | Size: 64 KiB |
After Width: | Height: | Size: 114 KiB |
After Width: | Height: | Size: 57 KiB |
85
content/blog/old/2021/blm-twitter-comic-response/index.md
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
---
|
||||||
|
title: "\"For all the 'All Lives Matter' Supporters\" - A Response"
|
||||||
|
date: "2021-02-18"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
Recently, I was made aware of the following cartoon comic strip created by a Twitter user:
|
||||||
|
|
||||||
|
<figure>
|
||||||
|
|
||||||
|
[![](images/ALM_retort.jpeg)](https://www.ethanjmarshall.co.uk/wp-content/uploads/2021/02/ALM_retort.jpeg)
|
||||||
|
|
||||||
|
<figcaption>
|
||||||
|
|
||||||
|
This image was posted to a twitter account "Crab Nighty" - page at [https://twitter.com/crabnighty/](https://twitter.com/crabnighty/)
|
||||||
|
|
||||||
|
</figcaption>
|
||||||
|
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
Now, from inspecting this account a little further, it is pretty clear where their biases lie...
|
||||||
|
|
||||||
|
<figure>
|
||||||
|
|
||||||
|
- [![](images/Wants-to-brainwash-kids.png)](https://www.ethanjmarshall.co.uk/wp-content/uploads/2021/02/Wants-to-brainwash-kids.png)
|
||||||
|
- [![](images/Says-woke-is-positive-change.png)](https://www.ethanjmarshall.co.uk/wp-content/uploads/2021/02/Says-woke-is-positive-change.png)
|
||||||
|
- [![](images/Complaining-about-appropriation.png)](https://www.ethanjmarshall.co.uk/wp-content/uploads/2021/02/Complaining-about-appropriation.png)
|
||||||
|
|
||||||
|
<figcaption>
|
||||||
|
|
||||||
|
I mean, they kind of speak for themselves...
|
||||||
|
|
||||||
|
</figcaption>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
And the account doesn't seem relatively used, with a grand total of only 25 tweets. However, one of the ones that they themselves have made that did gain quite some traction is one "debunking" arguments that, mainly conservative, members of the public have been making against Black Lives Matter. When I first came across this, I thought it was one of those political cartoons that people like to make, and I guess it still kind of is. But, the arguments contained within it seem very "XKCD on free online speech" to me (for an example of what I'm talking about, see [here](https://xkcd.com/1357/)). In other words, it's technically true, but also kind of not at the same time and is used to justify things that it should not be used to justify.
|
||||||
|
|
||||||
|
In this post, the author claims that the idea around Black Lives Matter as an organisation is to make sure that all lives matter. And, sure, I can imagine that is the goal that many of its supporters have in mind. But, the problem arises when it begins to compromise and make the lives worse for those of other races (for no reason other than their race) because they wish to make black lives better.
|
||||||
|
|
||||||
|
Don't believe me? Well, BLM encourages the lie that whites have inherent privileged over blacks and should therefore be punished for it (which has been [attacked](https://quillette.com/2019/08/22/why-white-privilege-is-wrong-part-1/) [to](https://quillette.com/2019/10/16/why-white-privilege-is-wrong-part-2/) [hell](https://thecritic.co.uk/issues/december-2019/no-need-to-plead-guilty/) [and](http://www.vanguardnewsnetwork.com/2014/12/why-the-term-white-privilege-is-bogus-and-marxist/) [back](https://www.theodysseyonline.com/why-white-privilege-is-as-racist-as-it-sounds) by those opposed to it - even by [black Americans](https://youtu.be/HMSTDsMXoD8)), [banned whites from their meetings](https://247sports.com/college/texas-tech/Board/102960/Contents/Black-Lives-Matter-Bans-White-People-From-Attending-Open-Meetin-54647768/) (again, for no reason other than race) and encourage affirmative action, which is literal discrimination against those who are not on a list of "approved minorities" to make sure that more of said "approved minorities" are in a certain job post. Not only that, but they repeatedly encourage and [call for violence against](https://youtu.be/dj4ARsxrZh8) those for their race/occupation (so, basically, being the collectivist racists that they claim to be against).
|
||||||
|
|
||||||
|
So, I think it's safe to say that BLM is harming the lives and livelihoods of other races in its supposed "effort" to improve the lives of black Americans. And so, when the author says:
|
||||||
|
|
||||||
|
[![](images/forests-panel-1.png)](https://www.ethanjmarshall.co.uk/wp-content/uploads/2021/02/forests-panel-1.png)
|
||||||
|
|
||||||
|
[![](images/forests-panel-2.png)](https://www.ethanjmarshall.co.uk/wp-content/uploads/2021/02/forests-panel-2.png)
|
||||||
|
|
||||||
|
Their argument is flawed in that my response _totally would_ be to say "All forests matter" to a protester to save the rain forest if their solution to cutting down the rainforest is to burn down all other forests on earth - which is comparable to what BLM is doing but with race divisions. Another example: I would respond "actually, all oceans matter" if somebody's solution to the Atlantic Ocean's sea level rising was to dump all the water into the black sea and flood several countries. The author trips himself up in his original post when he says that it "doesn't mean that we think the other forests have no value" - which, ironically, is how the BLM organisation treats the livelihood and relations to other races: worthless. The point being that a major part of the conservative backlash towards BLM as an organisation is their attitude towards other races and their seeming inability to actually follow through in their promise that they simply want all lives to matter equally. If BLM wants my confidence back that they are a simple, honest organisation focused on equality, they should start by publicly opposing affirmative action in all forms and remove the sections from their manifesto which state that whites should be "[giving up property for black families](https://nypost.com/2020/08/14/seattle-blm-protesters-demand-white-people-give-up-their-homes/)". Until they make these fundamental changes to the things that their organisation believes in, you are going to keep hearing this retort to your protesting - so I'd get it done sooner rather than later, if I were you.
|
||||||
|
|
||||||
|
_But that's not everything that's wrong with this argument though._
|
||||||
|
|
||||||
|
This poster appears to have assumed that the only valid (or even the main) argument against BLM is on the grounds that they do not consider that all lives truly matter. And, although I personally do not believe that they do take that seriously enough, this isn't even one of the main arguments I hear. The main ones I hear are that:
|
||||||
|
|
||||||
|
- BLM was founded by three Marxists who exploit calls of racism and black Americans to gain power
|
||||||
|
- BLM exploits and devalues the police force (effectively throwing them under the bus) for mistakes which had little to do with racism
|
||||||
|
- BLM has an agenda which involves very sketchy (and sometimes racist) goals which also involve the brainwashing and controlling of children in schools
|
||||||
|
- The BLM organisation has been one of the biggest causes of disarray and racial tensions, despite claiming to aim to do the opposite
|
||||||
|
|
||||||
|
The point being that many people have lost faith and confidence in this organisation for many reasons other than the hypocrisy and failure to actually do their job.
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
|
So, let's sum up. The author of this comic strip's argument is not only fundamentally flawed in its approach of the opposition, but also fails to properly understand or actually fully consider the argument against themselves. Oh, yeah, and:
|
||||||
|
|
||||||
|
<figure>
|
||||||
|
|
||||||
|
[![](images/supposed-personal-growth.png)](https://www.ethanjmarshall.co.uk/wp-content/uploads/2021/02/supposed-personal-growth.png)
|
||||||
|
|
||||||
|
<figcaption>
|
||||||
|
|
||||||
|
**I'd just like to interject for a moment:** What you are referring to as "personal growth" is in fact "growth as a leftist" or as I've recently taken to calling it "growth as an unknowing social Marxist"
|
||||||
|
|
||||||
|
</figcaption>
|
||||||
|
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
Yeah, not so sure about that buddy.
|
||||||
|
|
||||||
|
So please, for your own sake, don't try and take this comic strip seriously as an argument. It's a cool little piece of art and I will admit it's written snappily (better than anything I could do). That does not make the argument contained any less invalid.
|
||||||
|
|
||||||
|
Oh, and one last thing: yes I am aware of the watermark in the bottom right hand corner suggesting that somebody made this other than the person I linked, but (as far as I am aware) this was just the artist and the person I linked was the _actual_ creator. So, good art "Scarecrowbar", bad argument "Crab Nighty".
|
82
content/blog/old/2021/c-golden-rule/index.md
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
---
|
||||||
|
title: "The Golden Rule of C Programming"
|
||||||
|
date: "2021-06-26"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
The C Programming Language is my all time favorite programming language. Not only do I write as much of it as possible, I have yet to come across any problem that C is incapable of solving - which is simply not the case for languages such as JavaScript or PHP. But, I would be an absolute lier if I were to claim that C is perfect. The high-level ease yet low-level control that C hands to the programmer is often criticised as not hiding enough details away from the user. Now, I like it this way, but it does have some unfortunate consiquences. For instance, in Python, to get user input, all you have to do is the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
string = input()
|
||||||
|
print("Hello " + string)
|
||||||
|
```
|
||||||
|
|
||||||
|
Literally a five second job.
|
||||||
|
|
||||||
|
In C, this is made rather difficult by the fact that you need:
|
||||||
|
|
||||||
|
- Variably sized inputs
|
||||||
|
- Dynamic string allocation
|
||||||
|
- Dynamic string appending
|
||||||
|
|
||||||
|
If you're wondering, the full equivalent in C (with any length of string being supported) is the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
printf("Enter name:");
|
||||||
|
|
||||||
|
int alloc = 5;
|
||||||
|
int len = 0;
|
||||||
|
char *buf = malloc(sizeof(char) * len);
|
||||||
|
|
||||||
|
char in;
|
||||||
|
while ((in = getchar()) != '\n' && in != EOF) {
|
||||||
|
if (len + 1 > alloc) {
|
||||||
|
alloc += 5;
|
||||||
|
buf = realloc(buf, sizeof(char) * alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[len++] = in;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Hello %s\n", buf);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Quite a mouthfull. Now, this C code can handle as many characters as the operating system is physically willing to give us space to store and will carry on reading characters until a newline or standard input ends. So, basically, this does exactly what Python is likely doing under the hood. Now, at first glance this might make you think that C is an absolutely awful programming language that you should never use. But, in reality, this is a perfect example of _The Golden Rule of C Programming_:
|
||||||
|
|
||||||
|
> Where exactly is this memory coming from?
|
||||||
|
>
|
||||||
|
> Ethan James Marshall - 2021
|
||||||
|
|
||||||
|
Unlike in languages such as Python, memory in C is shown directly to the user as it is: a big, long list of bytes, some of which we can read from - others which we can write to. You need to find space in this big, long list which can be written to safely and which your program can keep track of. In many schools, C isn't taught like this. Instead, teachers tie themselves in knots trying to explain pointers with "move semantics" and "pass by reference" stuff. In reality, you could avoid all this confusion by just explaining how C and memory work in computing. In addition to this, if more people understood how memory works internally, we would have a whole lot less of people asking the following:
|
||||||
|
|
||||||
|
"Why can't C just have a function that returns an inputted string for us?"
|
||||||
|
|
||||||
|
By this, they mean something like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
char *string = input("This is a prompt"); /* This is a fictitious function */
|
||||||
|
|
||||||
|
printf("%s was the string entered\n", string);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Obviously, this wouldn't compile, because the function "input" is fictitious. However, you may ask yourself: how are they wrong? Why can't the C library just return us the string the user entered? Well, that's because the C library can't just conjure memory out of nowhere. **Where would that memory come from?**
|
||||||
|
|
||||||
|
Well, let's think to ourselves where we could possibly store this data, if we were the designers of the C standard library. Well, it can't be stored statically in the executable, because we don't know the size at compile time. We can't make it a string literal, because they are stored in the constant data section (and are also a fixed size, for that matter). We can't use the stack, because that is tied to the lifetime of the function call (and is also usually a fixed size - again). So, our only real option is to use the heap. That sounds fine, but the only problem with that would be that the code above now contains a memory leak and would need to explicitly free the string pointer returned before we can say this is safe. That means that a function call to the standard library may (and probably will) cause a memory leak - or at the very least introduce a great deal of complexity for the programmer to deal with. Not good. On the whole, it seems best that the C standard library works with just fixed size data that can be worked with totally safely and let the programmer choose if he wishes to add a layer of complexity on top of that.
|
||||||
|
|
||||||
|
Now, of course, C++ doesn't have this program, because it can actually make pointers on the heap last the lifetime of a function call, which is not possible as a core part of the C language because of how heaps are implemented for flexibility. A C++ class/function can simply allocate as much dynamic memory as it wants and have it tied to a destructor which will be called on the scope being exited - kind of like scope-oriented heap memory.
|
||||||
|
|
||||||
|
So, essentially, whenever you find yourself getting angry at C for not making your life easy, just think to yourself. Where do I expect this memory to come from? How do I expect the C language to give me this information? If the answer is just "magic", maybe have a think to yourself about how to program without asking miracles of the C standard library. Afer all, K&R were geniuses, but they weren't miracle workers.
|
BIN
content/blog/old/2021/climate-suspicions/images/biases.png
Normal file
After Width: | Height: | Size: 540 KiB |
BIN
content/blog/old/2021/climate-suspicions/images/communism.jpg
Normal file
After Width: | Height: | Size: 100 KiB |
BIN
content/blog/old/2021/climate-suspicions/images/conflation.jpg
Normal file
After Width: | Height: | Size: 161 KiB |
BIN
content/blog/old/2021/climate-suspicions/images/justice.png
Normal file
After Width: | Height: | Size: 249 KiB |
BIN
content/blog/old/2021/climate-suspicions/images/socialism-1.png
Normal file
After Width: | Height: | Size: 508 KiB |
BIN
content/blog/old/2021/climate-suspicions/images/socialism.png
Normal file
After Width: | Height: | Size: 508 KiB |
After Width: | Height: | Size: 913 KiB |
BIN
content/blog/old/2021/climate-suspicions/images/societs.png
Normal file
After Width: | Height: | Size: 516 KiB |
148
content/blog/old/2021/climate-suspicions/index.md
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
---
|
||||||
|
title: "Why People Are Suspicious of Climate Activism"
|
||||||
|
date: "2021-11-06"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
I should preface this with a half disclaimer: I actually do believe in climate change and think that it is a real problem which needs solving. From a purely engineering-based point of view, fossil fuels are a finite resource which is destined to run out at an increasingly exponential rate. As demand increases, the amount of these fuels we would have to burn would also increase, leading to their exhaustion at an increased rate, making it next to impossible for us to replenish them. Therefore, I do think that moving away from fossil fuels is important and will be required in the near future. However, I am much more optimistic than many climate activists. This will just be one other small blip of a problem on the journey of human progress that we _will_ solve and that won't set us back very far.
|
||||||
|
|
||||||
|
**However**
|
||||||
|
|
||||||
|
There are a lot of people who are _very_ suspicious of environmental activism in general who would heavily disagree with me. These people like to cite evidence such as previous "climate scares", such as cooling in the 70s and previous conditions of climate CO2 content in relation to climate state. In my opinion, these reservations are misled, as the evidence we must look at must be in relation to current states, as looking at previous statuses ignores a wide array of external stimuli which could have affected the correlation. We must consider _present_ evidence. Unlike many "climate believers" of my generation, however, I am much more understanding of those who "deny" - or who have reservations about - the idea of climate change. Everything in this movement seems to have aligned in order to make certain kinds of people very suspicious of this movement in general. In this summary, I would like to summarise many of the reasons why people are suspicious of this movement, and, ultimately, why it leads them to the substandard conclusion that climate change is not real.
|
||||||
|
|
||||||
|
First and foremost, it is important to consider wider political state in the current era. I would like you to consider the following images.
|
||||||
|
|
||||||
|
<figure>
|
||||||
|
|
||||||
|
[![](images/justice.png)](https://www.ethanjmarshall.co.uk/wp-content/uploads/2021/11/justice.png)
|
||||||
|
|
||||||
|
<figcaption>
|
||||||
|
|
||||||
|
Notice the conflation of "climate" and "social" justice
|
||||||
|
|
||||||
|
</figcaption>
|
||||||
|
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
<figure>
|
||||||
|
|
||||||
|
[![](images/communism-1024x576.jpg)](https://www.ethanjmarshall.co.uk/wp-content/uploads/2021/11/communism.jpg)
|
||||||
|
|
||||||
|
<figcaption>
|
||||||
|
|
||||||
|
Notice the pride and USSR flags
|
||||||
|
|
||||||
|
</figcaption>
|
||||||
|
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
<figure>
|
||||||
|
|
||||||
|
[![](images/conflation.jpg)](https://www.ethanjmarshall.co.uk/wp-content/uploads/2021/11/conflation.jpg)
|
||||||
|
|
||||||
|
<figcaption>
|
||||||
|
|
||||||
|
More conflation of goals and clear influences
|
||||||
|
|
||||||
|
</figcaption>
|
||||||
|
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
<figure>
|
||||||
|
|
||||||
|
[![](images/biases.png)](https://www.ethanjmarshall.co.uk/wp-content/uploads/2021/11/biases.png)
|
||||||
|
|
||||||
|
<figcaption>
|
||||||
|
|
||||||
|
Try to spot how many political affiliations there are. Notable mentions "Socialist change" being wielded by a child; and "Scottish Labour" wielded prominently.
|
||||||
|
|
||||||
|
</figcaption>
|
||||||
|
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
<figure>
|
||||||
|
|
||||||
|
[![](images/socialist-child-1024x551.png)](https://www.ethanjmarshall.co.uk/wp-content/uploads/2021/11/socialist-child.png)
|
||||||
|
|
||||||
|
<figcaption>
|
||||||
|
|
||||||
|
A **CHILD** wielding a sign from the Socialist Workers' Party which reads "The Solution: Revolution". To reiterate: **A CHILD**
|
||||||
|
|
||||||
|
</figcaption>
|
||||||
|
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
<figure>
|
||||||
|
|
||||||
|
[![](images/socialism-1.png)](https://www.ethanjmarshall.co.uk/wp-content/uploads/2021/11/socialism-1.png)
|
||||||
|
|
||||||
|
<figcaption>
|
||||||
|
|
||||||
|
A substantial block of protesters claim to "decolonize the planet" and to "rally against capitalism", having signs endorsed again by the Socialist Workers Party
|
||||||
|
|
||||||
|
</figcaption>
|
||||||
|
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
<figure>
|
||||||
|
|
||||||
|
[![](images/societs.png)](https://www.ethanjmarshall.co.uk/wp-content/uploads/2021/11/societs.png)
|
||||||
|
|
||||||
|
<figcaption>
|
||||||
|
|
||||||
|
The Red Banner of the former Soviet Union flies over a protest in Glasgow
|
||||||
|
|
||||||
|
</figcaption>
|
||||||
|
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
Can you spot the pattern? Climate protesters are almost always overwhelmingly left-wing intellectuals of the kind Orwell described in The Road to Wigan Pier: flabby, middle-class hippies with radical ideas which reach beyond the ideas they claim to simply be proponents of. There are two commonalities with the events described in these photographs. I will discuss them each in turn.
|
||||||
|
|
||||||
|
## Political Biases
|
||||||
|
|
||||||
|
Climate activists are not as they seem. As I outlined above, climate protesters are overwhelmingly left-wing and with radical agendas which completely disregard any other, even moderate, parts of politics. To the average person as it is to the political activist, this appears as though a cause has been co-opted with those with a wider political agenda to steer it as a bargaining chip for their aims. Upon realising that the average proletarian in the United Kingdon is not really big on revolutions and overthrowing their happy jobs (I know this from wide-ranging experience), they have shifted their focus. This shift forked into two different camps: the _intersectionals_, who focus on intersectionality and the "opression" of individual classes in society (such as race, gender etc.); and the _greenfingers_, who instead claim that capitalism is inherently exploitative of the environment and needs to be overthrown for this reason. This is clearly a distortion of the true aims behind the movement. If these people truly cared about this cause and were't just muscling in with the aim of distorting its true goals, they would attempt to unite everybody on the political spectrum on this issue. Instead of marching around with prominent signs reading "Socialists unite", they would instead point out the _hard facts_ on what is going on and why it needs fixing. Instead of [openly admitting to being radicals](https://youtu.be/aZETMhAf2uc?t=20617), they would instead attempt to reason with the general populus and fix this problem in a calm, orderly fashion. More on fear will be discussed later.
|
||||||
|
|
||||||
|
Let's take for one moment one of the most famously immovable political groups in the world: libertarians. Libertarians believe in freedom and little more. They believe in hard limits on government power and will fight the government when it oversteps these boundaries. These people make up a substantial part of the voter base in the United States and many other locations - particularly places such as Switzerland. The climate protesters have completely ignored these people's concerns and left them in the gutter as they march forwards demanding the complete antithesis of what these people wish. They call them "climate deniers" because of real concerns about the methods they are using. I myself am not a libertarian for a variety of reasons, but I can understand their viewpoint as completely valid. So, I find myself wondering: why have the climate protesters completely ignored the concerns of an entire unrelated group inthis way, while being eager to take onboard the collective wisdom of socialist economists? It is clear to me that something wider is going on here. Certain political groups are being particularly excluded. These groups are not random and are not by chance, and that is why these particulary groups will be particularly suspicious of any kind of climate activism.
|
||||||
|
|
||||||
|
## Use of Children
|
||||||
|
|
||||||
|
I said earlier that these images have a twofold commonalities. The primary is the left-wing nature of their biases. The second is their usage of children.
|
||||||
|
|
||||||
|
Children _should never_ be moral legislators. I know this from, technically, being one myself. Children are always, without fail, the most radical in their youthful feelings. Let's again examine one of the best historical records of socialism in the 1920s: The Road To Wigan Pier to find out why. Orwell outlines how, in his youth, he was very clearly a Bolshevik communist - and so were all of his classmates in a middle class school in London. As he grew, he saw many of them mature into simple socialists, unionists and less extreme idiologies. However, he believed that these people, had they been moral legislators in their youth, would have ushered in communism as a child. This is a repeating pattern throughout history. In the 1960s, young hippie communists were largely responsible for revolutionary social change (and arguably communist implantation) in the United States. Some of their changes were good. Some of them still haunt us to this day. In 2021, young children with very little understanding of how the world works and what it feels like to work a real job are now being looked to to morally legislate the actions of the old and wise. "It's our future!", they say. Well, it's the adults' world. "So what if the price of food goes up? We're saving the world!", they say. "So what" may not be the question on the lips of the struggling joiner in a working class town.
|
||||||
|
|
||||||
|
I can propose a theory for this. Children are, without fail, the most extreme in their opinions because of lack of exposure to the opposing sides of a debate. In their understandable youthful ignorance, they have been exposed to a carefully prepared slice of the world's perspectives on a matter. And so, seeing only a small part of a big picture, they tend towards the most extreme and "hippy" opinions of their time. I have seen this in myself. In past years, I saw people in poverty and saw people being evicted due to failing to pay bills. This led me down the ever-present communist road. I hated landlords with a passion, despite having never met one. However, I am now slightly more pleased to say that my viewpoint has changed back to being non-revolutionary in any way. Today I am probably more economically conservative. The wider picture of the things I witnessed were eye-opening. An eviction may, at first, appear like a disgusting show of power. Once I learned that the lady acting as the landlord had three children to feed and worked in the local newsagents, my dislike of her immediately dissolved. Had that man been allowed to stay, she would likely be the homeless one, all because the tennant was refusing to pay their rightly due rent for using her property which she maintained.
|
||||||
|
|
||||||
|
As for the rest of the children involved, I can only assume they are being used as talking heads for their parent intellectuals. As a general rule, it is a red flag (somewhat literally) when a child is being fed responses by a team. It almost seems like they are being used as a pawn for the change adults want. This will undoubtably promote suspicion of those of us priviledged enough to have read enough history to realise what the encouragement of the indoctrination of children leads to. Bearing in mind, I am talking about a cause I _agree_ with, but this should simply not be happening. Children are not props. They should be allowed to think freely without being used to promote social pressure and whip up hysteria (again, more on this in a moment).
|
||||||
|
|
||||||
|
In summary, children should _never_ be moral legislators. That is not to say that the adults in the room should not consider the interests and the futures of children when making decisions; that is, of course, the moral thing to do. But most children are like I was, and I was in no fit state to be making decisions.
|
||||||
|
|
||||||
|
## Use of Fear
|
||||||
|
|
||||||
|
I recently had to perform the sad task of going through the belongings of my dead father. This was mostly a sad task, until a little ray of sunshine shone through: I found his old, signed Elbow CDs in his school satchel. However, what I found underneath this was the most interesting. Underneath this was a poster from his chemistry lab when he taught as a science teacher. This was clearly printed in the early to mid nineties, as it claimed that "acid rain will have completely destroyed all forests on earth by the early 2000s". Among other dire predictions, it also claimed that we had "until the end of the decade to reverse the greenhouse effect before mass food shortages began". I don't know if you know the nineties and early two-thousands, but "mass food shortages" would not be how I would describe them. Economic stability and surplus goods tend to characterise the nineties, with political stability being another important feature.
|
||||||
|
|
||||||
|
But, this speaks to a wider issue, which is that this movement has clearly capitalised on existential fear of the nth degree. When you study any kind of social engineering (my field being particularly related to computer security and "hacking the human"), one of the first things they teach you is that **fear is the most powerful emotion.** It overpowers both love and greed, happiness and grief. Fear clouds the senses and dulls the mind's eye to the point where the skull is so thin anything which wishes to lodge itself in there is completely welcomed. There is a reason that most phone scams start out with alarms blaring and a warning message about financial compromise or legal threats. It makes you more likely to fall for a scam. I think it should be evident why, then, people are very suspicious of any activist group which capicalises upon fear.
|
||||||
|
|
||||||
|
Not only have the activists themselves capitalised on fear, the media has a large part to play in this too. The media has realised in the modern day that, as they are now making revenue based on advertisement clicks, they need to pump out as much content as possible which people will click on and remember. To do this, they have called upon the commonly cited psychological trait known as the "negativity bias". Simply put, a negative experience or report will weight much more heavily and consciously on the mind of the average man than a positive one. The media, therefore, pumps out as much panic-inducing, depression-sparking, doom-and-gloom nonsense as they can. There has been not a single report by ITV, BBC or Channel 4 News which reports the giant leaps forward we are making and have made. Please see [here](https://youtu.be/TBYDgJ9Wf0E) for a nice summary of some of the highlights you have missed, many of which spark my optimism about this subject. But, if you were to listen to the mainstream media on this topic, you would likely believe that we are still in the 1920s, burning hundreds of tonnes of coal every day to power a single working town. The media have radicalised a section of the population. Those sceptical are well aware of this, yet were simply radicalised in the opposite direction.
|
||||||
|
|
||||||
|
## Establishment Support
|
||||||
|
|
||||||
|
Throughout history, ideas which strongly challenge the _status quo_ were margainalised and surpressed by the establishment. The media would quell their movements, the parliaments would shun them and the politicians would pretend they don't exist. Is this happening to Greta Thunberg and her supposed anti-establishment rallying cries? No, of course not. Every time she demands something increasingly outlandish and extreme, the extablishment rushes to calm her and make peace with her mob of protesters. Why could this be? It is almost like _these_ people are, in fact, the establishment, not what they fight against. Their message is echoed by every large media corporation, politician and corporate body. Simply questioning their motives and goals gets you labelled as a "conspiracy theorist" or a "hopeless contrarian". These people hold a tremendous amount of power, and yet they still maintain that they are in a position of "fighting the system" and "rallying against the establishment". You need only glance at the images above to see that many of them truly believe it. They have likely come to this conclusion based on the fact that many of their extreme goals are simply logistically impossible. Take, for instance, the average Extinction Rebellion member, who believes we should outright ban fossil fuels, cars, planes, some foods and fun (but not the last one - maybe). When they demand that we completely axe a lot of core economic principles, which keep people afloat and stops mass human suffering, the politicians refuse. Then, despite the groveling attempts of the politicians to apologize to them, they think they are being surpressed when their message is not dictated straight into law.
|
||||||
|
|
||||||
|
Meanwhile, people with certain opinions _literally forbidden under law_; people being constantly demonised and hated for simply wishing to live their lives; and people who are dealing with big problems in their own lives are called opressors and "The Avont Garde" because some climate protester across the country didn't get to write the letter of the law. That is why establishment support stokes such suspicion, particularly in some counter-cultural departments.
|
||||||
|
|
||||||
|
There are some communities on the internet which, despite being completely related to saving the planet and living a more sustainable future, completely reject these climate protesters and, often get led down the path of outright climate nihlism. Why? Because their opinions of how to solve this crisis are not mainstream, and so they are called "the opressive establishment" and the "business as usual bregade", by protesters like Thunberg. Groups like the followers of former-naturalist John Seymore (who advocated for a return to traditional, small-scale and distributed farming, in place of low-quality, industrial, centralised farming) have been pushed to the extremes of the climate debate by the supposed counter-cultural movement, which really contains the purest forms of the establishment. If this fact alone does not push these groups towards deep suspicion, if not complete nihlism as mentioned before, I don't know what does.
|
||||||
|
|
||||||
|
## Worship of Idols
|
||||||
|
|
||||||
|
It is my fear, and the fear of many "deniers", that climate protesting has become less about critical thinking, wanting concrete solutions and change, and more about worshipping a certain group of key idols which dictate to us our goals and wishes. There is no better example of this than Greta Thunberg. Greta has no scientific qualifications. She has no experience in the field of geological engineering or power production. She is a child. However, she is a child whoose power stems from the herd (more accurately mob) of people behind her. This kind of mob seems to have formed a kind of religious cult of personality around this random child engaged in activism. Even completely ignoring all of the factors around children I outlined above, this is a single person who is dictating the wishes and policy of all those below her. Essentially, a neo-atheistic religion has been formed around Our Lady Thunberg and her army of climate protesters.
|
||||||
|
|
||||||
|
Although I would consider myself Christian, I am not blind to the downsides and the history of ignorance and blind faith which has followed religions around. My faith and belief in Christian values does not come from a blind reading of the Bible, but more from an appreciation of traditional values and the upsides which come with them. When I say "God bless you" when somebody sneezes, it is not (as it was for the original use of that phrase) because I actually believe that God may save this person from ills; it is because this traditional phrase represents much more than this. It is a representation of saying "I wish the greatest power in the universe to do you well": the ultimate wellwish. Traditional religion, however, seems to be plagued with arbitrary dictation of ideas. In particular, religions which focus less around moral stances and more around faith in a single, fallable person tend towards this end. This perfectly describes many of the tendencies of modern day climate protesters.
|
||||||
|
|
||||||
|
With traditional religions having been largely removed from a large prat of public life, people instead turn to other idols for worship, replacing the traditional idea of "God" (a representation of all that is good and right) and towards some arbitrary person. Some people worship comic book heroes. Some worship politicians. In this case, they worship Greta Thunberg and her goals. Now, I am sure she has good intentions, but I am also sure she is perfectly aware of what is going on. People are rallying around her, treating her like a godess who is all knowing and all good (notice the parallels with the traditional idea of God, again). Once again, another movement falls on its own fictitious sword of pride as it worships an arbitrary nineteen-year-old girl - one who may or may not be under the influence of adults (as mentioned above), at that. I think it is self-evident the effect this will have.
|
||||||
|
|
||||||
|
## Conclusion
|
||||||
|
|
||||||
|
So what can we do about this? As I said earlier in the preface, I am "one of you guys". I think that the earth is in danger and needs saving. But, our current movement has been taken over by communists, socialists, anarchists and revolutionaries from every corner of politics. Our movement is completely alien to the average man in our country, and, indeed, around the world. Something needs to change, but the most important change to happen first is to ourselves. Orwell advocated something similar with socialists in The Road To Wigan Pier. Socialists of his day were, what he called, "flabby, middle-class vegitarians". Effectively, he was describing the 1920s wave of hippies. In order to save ourselves, we must be more reasonable, less reliant upon fear and more upon realistic solutions. "Just ban carbon, bro", is not going to be listened to - by the electorate or by the politicians. Why should Joe Bloggs, the joiner from Bolton town center listen to a bunch of yoga enthusiasts about what fuel he is allowed to use in his car? Because we must ensure that he realises we really do have his best interests at heart. Currently, my suspicion is growing that part of my movement, unfortunately, does not.
|
||||||
|
|
||||||
|
I have neither attended any climate marches, neither will I ever do partially because of this fact.
|
BIN
content/blog/old/2021/cpp-good-bad-ugly/cpp-nutshell.png
Normal file
After Width: | Height: | Size: 58 KiB |
121
content/blog/old/2021/cpp-good-bad-ugly/index.md
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
---
|
||||||
|
title: "C++: The Good, The Bad and The Ugly"
|
||||||
|
date: "2021-07-25"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
![CPP in a nutshell](cpp-nutshell.png)
|
||||||
|
|
||||||
|
C++ is not exactly known for its elegant syntax or concise expressiveness. It is a pretty common joke to hear in the programming world that "C++ is the only language where the error message may actually be longer than the program that caused it". Now, be that as it may, I think its more accurate to say that "C++ is the only language where the symbol name will be longer than the program that uses it". Take the following example:
|
||||||
|
|
||||||
|
```
|
||||||
|
std::cout << game::mainloop::logger::statuslogger::outputstream::formatter::status.getStatusForOutput() << std::endl;
|
||||||
|
```
|
||||||
|
|
||||||
|
Fascinating stuff. You have symultaniously succeeded in creating the most pretentious and yet unreadable piece of code ever written. There is no person alive who can look at this and not think that this is ridiculous.
|
||||||
|
|
||||||
|
Now, if you thought that was bad, just you wait until you see some of the errors that same piece of code can throw at compile time:
|
||||||
|
|
||||||
|
```
|
||||||
|
src/scores-graphics.cpp:59:21: warning: loop variable ‘s’ creates a copy from type ‘const std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>
|
||||||
|
>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >’ [-Wrange-loop-construct]
|
||||||
|
59 | for (const auto s : sbddl) {
|
||||||
|
```
|
||||||
|
|
||||||
|
Yes, you read that correctly. The typename in that piece of code was
|
||||||
|
|
||||||
|
```
|
||||||
|
const std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>
|
||||||
|
>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, if you can please explain to me exactly what that typename is meant to store, please email me, because I want to give you a large sum of money. Another fascinating thing that C++ somehow succeeds in doing is making literally the most basic of problems really overcomplicated. For instance, what if I wish to copy a fundamental type (fixed size, less than processor word length - literally the most basic of CPU operations). Let's take a look at a good example, but let's initially write it in our good old friend C:
|
||||||
|
|
||||||
|
```
|
||||||
|
int var = 5;
|
||||||
|
int copied = var;
|
||||||
|
```
|
||||||
|
|
||||||
|
As you can see, we have created a value _var_ with a static value of "5". We then _copied_ this value into a new variable called "copied". This can be implemented with a single **movl** instruction under the hood: it's really simple. _But not simple enough for C++, of course!_ Instead, C++ has to have a concept of "copy constructors", which means that this literal single instruction operation instead has to compile to a load of garbage. It also means that passing variables to functions is never safe again, or else you get errors like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
gameboard.cpp:138:23: warning: loop variable ‘current_offset’ creates a copy from type ‘const point2D_t’
|
||||||
|
-Wrange-loop-construct]
|
||||||
|
138 | for (const auto current_offset : offset_check) {
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, two problems are posed here. First off, why the hell is it a problem that I created a copy? We do this all the time! What's the problem, C++? In fact, in this case, the actual problem is that the variable is not a fundamental type, so the copy constructor must be called in order to create a copy of this variable. So, in effect, there _is no_ problem; the code is simply less efficient than if a pass by reference were to be used. I had to dig through the GCC manual to find the documentation for that specific warning ID in order to find out why this is even a problem. Whereas, in C, the most complex error or warning you will ever get will _at the very least_ have have a definitive reason for this warning being there, rather than the compiler making arbitrary demands for the purpose of "performance and readability". The second problem is the fact that (although this would make you completely unaware of it), this copy has also called a copy constructor. The error does not mention this at all, but this _could_ leak memory. Just more of the issues with the implicit behavior which so often comes with C++.
|
||||||
|
|
||||||
|
Now, my pet hate in C++ is the ambiguous syntax. For instance, what does the following code do:
|
||||||
|
|
||||||
|
```
|
||||||
|
MyClass instance();
|
||||||
|
```
|
||||||
|
|
||||||
|
What in God's name is that supposed to mean? Are we calling a function with the name "instance"? If so, then why is there a type name in front of it. If this is a variable, why are we calling it like a function. What on earth is this? Well, that this actually does is creates a new instance of the object "MyClass", calling the default constructor. Great, totally clear. You see, the way we do this in C is:
|
||||||
|
|
||||||
|
```
|
||||||
|
MyClass instance;
|
||||||
|
create_myclass(&instance);
|
||||||
|
|
||||||
|
/* Or, alternatively */
|
||||||
|
MyClass *alternate = create_myclass_a();
|
||||||
|
```
|
||||||
|
|
||||||
|
In both cases, it is absolutely clear what we are doing. But, if you thought that was bad, just wait until you discover implicit casting. For instance, observe the following code:
|
||||||
|
|
||||||
|
```
|
||||||
|
MyClass instance = 2;
|
||||||
|
```
|
||||||
|
|
||||||
|
Surely this is a compiler error. Surely... Nope, that's totally valid C++, assuming that a constructor exists which can implicitly convert this. What this will actually compile as is equivalent to the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
MyClass instance = MyClass(2);
|
||||||
|
```
|
||||||
|
|
||||||
|
_Why did this need to be a thing?_ Seriously, **when does this produce better code than just writing good code?** I genuinely don't understand. What is the point in this feature? Well, after in-depth research, it's apparently for situations like the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
/* Will create a vector with 5 somewhere? */
|
||||||
|
Vec2 vector = 5;
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, what does this code do? Good question because even this code, with its fancy implicit conversions and casting, is now ambiguous. What field in the vector does this variable get assigned to? What is the state of the vector after the conversion. In order to find out, you will have to dig through the source code for the constructor (assuming you find the same one which the compiler decided to use for the conversion, which is not guarunteed).
|
||||||
|
|
||||||
|
Finally, we have reached quite possibly the most annoying feature (in my opinion) of the entire C++ language: modifiers. For example, take the following snippet:
|
||||||
|
|
||||||
|
```
|
||||||
|
const int func(int a, int b);
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, what does this actually do? Well, this function is returns a constant integer type. So far pretty simple. However, what about the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
int func(int a, int b) const;
|
||||||
|
```
|
||||||
|
|
||||||
|
Same thing, right? No, of course not - this is C++ we are talking about. The movement of the const over to the other side of the function _obviously_ means that it applies to the function and therefore means the following: this function is prevented from modifying global state or the state of any object which this function is a part of. Ok, so that's kind of dumb, but not too bad yet, right? Well...
|
||||||
|
|
||||||
|
```
|
||||||
|
const int func(const int a, const int b) const;
|
||||||
|
```
|
||||||
|
|
||||||
|
This is still valid C++, by the way. Now, we are pasing two constant integers (why this needs to be the case is beyond me, saying as we are passing by value), returning a constant integer and are prevented from mutating global state. Now, this all doesn't seem too bad, until you get something like this:
|
||||||
|
|
||||||
|
> _If you think C++ is not overly complicated, just what is a **protected abstract virtual base pure virtual private destructor** and when was the last time you needed one_?
|
||||||
|
>
|
||||||
|
> Tom Cargill
|
||||||
|
|
||||||
|
I thought this was just a joke. So I looked it up. No.
|
||||||
|
|
||||||
|
That is a very real name of a very real language construct in C++. Its definition contains the word _const_ at least three times. I didn't bother to write out the rest.
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
|
If you too join me in really not liking C++ (or, at least, modern C++), please see the following to assist in your initiation into the cult of C99:
|
||||||
|
|
||||||
|
- [https://stackoverflow.com/questions/4295681/evil-samples-of-subtly-broken-c-code](https://stackoverflow.com/questions/4295681/evil-samples-of-subtly-broken-c-code)
|
||||||
|
- [http://harmful.cat-v.org/software/c++/](http://harmful.cat-v.org/software/c++/)
|
||||||
|
- [http://port70.net/~nsz/16\_c++.html](http://port70.net/~nsz/16_c++.html)
|
52
content/blog/old/2021/far-right-checklist/index.md
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
---
|
||||||
|
title: "Your Handy \"Far Right\" Checklist"
|
||||||
|
date: "2021-06-07"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
So, in the year 2021, it appears that the definition of the phrase "Far Right" has been morphed from a person who is on the extreme right wing of politics and who believes in non-mainstream, fringe ideas to anybody who disagrees with or who refuses to capitulate completely to something that they disagree with. So, for you to stay ahead of the times, I've taken the time to compile together a handy list of warning signs that may mean that you are far right in 2021.
|
||||||
|
|
||||||
|
## Number 1: Liberalism
|
||||||
|
|
||||||
|
Sorry, liberals: you're actually a bunch of extremists. You see, obviously, it's a fringe idea to suggest that it's wrong to tell and entire generation of people that, just because of their race, they have no place in the world and cannot succeed without help. I mean, come on! The system is against all of you and will only keep pushing you back down. The liberals just hate all ethnicities other than their own, because they don't think that its right for us to collectivise you all together. I mean, come on! They just all have white fragility.
|
||||||
|
|
||||||
|
But, that's not the end of it. Those liberals even believe that it's wrong to claim that all white people are racist, because white people as a collective are just as wrong to collectivise as other ethnicities. Now, I think we all know that racism is bad, but when its directed at white people, it's allright because they were the ones in the past who owned slaves and who benefited from racism. So, the liberals are all just a bunch or racists when they want us to stop what we are doing.
|
||||||
|
|
||||||
|
## Number 2: Scientists
|
||||||
|
|
||||||
|
But wait: I don't mean the good kind like Dr. Fauci or those guys over in the WIV - they are the good kind who promote social justice and prove that we are objectively correct! I mean the bad kind who consider new ideas (even racist, evil ones!) and actually take them seriously. I mean, are you seriously going to listen to racist, transphobe, bigot, far-right, conspiracy theorist idiots? I don't think so. Scientists should have a duty to censor and ignore ideas that suggest racism or transphobia as much as they can! After all, science is all about progress.
|
||||||
|
|
||||||
|
Also, the fact that scientists claim to be able to discover objective reality is highly offensive and clearly only something a far-right believer would say, as reality is whatever you percieve it to be, because that's your identity.
|
||||||
|
|
||||||
|
## Number 3: Humanists
|
||||||
|
|
||||||
|
Humanists say that there is no God, so they are obviously islamaphobic bigots for not accepting people's ideas. Imagine if a humanist and a Muslim were to meet! Imagine what kind of dangerous thinks they could do, like disagree or have an argument over God. This is obviously all the fault of the humanists, who are so intolerant, I think they are far right. And, get this, prominant humanists like Richard Dawkins are even suggesting that we should dare to misgender and cause violence against trans people. Clearly, humanism has gone too far and I think we should call them out for their far-rightness.
|
||||||
|
|
||||||
|
## Number 4: Christians
|
||||||
|
|
||||||
|
If I even need to tell you why all Christians are far right, you are far right too. Christianity teaches evil, bigotted things such as forgiving those who do wrong against you (clearly an allegory for exploitation in capitalism) and loving others as yourself (clearly intolerant of homosexual people, as they can only love those of the same gender as themself). Not to mention all the evil things it says about people earlier on in the book (we do not speak its name). Christians also teach of personal responsibility and resilience to pain and suffering, which just seeks to victim blame those who have disphoria and suffering every day. So, I think its safe to say that all Christians are very far right and bigots.
|
||||||
|
|
||||||
|
## Number 5: Libertarians
|
||||||
|
|
||||||
|
Oh, you thought that libertarians could get away better than liberals? Well, think again! Libertarians preach the clearly bigoted idea that government should be limited in power, which is bigoted because the government could solve all our problems if we just let it! The people who say it shouldn't are just intolerant of people who want the government to solve their problems for them, who have been victimised by the evil libertarians. The libertarians are just using their priviledge of not having provlems to say that the government shouldn't be allowed to solve anybody else's problems - which clearly makes them far right.
|
||||||
|
|
||||||
|
## Number 6: Computer programmers
|
||||||
|
|
||||||
|
Computer programmers use a number system called "binary", which enforces the artificial idea of the gender binary and causes significant disphoria to trans people. Also, computers have devices called "master and slave drives", which was clearly designed by a confederate who wanted to own slaves. I think we all really knew that computer programmers are all far-right deep down.
|
||||||
|
|
||||||
|
## Number 7: Podcasters
|
||||||
|
|
||||||
|
You see, the problem with podcasters is that they like to talk to lots of people, and that sometimes includes far-right bigots. This is clearly irresponsible and dangerous, because we can't allow these dangerous ideas to proliferate thoughout society.
|
||||||
|
|
||||||
|
## Number 8: Engineers
|
||||||
|
|
||||||
|
Over 90% of engineers are male, which means that they must be discriminating against the huge amounts of females that apply and must just want to turn their under-staffed workplaces into ethostates but for gender! I think that all engineers must be far-right after realising this. So, if you're and engineer and you're reading this, I hate you until you either become a woman or employ one.
|
||||||
|
|
||||||
|
## Number 9: George Orwell
|
||||||
|
|
||||||
|
George Orwell wrote novels which warn against us controlling people's speech, which obviously is only an idea that a far-right, offensive, evil bigot would come up with. Also, he wrote stories about his time as a police officer in colonial territories, which makes him a coloniser, a fascist and a racist. He also tried to claim that communism is just as bad a fascism and worse than capitalism, which the fact checkers said isn't true! All of this makes me think that we ought to start banning Orwell's books - or at least rewriting them to make them a bit more accurate to the real world.
|
||||||
|
|
||||||
|
## Number 10: Joseph Stalin
|
||||||
|
|
||||||
|
Joseph Stalin is probably the chief far-right bigot of the 20th century. Not only did he kill people (something only evil capitalists can do), but he also had people imprisoned for their beliefs and was obviously ableist. I think we need to re-write history to make sure that everybody knows that Joseph Stalin was so far-right.
|
After Width: | Height: | Size: 309 KiB |
BIN
content/blog/old/2021/leyendecker-appraisal/images/tf2-blue.jpeg
Normal file
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 14 KiB |
BIN
content/blog/old/2021/leyendecker-appraisal/images/tf2-red.jpeg
Normal file
After Width: | Height: | Size: 12 KiB |
50
content/blog/old/2021/leyendecker-appraisal/index.md
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
---
|
||||||
|
title: "An Appraisal of J. C Leyendecker"
|
||||||
|
date: "2021-09-25"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
J. C Leyendecker's art is what I like to call the "Art Style of the 1950s". Leyendecker's work is so stereotypically 50s in nature, in fact, that it is continually used by things, such as The Incredibles and Team Fortress 2, to imitate the dress sense and appearance of the era. But why? Why is it that Leyendecker's work is so memorable and stereotypical to its era that it is continually returned to as a reference point? Well, my answer is that its simplicity and representation of the era is its genius.
|
||||||
|
|
||||||
|
You see, Leyendecker's art is based around bold, blocky colors which are used to, nevertheless, create very detailed portraits and pieces of art. For instance, observe the following illustration:
|
||||||
|
|
||||||
|
<figure>
|
||||||
|
|
||||||
|
[![](images/leyendecker-1-1024x718.jpg)](https://www.ethanjmarshall.co.uk/wp-content/uploads/2021/09/leyendecker-1.jpg)
|
||||||
|
|
||||||
|
<figcaption>
|
||||||
|
|
||||||
|
"Arrow Collar Man" - J. C. Leyendecker - 1947
|
||||||
|
|
||||||
|
</figcaption>
|
||||||
|
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
In this image, you can see that the color of each different surface is, essentially, painted in a fashion where they are sub-divided into little blocks to show details. Then, each subsequent block is colored a different, lightly contrasting, color. However, one of the most interesting details about this image is the contrast of colors in general. The foreground and background elements are very clear in their contrast. The skin tone of the man and woman is very distinct to their shirt colors. Similarly, the color of the woon upon which they sit isn't even in the same saturated range as every other color in the image. However, at the same time, the colors are all complementing: nothing particularly stands out yet they all still contrast enough that individual elements can be picked out. There are no blues on reds or greens on blacks.
|
||||||
|
|
||||||
|
One of the best places where this can be seen is in the art style of Team Fortress 2, which heavily used this fact in order to make the game visually distinct and easy to spot important elements (meaning, of course, other players). For instance, observe the following image:
|
||||||
|
|
||||||
|
<figure>
|
||||||
|
|
||||||
|
[![](images/tf2-contrast.jpeg)](https://www.ethanjmarshall.co.uk/wp-content/uploads/2021/09/tf2-contrast.jpeg)
|
||||||
|
|
||||||
|
<figcaption>
|
||||||
|
|
||||||
|
Screenshot from Team Fortress 2 - taken 12/06/2015
|
||||||
|
|
||||||
|
</figcaption>
|
||||||
|
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
In this image, a few things are very apparent. Firstly, the player in the center of the screen is very visually distinct: you can't miss him. The soldier stands out from the background very easily, despite using the exact same color pallete and using complementing colors. Why is this? The answer is _saturation._ TF2 ensures that players will always have a much higher level of color saturation to that of the background, meaning that it is really difficult to miss where he is standing. Secondly, you can see exactly whose base you are in. TF2 uses contrasting color palletes to ensure that you can always tell where you are in a level at any time. Observe these two images:
|
||||||
|
|
||||||
|
[![](images/tf2-blue.jpeg)](https://www.ethanjmarshall.co.uk/wp-content/uploads/2021/09/tf2-blue.jpeg)
|
||||||
|
|
||||||
|
[![](images/tf2-red.jpeg)](https://www.ethanjmarshall.co.uk/wp-content/uploads/2021/09/tf2-red.jpeg)
|
||||||
|
|
||||||
|
Which team do you think occupies each part of the map? To even the minimum of pertinent observers, it is fairly obvious that the left base is occupied by blue, whereas the right goes to red. This is entirely down to Leyendecker's genius of contrast: everything was based on color. Whereas a lot of art uses other techniques to contrast things (such as positive and negative space), Leyendecker could place two different objects right next to each other (maybe even inside each other) and still have the eye naturally contrast them.
|
||||||
|
|
||||||
|
Now, I said in the outset that Leyendecker's art tends to just scream "1950s". And, I think that is very accurate. But why is this, specifically? Well, my theory is that Leyendecker's style is just an evolved version of pop art. Pop art is also well known for being based around blocky, shaded sections which are built up using contrasting colors. Just look up 50s art ([here, I've done it for you](https://duckduckgo.com/?q=1950s+art)) and you will see that this type of artistry was very popular in 50s and 60s advertising. There could be a number of reasons behind this, but, again, my theory is that it was both cheaper and more practical to reproduce this style. There was no such thing as a photocopier in the 50s and camera quality was nowhere near good enough to be used for this purpose. As such, artists attempted to use as much of the same shades as possible. This created the distinctive style that Leyendecker is known for. It is also possible that the limited color pallete that technicolor cameras (and art in general) allowed for was simply being used to the greatest effect possible while still maintaining a degree of realism.
|
||||||
|
|
||||||
|
In summary, Leyendecker's art is something that we really have lost with the advent of accurate and cheap digital cameras. And it is a shame. There is a reason that games such as Team Fortress 2 are often described as looking quite beautiful by players: because it is based on a beautiful art style: an art style which Leyendecker exemplified.
|
14
content/blog/old/2021/mlk-one-thing-wrong/index.md
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
title: "The One Thing MLK Got Wrong"
|
||||||
|
date: "2021-09-19"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
Reverend Dr. Martin Luther King Jr. is a legend in the history of the United States civil rights movement. During the late 1950s and most of the 1960s (up to his assasination), MLK campaigned for official rights for racial equality under the law and in discrimination law to be incorperated by the US government. He placed a heavy focus on _non violent_ protests and resistance, and he always condemned what he called a "vocal, numeric minority" of his group who thought that violence was the answer. His explanation of this growing voilent faction was that a "riot is the reaction of the unheard".
|
||||||
|
|
||||||
|
However, this is the _one thing_ that MLK got completely wrong, and this was likely a large part due to the fact that he never predicted that his movement would become either a borderline supremacist movement and the establishment post-millenia. In the modern day, riots are the voices of the _overheard_: those who are being heard, yet whose ideas are not being taken seriously. So, their solution is to attempt to force their way into the minds of the average man in their land. Simply being transformed from the _avont-gard_ into the establishment was not enough for them; instead, they need permanent persistence in the minds of the population. And, how did they attempt to do that? They instead turned to oppressive violence to attempt to cement themselves into the mind of the populus.
|
||||||
|
|
||||||
|
And, can I really fault them in their evil plans? - you may ask. Yes, as I believe that this is the _wrong_ way to go about creating social change - even if they were _actually_ following MLK's plan towards his dream. Their genius yet evil plot of persistence has succeeded: it is almost impossible to have a conversation about these things these days without having any of these riots or riotous movements and the mainstream establishment has ensured that they remain in relevance, even causing [complete hoaxes](https://summit.news/2021/07/16/racist-defacing-of-rashford-mural-turns-out-to-have-no-racial-connotations-whatsoever/) to make sure that this happens.
|
||||||
|
|
||||||
|
MLK was a genius and we almost made it to his dream. But, sadly, his own side has been overrun by those at complete odds with that original goal, both in his view of equality and his non-violent focus. Hopefully, one day, we can make it back on track.
|
|
@ -0,0 +1,76 @@
|
||||||
|
---
|
||||||
|
title: "\"You have nothing to fear if you have nothing to hide\""
|
||||||
|
date: "2021-02-19"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
Throughout the length of its existence, this arguments has been one of the most commonly repeated talking points (or, really, justifications) of authoritarianism and surveillance that I have ever heard. It is used so commonly, but without any push back, that I feel myself repeating the same responses to it over and over again. So, let's set the record straight and put my response down for reference.
|
||||||
|
|
||||||
|
In fact, if I am ever faced with a person who fervently believes that this argument is a legitimate argument for authoritarian surveillance, then I am just going to link them this article (hello people from the future who got here from me doing this!).
|
||||||
|
|
||||||
|
But, in any case, as hinted previously, this article will be on why I think that "You have nothing to fear if you have nothing to hide" is a stupid argument that I wish people would stop making.
|
||||||
|
|
||||||
|
## Humans are naturally protective
|
||||||
|
|
||||||
|
This argument is the main one which revolves around ethics and the human condition. However, it is also what I would consider one of the strongest ones. Humans are naturally protective of both themselves, their belongings and, most importantly, _what they do when they are alone._ Don't believe me? Well, why then do we attempt to be private while using the bathroom? Why do we not like to be watched undressing by most people?
|
||||||
|
|
||||||
|
Right off the bat, we've established that there are at least two things that we are protective of and which we wish to hide for no nefarious reason, so how far does it extend? Well, that is exactly the point: it extends to different points for different people, but I'll get on to that in a few moments. But, I can imagine that most people would be a little concerned if they were watched by the government at all times while in their house to "prevent crime". But, again, we (apparently) should have no reason to fear this and its ominously creepy nature because we have "nothing to hide".
|
||||||
|
|
||||||
|
The point being that we are naturally protective of some things. But, by the logic of this argument, we should have no problem undressing in front of a government agent by force as long as we are not hiding something in our underwear. What? You don't want to show private parts of yourself to the government for "The Greater Good"? Well, off to jail with you, you safety compromising criminal.
|
||||||
|
|
||||||
|
It is at this point that the insidious nature of this statement begins to become apparent. It can be applied to somewhat harmless things and to full scale harmful things too. For instance, if you are stopped by the police for driving strangely, you don't need to be worried as long as you haven't been drinking. But, therein lies the problem: there _are no limits_ of this kind. By the logic of the statement, privacy has no reason to exist as long as you aren't hiding something from the government - whereas, in reality, there are a lot of reasons a person may wish to hide things other than illegalities.
|
||||||
|
|
||||||
|
If we take the statement at its true value, we compromise the legitimate privacy and freedoms of the masses to catch a proportionally tiny amount of actual bad people. Yet, still, we are told that if we question the surveillance run by the state, we must have something to hide, warranting more surveillance!
|
||||||
|
|
||||||
|
At the end of the day, what I am trying to say is that we all have something to hide, because its human nature. We don't need to have a reason to want to hide it - it could simply be that incursion into that feels very creepy to us. And, for me, that is the main reason why - yes - you _do_ have something to fear, even if you have nothing to hide.
|
||||||
|
|
||||||
|
### Example application: HIV epidemic
|
||||||
|
|
||||||
|
Let's imagine that a hypothetical mutation of the HIV virus is going around causing an epidemic in the UK. For the sake of this discussion, let's also say that it can only spread through intercourse and stopped with protection.
|
||||||
|
|
||||||
|
If we live by the rule that people should have no qualms in being survived if they are not hiding something, would there be a problem with you being watched by video surveillance as you have sex by the government to ensure that you are using protection at all times? Let's take it further: would it be alright to require a physical witness to be present during all session of sexual intercourse?
|
||||||
|
|
||||||
|
**Are alarm bells going off in your head yet?**
|
||||||
|
|
||||||
|
## But surely everybody thinks the same... Right...?
|
||||||
|
|
||||||
|
This is one of the less obvious (yet no less harrowing) idiotic aspects of this argument: it assumes that everybody must feel the same way.
|
||||||
|
|
||||||
|
As I outlined earlier, this argument assumes that everybody will feel the same way about their privacy, and that, if they do not, their only possible motive would be that they are doing something wrong. This is ultimately collectivist and completely ignores that people feel very differently about their own privacy and the privacy of others around them. And, this is not one of those things that you just need to get on with as it is a part of life (quit the opposite, in fact, as outlined by the previous paragraph), this is something that every single person will have a different outward facing trait marking them. In common speech, we may refer to people with an extreme wanting of privacy and a dislike for being observed "shy" (or less commonly "introverted"). Being shy is not treated as a bad thing here, so why should being shy to being watched/observed by a person whom you do not know and cannot interact with be treated any differently? If anything, it should make us more shy to the fact, based on the fact that the thing watching us is a faceless entity which cannot be reasoned with (being yet another reason why camera mass surveillance is so creepy to me).
|
||||||
|
|
||||||
|
So, effectively, this argument is only valid if we can collectively classify every person as only having qualms about surveillance if they are hiding something illegal. Not only is this out of touch with reality, it is ultimately extremely collectivist and completely ignores the individual aspect to this issue.
|
||||||
|
|
||||||
|
## Ultimate trust in ultimate power
|
||||||
|
|
||||||
|
Although this argument is more of a general libertarian argument, it is still valid towards this case in particular.
|
||||||
|
|
||||||
|
Let's say for a moment that we all take there truly is nothing to fear if we are not hiding anything and that the constant surveillance by an all powerful government is nothing for us to worry about because we are not doing something wrong. For a moment, let's run with the idea that every single person in society has fully accepted what is going on and has no problem with it - despite what I outlined in the previous paragraphs. In this particular situation, we have a state of society where every single person is ultimately trusting of the government and the elites who run it. Effectively, there is no accountability and every person must think that what is being done is just for their own good. This is not a good situation.
|
||||||
|
|
||||||
|
A government should fear its own people, not the other way around - as the government is meant to serve the people. If the government is _not_ serving the people in a way which they like, it should be very afraid of what they will do. However, in this situation, nobody questions the surveillance because its for "their own good". Surely it's not possible at all that power will be misused, wrongful accusations or other negative consequences will happen, right...? No accountability will be afforded to those in power and the system goes on, unchallenged, for the rest of time.
|
||||||
|
|
||||||
|
Doesn't sound like a particularly good situation to me. Speaking of governmental fear, that leads me perfectly on to...
|
||||||
|
|
||||||
|
## Great! A society based around fear!
|
||||||
|
|
||||||
|
The crooks of this argument boils down to the fact that us having nothing to fear is conditional - that we can have our safety taken away at any moment. Instead of meaning to work on and improve yourself, you are instead made to fear your overlords who can take away your state of safety at any moment.
|
||||||
|
|
||||||
|
So, this statement instils a vague sense of fear into the back of all our minds. Sure, you might have done nothing wrong. But what if you have? Well, _they will_ know and you _are not_ safe. There is no middle ground here: you either have done something wrong and need to go into full blown fear; or you have not and you are perfectly safe. This doesn't sound like the kind of society I want to live under.
|
||||||
|
|
||||||
|
## Welcome to the self-preservation society!
|
||||||
|
|
||||||
|
Yes, that was a reference to The Italian Job.
|
||||||
|
|
||||||
|
In a society where every action you make is one that can be used against you to get you into trouble and to catch you out for something, the only logical reaction would be self-preservation. Your previous freedoms would be completely gone, as the only thing in your mind when doing most things would be "could I get into trouble for this?". The classic example for this is that a young driver stops off in the bar each Sunday night. He stops there to get some food, but never buys a drink and then proceeds to walk home. A few weeks later he applies for a driving licence. In a society where his every move is tracked and monitored, he may begin to worry what the DMV thinks about him entering a bar habitually and how it may hurt his chances for a drivers licence. It doesn't matter what he was doing in the bar - he was in an institution where alcohol is. So, from then on, he never does what he actually wants to because of how the surveying overlords may see it. In our current society, however, the DMV couldn't care less where you like to eat every Sunday evening, so no such thoughts enter your head.
|
||||||
|
|
||||||
|
This goes to the core of why liberty is so important: we all want it in some form or another, but once its gone in one area, we all want it back. We naturally want to be free to do certain things, and liberty-focused arguments do not try to deny this specific part of human nature. In a surveillance-based society, however, we are asked to deny our feelings and exchange them for our increased "safety and security".
|
||||||
|
|
||||||
|
## Let's sum up
|
||||||
|
|
||||||
|
So, to sum up: this is a bad argument that has been done to death by every authoritarian throughout history. It makes little sense once examined, but has fooled too many people throughout the course of its existence. So, the next time you hear it, please don't allow it to fool you too.
|
||||||
|
|
||||||
|
I'll just leave you with the legendary quote from Jacob Appelbaum, which, if you still weren't convinced, I would hope will push you over the edge:
|
||||||
|
|
||||||
|
> There is the inherently selfish response of ‘I have nothing to hide’. Well it is true that I am not ill. It is true that I am not blind. But I still want to live in a world that has hospitals. I still want to live on a street that has accessibility for blind people. And it is also the case that I want to live in a world where everyone has privacy, thus dignity, confidentiality and integrity in their daily lives, without having to ask for it.
|
||||||
|
>
|
||||||
|
> Jacob Appelbaum on privacy and dignity
|
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
title: "C vs Go: Opinionated Design in Programming Languages"
|
||||||
|
date: "2021-08-10"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
The C programming language and the Go programming languages are my all-time favorite tools for programming. Full stop. These two languages are so versatile, so extensible and so incredibly useful that I have yet to come across a problem in which neither of the two is appropriate for use. And yet, these two languages are, evidently from even the slightest bit of use, radically different in their approaches to programming language design. Having sat down and had a serious think about the subject, I have finally come to a conclusion about what this fundamental difference is.
|
||||||
|
|
||||||
|
You see, C is designed with what I call "Design Indifference". Effectively, the philosophy of the language is that the language will have no opinion on how the user organises their code. It shall not enforce any rules on how code ought to be written, nor shal it restrict the user from using certain features of the machine because the author thought that that feature is not safe or necessary for well written programs. Whatever is technically possible, C shall allow you to do.
|
||||||
|
|
||||||
|
Go, however, is a very _opinionated_ language. Essentially, the designers of Go (possibly the most prominent of which is Rob Pike) had strong opinions on what should and should not be present in the language. In a [2015 talk](https://www.youtube.com/watch?v=rFejpH_tAHM), Rob Pike said that he and the rest of the Go designers would all have to unanimously agree on the inclusion of a feature into the language before it would be added. This made the Go language substantially higher level than the C language, but also very minimal. However, this also is where the opinionated nature of Go's design comes from. The opinions of all these people were taken into account, not just what the machine is capable of doing being allowed.
|
||||||
|
|
||||||
|
There is no more a perfect example of this than Go pointer arithmetic. It is stated very clearly in The Go Programming Language (2015) that Go intentionally does not include pointer arithmetic, being a feature which is purposefully absent when compared to C. In C, it is recognised that a pointer is simply an integer like anything else stored in registers, and therefore can be manipulated like anything else. This means that C will, like it does with anything else, allow you to do arithmetic on it. What you use this for is your decision. You can use it as a more convenient (and efficient) way of getting a pointer to an array element. You can (technically, although I really don't recommend this) use it to get at adjacent elements in structs). The point being, the language doesn't care about why you may wish to do this: it is possible for the machine to do, and so you can do it. Go, however, does not have this attitude. Instead, if the designers of the Go language see no reason for you to do something, you can't do it. Simple as.
|
||||||
|
|
||||||
|
Another good example is variable naming schemes. There is no way to export a variable or function from a package in Go without making the naming of said exported symbol upper-case. The upper-case nature of this symbol is what denotes it as exported. The Go designers do not care that some people may wish to write this another way and export it manually. This is the way Go is invisioned - deal with it.
|
||||||
|
|
||||||
|
Now, I do not have a particular preference either way as to which design is better or worse. I have written fairly important C applications and written some rather important Go applications. Both of these sets of projects use the languages to their fullest extent as needed. Both of these were joys to write.
|
||||||
|
|
||||||
|
At the end of the day, there is nothing wrong with writing an opinionated programming language, so long as you have good justification for your opinion on code and software development - and so long as people can widely accept this opinion and work well with it. And there is similarly nothing wrong with creating a programming language which is just a simple tool which does as you say. Some people won't like Go because of its opinion on these matters. Others, like myself, may share this opinion. And, other may just take on this opinion because they trust in the genius of Rob Pike and Ken Thompson. But either way, C and Go are very good examples of near-perfect executions of both models.
|
52
content/blog/old/2021/scott-joplin-genius/index.md
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
---
|
||||||
|
title: "Scott Joplin was a Genius"
|
||||||
|
date: "2021-09-22"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
![Maple Leaf Rag](mlr.jpg)
|
||||||
|
|
||||||
|
It is very rare in the world of music that you come across something which you believe to be totally perfect. A piece which is so wonderfully intricate and yet to perfectly easy to listen to that you daren't change a single note, as that may upset the balance and ruin it. At least, for me, it was particularly rare until I re-discovered the undisputed king of ragtime: Scott Joplin.
|
||||||
|
|
||||||
|
Scott Joplin's music is not only iconic, but it has lasted hundreds of years. The Maple Leaf Rag (one of his more famous pieces) was first published in 1899, and yet it is still one of the best known pieces of ragtime ever written.
|
||||||
|
|
||||||
|
## On The Maple Leaf Rag
|
||||||
|
|
||||||
|
The Maple Leaf rag is a perfect example of, not only Joplin's genius, but of the effect I described above. If I were tasked with improving the Maple Leaf Rag, I would likely change very little, if anything at all. When you listen to (or watch somebody play) this piece, you are easily overwhelmed by all the pieces fitting together to create a sound which is unique and yet still stereotypically ragtime.
|
||||||
|
|
||||||
|
The melody of the piece is so wonderfully unique that it took me a few tries before I fully understood it. The bass and the treble both provide part of the overall melody through interlocking notes between the two parts. However, when played separately, the individual melodies which emerge still both make sense and sound great. I cannot even begin to understand how another human being came up with every single note which is a part of some of the sections of this piece. For instance, take [this section](https://youtu.be/sE86FR2SzBo?t=40). It causes my mind to slightly implode thinking about the fact that somebody had to actually come up with the notes that go behind this sound and make it the way that it is. Each individual note is just perfect in an indescribable fashion which only serves to increase the sense of intricacy.
|
||||||
|
|
||||||
|
This rag is quite possibly my favorite. Sure, it is complicated (and I have carpal-tunnel and a sprained wrist by the time I have finished playing it), but that is part of what makes it brilliant. It _is_ complicated, but incredibly easy to listen to.
|
||||||
|
|
||||||
|
## On The Entertainer
|
||||||
|
|
||||||
|
Probably the most famous out of Joplin's many works is the Entertainer. Often known as the "silver screen's soundtrack", this piece is known to be associated with the wild west and, in particular, bar fights.
|
||||||
|
|
||||||
|
This piece is in a similar yet infinitely different boat to the Maple Leaf Rag in that it is _actually_ simple and quite easy to play. Its structure is mainly based around repeats and small variations on the same pattern. It doesn't sound right when played too quickly, which makes the tempo easy to manage, and it has very few advanced musical features to it. Joplin was not lying when he described it as "easy to play".
|
||||||
|
|
||||||
|
As a pianist, I would consider this one of the best songs to have in your back pocket if you are ever in need of one to whip out and play at a moment's notice. It is easy to play, easy to remember, but (most importantly) easy to recognise.
|
||||||
|
|
||||||
|
## On The Magnetic Rag
|
||||||
|
|
||||||
|
If I remember rightly, this was Joplin's last rag, owing to the fact that he died of Syphilis not so long after and was forgetting all his music. With the assistance of others, the fractured remainants of songs he was writing were stuck together (hence the "magnetic" in the title) and released under that name.
|
||||||
|
|
||||||
|
And yet, it still sounds perfect. I think, due to the habbit that Joplin had of including very contrasting different sections in all his songs, this song simply sounds as natural as all the others. What is there more to say? Joplin managed to scavenge a load of his own songs together, sewed them together Frankenstein style and ended up with a wonderful creature, rather than a hideous monster.
|
||||||
|
|
||||||
|
The Magnetic Rag is the kind of song that transports you back to mid-to-late 18th century stately homes, with their rich inhabitants and easy music playing in each room from the echo of the piano. The song is so expressive that it almost takes me there on each listening.
|
||||||
|
|
||||||
|
## On Music Philosophy
|
||||||
|
|
||||||
|
Joplin is well known to have written "**Do not** play this piece fast. It is never right to play ragtime fast" on all his sold sheet music. I agree.
|
||||||
|
|
||||||
|
I think that pieces of music which are played back overly fast are simply hiding their lack of detail and development. Songs which are overly simplistic are not always a bad thing, but they cannot simply attempt to hide this by speeding up the playing and making the impressive feat of the music not the talent that went into writing it, but instead the pianist's ability to not break their fingers while playing it back.
|
||||||
|
|
||||||
|
When music is sped up, we loose a certain lag time which we can use to process the sound which just entered our ear and appreciate all the small details. When the Maple Leaf Rag was played back slower, I heard so many more details about the song that I had never heard before.
|
||||||
|
|
||||||
|
Joplin was right. Music which is played back fast (and only fast) is not fit for purpose. Music's beauty should be in its design, not in the speed of its playback. If a song only sounds right when played exessively fast, it is not a song. It is noise.
|
||||||
|
|
||||||
|
## In Conclusion
|
||||||
|
|
||||||
|
How much more is there to say? You have likely heard at least two Joplin songs in the course of your life, and may you hear many more in the future. If you get the change, try to learn some! Joplin's music is often the gateway drug into piano and are a very fun way of making your reaction times shorter (especially try songs such as Elite Syncopations for that end).
|
||||||
|
|
||||||
|
So, I can be wholly confident when I say that **Scott Joplin was a genius.**
|
BIN
content/blog/old/2021/scott-joplin-genius/mlr.jpg
Normal file
After Width: | Height: | Size: 127 KiB |
142
content/blog/old/2021/totally-reliable-software/index.md
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
---
|
||||||
|
title: "Is software with zero errors possible?"
|
||||||
|
date: "2021-11-27"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
Could it ever be possible to create sofware with zero errors? Software which is so perfect that it is not possible for it to ever do something unexpected, undefined or contain any errata of any kind? To answer this question, let's take one of the most simple programs physically possible: hello world. For the moment, I will be writing in very generic pseudocode, for reasons which will become clear in due course. Here is an example of "hello, world" written in my flavour of pseudocode:
|
||||||
|
|
||||||
|
```
|
||||||
|
OUTPUT "hello, world"
|
||||||
|
```
|
||||||
|
|
||||||
|
In this example, the computer isn't doing any real computation, however, so let's improve this slightly to suit our needs. We will be using a program which accepts two inputs from arbitrary sources and outputs (through an arbitrary channel) their sum. Pseudocode reads as follows:
|
||||||
|
|
||||||
|
```
|
||||||
|
INPUT a
|
||||||
|
INPUT b
|
||||||
|
|
||||||
|
c <- a + b
|
||||||
|
OUTPUT c
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, let's imagine the scenario: you are running on a computer which is solely dedicated to executing your code. For the sake of simplicity, we will assume that the computer will have a constant and uninterrupted power supply. Now, can we guarantee that this code will be error free? Where in this code could an error occur.
|
||||||
|
|
||||||
|
Well, first, let us examine the language itself which the code is written in. On creating the variable "c", we have implicitly allocated some kind of memory. If we assume that this variable is allocated on the stack, it is very possible for a stack overflow or out-of-memory scenario to ruin our plans. Typically, memory is allocated on the stack by subtracting a value from the base pointer (the stack is usually in high memory) and placing the result in the stack pointer, so future allocations will occur after the un-use block of memory. This is fine, but does lead to it being very difficult to catch when our stack over-grows its bounds. For instance, what would happen if we subtract enough space from the stack pointer to run into our program code. On x86, you will crash with a segmentation protection violation (attempted to write to RX only memory). So, using the stack is out of the question, right? Well, in theory, we could insert a check before the allocation of each stack frame to detect and overflow (compare our memory map to the current base pointer before setting the stack pointer), but what we will do when this fails is quite a problem. It's not like we can just erase stack frames, after all. It seems more likely that the heap will do. Now, the question of the language is particularly relevant. In garbage-collected, escape-analysed languages (such as Go and Python), it is impossible to use the heap without an implicit call to code we do not control. This tends to lend itself to serious problems with reliability if our goal is to literally never crash. Go's memory allocator, for instance, will instantly abort program execution on failed memory allocation. Python will do something similar. So, garbage collected languages are out of the question - we will have to manage the heap ourselves. That means going back to C.
|
||||||
|
|
||||||
|
The question that may have popped into your mind is "Why not C++ Ethan?". Leaving aside C++'s obvious flaws in other areas, it is completely unfit for both low-level and high-reliability software. Unhandled exceptions can come from anywhere, and the C++ method of doing things tends to revolve around abstractions at the language level, which is never good if we need to cover all our bases. Think about it: the C++ runtime, according to the language standard, has the right to abort your program at any time it sees fit. It is much safer to just write in C.
|
||||||
|
|
||||||
|
Ok, so our code currently looks something like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
int callback(int in0, int in1)
|
||||||
|
{
|
||||||
|
int *res = malloc(sizeof(int));
|
||||||
|
*res = in0 + in1;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Whoops! We just invoked undefined behaviour! In this instance, we have not checked the return value of malloc. Malloc reserves the right to return a NULL pointer. So, in dereferencing it without checking, we have just potentially caused a segmentation violation and a crash. Let's fix it:
|
||||||
|
|
||||||
|
```
|
||||||
|
int callback(int in0, int in1)
|
||||||
|
{
|
||||||
|
int *res = malloc(sizeof(int));
|
||||||
|
if (!res) {
|
||||||
|
// But what now?
|
||||||
|
}
|
||||||
|
|
||||||
|
*res = in0 + in1;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
What now indeed? Well, we have reached a similar problem to with stacks, but with a twist: as the heap is a nonlinear data structure, it can be freed and allocated in a non-defined order. So, we could run some kind of cleanup function here which cleans out any memory we don't absolutely need. Let's program that in then.
|
||||||
|
|
||||||
|
```
|
||||||
|
int callback(int in0, int in1)
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
int *res = malloc(sizeof(int));
|
||||||
|
} while (!res);
|
||||||
|
|
||||||
|
*res = in0 + in1;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If I were to actually need to do this, I would write a wrapper function to do this (maybe called smalloc, for "safe malloc"). I haven't called a cleanup function here for simplicity, but it would be easy to add. The problem still remains, however, that it is not for certain that we will actually ever get any freed heap memory and may still be stuck in this loop forever blocking. Not good. Another minor problem being that the pointer we just recieved may well be stored on the stack _again_. We have just made the problem a whole lot more complicated and slow. And it could block forever. And it could just abort our program due to heap corruption. On the whole, it may be safer to simply use the CPU's registers. There is no direct way to do this in C, but there are compiler flags which force it to pay attention to "register" declarations, throwing an error if you ask it to do something impossible. Let's program it in:
|
||||||
|
|
||||||
|
```
|
||||||
|
int callback(int in0, int in1)
|
||||||
|
{
|
||||||
|
register int res;
|
||||||
|
res = in0 + in1;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Okay, so we now have a completely safe callback, right? No, of course not. Integers in computing are not as they are in mathematics. They are limited to two to the power of the sizeof the integer. In this case, two to the power of 32 (4294967296). However, we have not specified that the integers are unsigned, so the actual space to store the integer is 31 bits, meaning the maximum is, in fact, two to the power of 31 (2147483648) - which is signiricantly smaller. How can we guard against this without overflowing our integer? We could rely on the calling code, or we could implement a simple check here. Let's think about our design requirements:
|
||||||
|
|
||||||
|
- We must never return more than 2^31
|
||||||
|
- We must never handle any value larger than that size, lest we cause an overflow
|
||||||
|
- Inputs may be up to this size or down to this negative size
|
||||||
|
|
||||||
|
It is clear that we can't juts add the numbers and see if it is over a maximum. What can we do? Well, we know the maximum, and we know both inputs. So, logically, if we subtract one of the operands from the maximum, the result must be larger than or equal to our other operand - otherwise, we have detected an overflow. However, there is a big problem here: what if the first operand we subtract is larger in size than the maximum? Well, this is not possible, as it would simply not fit in the integer which was passed. Let's implement it. While we're at it, let's fix the minor problem that we are not returning any value.
|
||||||
|
|
||||||
|
```
|
||||||
|
int callback(int in0, int in1)
|
||||||
|
{
|
||||||
|
register int res;
|
||||||
|
|
||||||
|
/* assumes presence of limits.h */
|
||||||
|
if (INT_MAX - in0 < in1) {
|
||||||
|
/* overflow detected */
|
||||||
|
return INT_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = in0 + in1;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Two small problems still remain. Primarily, what happens if in0 is negative? Big problem, as subtracting a negative simply adds. This could overflow our calculation to the extent of being completely incorrect. Let's check for this case specifically and amend our algorithm:
|
||||||
|
|
||||||
|
```
|
||||||
|
int callback(int in0, int in1)
|
||||||
|
{
|
||||||
|
register int res;
|
||||||
|
|
||||||
|
/* assumes presence of limits.h */
|
||||||
|
if ((in0 >= 0) && INT_MAX - in0 < in1) {
|
||||||
|
/* overflow detected */
|
||||||
|
return INT_MAX;
|
||||||
|
} else ((in0 < 0) && INT_MIN - in0 < in1) {
|
||||||
|
/* underflow detected */
|
||||||
|
return INT_MIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = in0 + in1;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
We have thus prevented an overflow in both directions, and we have introduced exactly zero ourselves (unless the compiler sucks and feeds us false information, but that is unlikely).
|
||||||
|
|
||||||
|
So, have we finally managed to add two numbers together without the possibility of error? Kind of. You see, in all of our efforts to guard against over or underflows, we have simply replaced one kind of errata with another, more defined version. According to this function, 2^31 + 1 = 2^31. That is simply not true, and breaks the entirety of mathematics. But, I find it better than the technically undefined behaviour of overflows. It is better to clamp the value than obtain a completely nonsensical version. However, a greater problem is the concept of hardware errors. What happens if we have a memory parity error, a bit flips in a register due to cosmic radiation, or some other kind of completely random behaviour? There is nothing we can do about this, right? Well, let's take the case of cosmic radiation for one moment: we can guard against this by shielding the computer in lead lining. Memory parity errors are rare and can be avoided by memory testing at program startup. If we really cared about this, we could test the memory on bootup for errors and bad wiring, aborting if we find issues (or create a memory map of where we can't use, but that isn't an issue in this case).
|
||||||
|
|
||||||
|
However, we have established so far that, even if we have a computer shielded in lead, using only registers and low level programming which has a dedicated power plant to supply it power, we _still_ can't do everything right - and there is a lesson here. Computers are flawed machines. They cannot exist in the same space as human beings can in our minds, where numbers are unlimited in size, space can just be conjured out of nowhere and things can only happen if we explicitly tell it to. There are an infinite number of ways in which things can go wrong. In the original UNIX, Ken Thompson famously ridiculed the developer of SunOS for including so much error handling code, instead remarking:
|
||||||
|
|
||||||
|
> Yeah, we threw all that out. Instead we have this one function called "panic" that just crashes the machine and gives out a stack trace. Saves a lot of time.
|
||||||
|
>
|
||||||
|
> Ken Thompson
|
||||||
|
|
||||||
|
Today, most major kernels _still_ use this phillosophy of error handling for certain errors. The Linux and BSD kernels followed the UNIX tradition of "panicking" when something bad happens. The Windows developers, ever corporate, decided that it should be instead renamed to a "DebugCheck callback". These routines are all identical. They all crash your machine instantly and irreversibly until reboot. You have likely seen one of them in the form of the Blue Screen of Death (BSOD).
|
||||||
|
|
||||||
|
The moral here is that it is futile to attempt to eliminate 100% of the errors that could occur in your code. If this is your goal, programming is not going to be kind to you. Instead, aim to eliminate errors which occur overly frequently and which have well-defined and practical solutions. Only using registers may be possible on x86 (where you have an enormous amount of them available), but it isn't _real_ programming. And, in theory, you _could_ detect cosmic radiation ruining your calculations by doing the same calculation on three different CPU cores and repeating until all three agree, but it isn't really practical. Has anybody ever really written code this way? Well, NASA has some [interesting insights](https://altbulletin.com/how-to-code-like-the-top-programmers-at-nasa-10-critical-rules/) about how you ought to use C99 to make it as reliable as possible when running on a spacecraft in the middle of deep space. The original NASA guidance computer was written in pure assembly and was designed to never do anything unexpected. For context, this was a computer that had to map the floor of a celestial body with radar (and detect failure to do so), navigate between a planet and its moon using complex physics, and monitor and issue commands to the spacecraft and pilot - and do all of this with 1960s integer math technology. Oh yeah, and it had to operate a control system that the astronauts could interface with through a keypad. No standard library. No heap. No calling conventions, code testing or tooling- nothing except mathematical models of how to test code and a bunch of monospaced punch cards and paper. If they could do it up to what was needed, we can too. In the modern day, if your code has any glaring errors in it which are not completely out of your control, it _must_ be fixed. Probably the one place where I disagree with the UNIX phillosophy is that incorrect results must never be allowed - within reason. I think it is fine to return incorrect results if what the user is asking for is outlandish or would just result in tedious and slow error handling code. Apart from extreme circumstances, however, incorrect results are simply unacceptable and must be rooted out and fixed.
|
||||||
|
|
||||||
|
So, to answer the question in the title, no, it is probably never possible - but we can get pretty close, and that should be our aim.
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
|
_This article was sparked by the computer lab Windows workstation I was on crashing three times in a row while I was working the other day. I have used Linux computers for many years now. They have crashed probably around three times in that entire time - and I never lost data._
|
59
content/blog/old/2021/year-of-newspeak/index.md
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
---
|
||||||
|
title: "2020: The Year of Newspeak"
|
||||||
|
date: "2021-02-19"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
Anybody vaguely familiar with Orwell's famous novel "1984" will also be familiar to a similar degree with the term "Newspeak".
|
||||||
|
|
||||||
|
In 1984, Orwell describes how language was taken over, redefined and recreated to an extent where certain ideas which challenge the ideas of the party are not able to be communicated. In the year 2020, we have started to reach a point of language redefinition which I don't think I have ever seen before.
|
||||||
|
|
||||||
|
Now, I know, I know - this seems like a big overreaction; what could have happened in this year which is on the levels of Orwell's Newspeak? Well, let me enlighten...
|
||||||
|
|
||||||
|
## Social distancing? Or just staying apart?
|
||||||
|
|
||||||
|
It seems like, this year, our language has changed. It has changed in a very strange way.
|
||||||
|
|
||||||
|
In this year, our language seems to have been redefined and replaced with new terms that the average person cannot stop using. I have noticed this kind of effect in certain internet sub-communities too: a notable example being Reddit. The average Reddit user seems to be obsessed with restating the same phrases on a regular basis, to the point where it becomes simply a part of their vocabulary. This gets to such a point where this person may begin to actually use these terms compulsively in their actual conversations too. I can guarantee that you have noticed this before. For example, here are just a few of the terms that seem to be used inexplicably often:
|
||||||
|
|
||||||
|
- Original Poster (OP)
|
||||||
|
- Clarification
|
||||||
|
- Delivery
|
||||||
|
- Topic at hand
|
||||||
|
|
||||||
|
On asking people why these terms are used so often, the reply is often simply "It's just forum culture!". _This is what I am worried about._
|
||||||
|
|
||||||
|
This year, instead of an (arguably coerced) mutation of our language occurring as part of a localized subculture on an internet forum, it seems as though the entire nation has taken on this mutation of language. And it is really strange.
|
||||||
|
|
||||||
|
> You must practice to social distancing
|
||||||
|
>
|
||||||
|
> **TRANSLATION:** You can't see other people and stay at home
|
||||||
|
|
||||||
|
Whereas, on Reddit, we have the above little terms, in the wider world right now, we seem to have the following:
|
||||||
|
|
||||||
|
- Adhere to social distancing guidelines
|
||||||
|
- Wear a face covering
|
||||||
|
- Protect our National Health Service
|
||||||
|
- Designated key workers
|
||||||
|
- The Coronavirus global pandemic
|
||||||
|
|
||||||
|
This whole situation reminds me of how children that went through the British school system in the early 2000-2010s were conditioned by teachers to call the school projector systems the "Interactive whiteboard system". I know that this was the case _because I was one of those children._ The root cause behind this kind of vocabulary mutation was the constant repetition of these specific phrases by those in higher positions in the school - AKA: the teaching staff.
|
||||||
|
|
||||||
|
This constant repetition and subsequent embedding of language into children's brains acted like a script being carved into our skulls. It was as though a rehearsed performance was being played through us every time an object or idea was referred to.
|
||||||
|
|
||||||
|
**Sound familiar?**
|
||||||
|
|
||||||
|
> We are adapting our stores to protect your from the Coronavirus global pandemic in accordance with government social distancing guidelines
|
||||||
|
>
|
||||||
|
> **TRANSLATION:** We added more floor markings and made the tills wider
|
||||||
|
|
||||||
|
This has gotten to the point where I will walk down the street and can almost guarantee that I will hear the words "practice social distancing" or "adhere to guidelines" at least three to five times. That's not normal, but it is becoming...
|
||||||
|
|
||||||
|
## Normalisation through repetition
|
||||||
|
|
||||||
|
I have a theory that the end goal of all of this mutation of language is to create an aura of normality around the incredibly extraordinary events that are occurring. This year (and the one before it) have been marked by us giving up our dignity and our liberty for safety and because the "government told us so". If you had informed me of the events to come this year and after three years ago, I would have told you to go and put on your tin foil hat with the InfoWars crowd. Now, however, it is accepted as though it were always here.
|
||||||
|
|
||||||
|
Lockdowns are not normal life, social distancing is not natural human behaviour, we have not always worn masks at all times and we have not always been at war with East Asia.
|
||||||
|
|
||||||
|
2020-2021 will be marked (at least by me) as the years where those in power tried to redefine "outside" as "dangerous", "meeting" as "irresponsible" and "socialising" as "luxury". This year is not normal (new normal or old) and it will never be normal. So please, don't be convinced that we are living in normal times. We are not. We are living in very abnormal times and things are not likely to get better fast unless we, collectively, do something about it.
|
24
content/blog/old/2022/broken-linguistics/index.md
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
---
|
||||||
|
title: "Language Teaching is Fundamentally Broken"
|
||||||
|
date: "2022-03-16"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
I have been in formal language education for a total of four years now, learning Spanish for Brittish GCSEs, and this has led me to the unfortunate conclusion that language teaching and learning has been fundamentally broken by the modern day. This links in to an overall theme that the Brittish GCSE system is fundamentally broken, but that is a topic for a later date. In this instance, I would like to focus specifically on the twisted mess that has become of the holy mantle of passing language through the generations.
|
||||||
|
|
||||||
|
The job of a language teacher is to give students natural and intuitive access to a completely new tool of expression, and - just like any other tool - the core of learning how to use it is learning the core of how it functions. This is at the very heart of how we ought to be teaching languages. A language is a formal system of rules above anything else. The specific vocabulary are simply auxillary tools of expression. The core of the language - including its core grammatical structures, generic tools of expression (words for "this", "it", "that", etc.) and its general style are the absolute essentials. Common words which are used in every other sentence should be the top priority for the learner. This is how I started out. I wanted to learn structures and words which had the widest possible application. Words such as "how", "place", "way" and "what". Words such as "I am", "I go", "I think", "I have". These words are generic parts of most languages. However, in many (arguably most) courses and schools, these parts of the language seem to take a back seat. Rather than learning these core features of expression, students are instead expected to memorize vast banks of vocabulary. What is the use of knowing for the word for an airport if you cannot understand the bulk of any sentence referring to the airport? The goal of any linguist should be to be conversational and expressive in the language without having memorized immense amounts of vocabulary. This suggests that you truly understand the underlying language and its function.
|
||||||
|
|
||||||
|
Now, does language learning, especially in modern schooling, achieve this ends? Absolutely not. Not only does the classic "drill this into your skull" mentality seem to be preserved constantly, the absolute inaplicability of some of the content that I was expected to learn is just staggering. Among other highly useful phrases, I was expected to learn:
|
||||||
|
|
||||||
|
- "It produces a strong physical dependency" - "Produca una física dependencía fuerte"
|
||||||
|
- "I am concerned about the economic crisis" - "Estoy preocupado de la crisis economica"
|
||||||
|
- "The greatest problem in my area is the prevalance of joints being smoked" (my personal favorite) - "La problema más grande en mi zona es las cuentas de porros que se fuman"
|
||||||
|
|
||||||
|
Applicable? Teach the core of the language? No! This is nothing but intentional word salad which is designed to just pass an exam. This is an emerging pattern in Brittish secondary education, given that the entirety of schooling at this stage is defined by exams which take place across two weeks in our summer term. All of this time is simply dedicated to what will be written on a paper by some arbitrary organisation which doesn't care about us and which doesn't represent the real world. Because some beurocrat working for the Associated Qualifications Board (or whatever they're supposed to be called) decided that the Spanish have a drug problem, now I have to spend over three weeks writing sample sentences (don't forget to include your four tenses, even when it makes no sense!) about how I used to smoke fictional joints (porros) behind the fictional bikeshed (cobertizo de bici) with my fictional primary school friends (amigos de mi escuela primaria). Because some different beurocrat decided that the words that the Spanish use extremely often are way too easy to learn, instead we have to learn over-complicated replacements for these words that are rarely used in spoken Spanish. How do I know? Because I, unlike the beurocrats, actually learnt through experience. I was taught by a Spanish woman in my primary school on how she spoke the language in practice. I listened to how native speakers in the Canaries spoke their language and what types of language was used, and you can be damn sure it wasn't predecated on using "tengo la intención de" instead of "quero" or "tengo ganas". We are constantly being reminded that we are learning this because the "examiner will do this" or the "exam will contain that", rather than "the Spanish like to say this" or "native speakers would do that". In other words, modern language learning has fallen down the same trap as most GCSE subjects: we are taught to pass an exam, not to go into the real world. I have wasted four years of my life just so I can be slightly more qualified to fill in a piece of paper so that an underpaid teacher half way across the country can mark it in five minutes and so that AQA can make more profits through remarking.
|
||||||
|
|
||||||
|
Just for context, I can translate pretty much every word in this article into Spanish with only marginal difficulty (as I write this realising that I do not know the word for marginal). I am not inexperienced in this language. What I am inexperienced at is the AQA game. I am inexperienced at knowing the hyper-specific sets of overly specific vocabulary that whoever writes my exam felt like including this year. I'm half convinced that GCSE languages courses are designed partly do drive up the youth suicide rate so that some billionare like Bill Gates can achieve his world depopulation goals. In any case, this exam will be the bane of many children's lives, just as it is for me. I am never going to need to talk about "economic consequences of drug addiction" in Spanish ever again. I am never going to need to explain using four tenses at once how my summer holiday was (because the exam markers apparently wet themselves whenever they see somebody who bothered to learn grammar rather than the sixty words they gave us).
|
||||||
|
|
||||||
|
The solution? Michel Thomas. He understood how languages worked because he was a polygot. He understood the core of how humans communicate and how our langauges were formed naturally. Not by a beurocrat or an office worker. Not by a scientist or a designer. They were designed by humans speaking and communicating the way that humans like to speak and communicate.
|
||||||
|
|
||||||
|
But, of course, that doesn't look good on a grade spreadsheet. So AQA ignores it. Instead, we turn back to our list of four tenses we have to unnaturally cram into a piece of writing and looking up synonyms for perfectly good words like "además". I'm sure Michel would be proud.
|
BIN
content/blog/old/2022/email-paranoia/images/Hillarious-Spam.png
Normal file
After Width: | Height: | Size: 8.9 KiB |
BIN
content/blog/old/2022/email-paranoia/images/hillarious-email.png
Normal file
After Width: | Height: | Size: 329 KiB |
BIN
content/blog/old/2022/email-paranoia/images/more-spam.png
Normal file
After Width: | Height: | Size: 160 KiB |
78
content/blog/old/2022/email-paranoia/index.md
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
---
|
||||||
|
title: "Public Emails for Paranoid UNIX Users"
|
||||||
|
date: "2022-03-13"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
I have been dealing with spam on my public email address for quite some time now, and it finally got to the peak of my patience with the the following email, sent to my email not so long ago:
|
||||||
|
|
||||||
|
[![](images/hillarious-email-1024x563.png)](https://www.ethanjmarshall.co.uk/wp-content/uploads/2022/03/hillarious-email.png)
|
||||||
|
|
||||||
|
I mean, not the most convincing fake in the world, but it did give me a good laugh. And, for quite a long time, I was perfectly willing to leave my public email out there so that these hillarious messages of spam could get through to me, as I don't use any filter other than explicitly banned addresses. Among other very funny spam messages, here are the two runner ups of best spam emails:
|
||||||
|
|
||||||
|
<figure>
|
||||||
|
|
||||||
|
<figure>
|
||||||
|
|
||||||
|
[![](images/more-spam-1019x1024.png)](https://www.ethanjmarshall.co.uk/wp-content/uploads/2022/03/more-spam.png)
|
||||||
|
|
||||||
|
<figcaption>
|
||||||
|
|
||||||
|
Great email from a Spanish prince this time?
|
||||||
|
|
||||||
|
</figcaption>
|
||||||
|
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
<figure>
|
||||||
|
|
||||||
|
[![](images/Hillarious-Spam.png)](https://www.ethanjmarshall.co.uk/wp-content/uploads/2022/03/Hillarious-Spam.png)
|
||||||
|
|
||||||
|
<figcaption>
|
||||||
|
|
||||||
|
Nice try from The Bee - but I'm neither American nor a taxpayer (yet)
|
||||||
|
|
||||||
|
</figcaption>
|
||||||
|
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
And, you know what? Things were alright. However, I have recently been a victim of a seemingly targetted spamming incident. I was suddenly recieving mail from the mail server warning of low disk space and of high volumes of mail being delivered to this mailbox. I looked into by junk box for the first time in a while and discovered over one hundred emails in the past half an hour. Luckily, due to the helpful nature of mutt bindings, I could mass delete them all in one go. However, this kept happening. Every now and then, I would come across a random bulk email spam from a clearly throw away email address.
|
||||||
|
|
||||||
|
However, these obfuscated mailing addresses gave me an idea. How were the spammers obtaining my email address? Well, the obvious answer was that they were randomly accessing the site and scraping using a regex to find a correct email address. It doesn't matter if some of them are inactive, inaccurate or completely broken - thousands more will be all of the above. So, if I can create something which does not fulfill the regex of an email address, they won't pick it up. In particular, this requires disrupting the pattern for the box name (the part before the '@' sign) and attempting to disrupt the pattern entirely (remove the '@' sign entirely). The solution? Very simply. The standard UNIX "tr" tool can translate these patterns between them effectively. I chose the '\*' to replace the '.' sign, as it is illegal in normal email addresses (regex specifies word characters, from which '\*' is excluded). I also chose to replace the '@' sign with a dash to prevent it appearing entirely. The dash was chosen as it actually _is_ legal in email addresses, so will disrupt regexes which find the '@' symbol later on.
|
||||||
|
|
||||||
|
Now, I have heard from the AUR maintainers that some spammers are starting to realise of this common obfuscation method and attempt to decode it properly. So, I added an extra layer of obfuscation - the sed layer. At the end of the email pipeline, you will see something which looks like this:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
| sed 's/com.au/co.uk/'
|
||||||
|
```
|
||||||
|
|
||||||
|
All this is doing is substituting the fake domain registrar ".com.au" for the real one in the final email. This means that spam bots will be directed to the entirely false domain of "ethanjmarshall.com.au", which - as of 2022 - is not registered. This extra layer has reduced my volume of spam to effectively zero. I am assuming that my mail is already out there in some pre-compiled list, but I don't really care about this: hopefully it will be the highlight of my week when I obtain another email from "metropolitanpolicemps@gmail.com" calling me a pedophile (and spelling it horribly wrong in the process).
|
||||||
|
|
||||||
|
This process also helps to eliminate non-UNIX users from being able to email me. As mentioned in the contact page, people who claim that they use WSL occasionally still slip through the net. This is a problem I need to solve, and I do have an idea, From personal experience, I know that neither WSL 1 nor 2 implement direct packet access. So, simple programs like **ping(8)** will completely fail. So, I could just add:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ping -c1 ethanjmarshall.co.uk >/dev/null 2>&1 && ( <rest of pipeline> )
|
||||||
|
```
|
||||||
|
|
||||||
|
This will mean that WSL users who don't know what they're doing will just get nothing and be really confused. Actual _Based UNIX Users_™_,_ however, will be unaffected.
|
||||||
|
|
||||||
|
In any case, this simple method has reduced my volume of spam by at least two thirds and eliminated my high-volume problem. Good tech, can recommend.
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
|
_Check your compliance with Based_™_ UNIX-ism with the following simple script:_
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/sh
|
||||||
|
asdfg() {
|
||||||
|
return "this should cause an error"
|
||||||
|
}
|
||||||
|
echo $(asdfg)
|
||||||
|
```
|
||||||
|
|
||||||
|
This should cause an error.
|
66
content/blog/old/2022/long-opts-good/index.md
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
---
|
||||||
|
title: "GNU Options are Awesome"
|
||||||
|
date: "2022-05-22"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
Generally speaking, when I write in C or some other language that uses command line flags or POSIX-style interfaces, I try to stay away from spec extensions. There are numerous reasons behind this, including but not limited to acceptance, portability and stability. However, there is one exception to this rule. I love GNU option parsing.
|
||||||
|
|
||||||
|
At the command line, there are two general ways to pass options to a program. The first, and arguably most simple, way is through single character short options. These are applied like so:
|
||||||
|
|
||||||
|
```
|
||||||
|
grep -lrE "(extended)* regex"
|
||||||
|
```
|
||||||
|
|
||||||
|
As you can see, a single dash has been placed to indicate the beginning of an option. This is important grammatically, as this allows for the options parser to trivially determine if an argument is actually an option of simply a filename. For instance, grep should not parse the following for command line arguments:
|
||||||
|
|
||||||
|
```
|
||||||
|
grep "something special" file
|
||||||
|
```
|
||||||
|
|
||||||
|
Another thing that is worth mentioning is how multiple argments were combined into one for brevity. I _could_ have written the above as the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
grep -l -r -E "(extended)* regex"
|
||||||
|
```
|
||||||
|
|
||||||
|
But that exampel contains a large amount of duplicated information. I do not _have_ to add extra dashes to get my meaning across, so why should I? Instead, many short options can be combined into one. There is one exception to this, and that is if a flag requires an argument, which is the next text to be parsed. Because of a quirk in how parsing works, this argument can either be combined with the flag or be separated by whitespace and it has the same semantic meaning:
|
||||||
|
|
||||||
|
```
|
||||||
|
sed -ibu 's/bad/good/g' file
|
||||||
|
sed -i bu 's/good/bad/g' file
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:** The "-i" flag is a GNU extension, but is widely adopted and, frankly, I don't understand how the POSIX designers left it out. It's practically a necessary feature.
|
||||||
|
|
||||||
|
Now, however, this is all well and good. But, at times, short flag names can hinder expressiveness. Take the following hypothetical example of a webserver startup. Which startup is more clear to you:
|
||||||
|
|
||||||
|
```
|
||||||
|
httpserve -p80 -l0.0.0.0 -faB ./public
|
||||||
|
httpserve --port=80 --listen=0.0.0.0 --fork --append --bar ./public
|
||||||
|
```
|
||||||
|
|
||||||
|
In this instance, I think a balance has to be struck, and some of those options are perfectly good as short options, but the fact remains that sometimes short options severely hinder expressiveness and readability, particularly in long pipelines or shell scripts. However, what you just saw was one feature of the GNU libc implementation that I think is an absolute genius of design.
|
||||||
|
|
||||||
|
The GNU designers wished to add a feature where an option could be written as a full word, rather than a single character. This introduces a certain amount of complexity into the C programming (unbounded strings are always a pain to deal with), but the addition is by no means severe. This sounds all well and good - so why didn't they simple do what Go has done and implement flags like the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
httpserve -port 80 -listen 0.0.0.0 -fork -append -bar ./public
|
||||||
|
```
|
||||||
|
|
||||||
|
The answer to this is that there is no semantic difference between the argument "-port" and the _separate_ flags "-p", "-o", "-r" and "-t". In order to support **both** short and long options, as I think is a good idea, something had to semantically differenciate a long option and a short one. So, what did they choose? They chose an already established identifier which had a very clear semantic meaning that would not be confusing for the parser: "--". If the next character for an option is a "-", redirect parsing on to the long option parser. Else, just do a regular short option parser. Simple!
|
||||||
|
|
||||||
|
Now, this does introduce a small problem. "--" is an already established identifier, as I mentioned earlier. You may not have known this, but placing "--" in a UNIX program's command line forceably terminates option parsing. This is useful to be able to manipulate files or pass literal arguments which begin with a leading dash. Otherwise, it would be impossible to delete a file which is simply called "-file" or even just "-f". The correct way to do this is to use `rm` like the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
rm -- -f
|
||||||
|
```
|
||||||
|
|
||||||
|
This will delete a file with the name "-f", rather than place `rm` in force mode. This way that the GNU option parser decides if this is the token to end parsing or begin a long option is simply the presence of whitespace straight after the token. This means that long options cannot begin with a space character, but - realistically - how likely was that to begin with? This is why I think that the choice of using the "--" token for this purpose was a stroke of genius.
|
||||||
|
|
||||||
|
Passing arguments to long options is a similar challenge. We obviously can't pass them without any kind of delimter, as the nature of a long option requires that the parser treat any non-whitespace characters after the "--" as part of the option name. The designers decided to instead use a simple equal sign ("=") as the delimeter. Failing that, simple whitespace again. This is expressive, programatic and declarative - which fits all the stated goals of introducing long options.
|
||||||
|
|
||||||
|
In summary, I believe that the presence of these long options is a stroke of design genius. Although long options are a tool to be used lightly and to be implemented sparingly, I still believe that they are a fantastic piece of design. Their usage, in my opinion, should be similar to that of the `git` command line tool, which places most things as long options and creates shortcuts to them through short options.
|
||||||
|
|
||||||
|
This is one of the few GNU extensions that I use in most of my programs and will continue using for a very long time.
|
18
content/blog/old/2022/tf2-hitbox-myth/index.md
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
---
|
||||||
|
title: "Myth Busters: TF2 Scout Hitbox"
|
||||||
|
date: "2022-05-30"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
In TF2, there was a rumor around a while ago that the Scout could, if given enough increases to his base movement speed, outrun the hitbox used for hitscan and/or projectile collision detection. This is **completely _false_**_,_ but the reasons are quite interesting, so I would like to explain why I believe it to be false.
|
||||||
|
|
||||||
|
The "hitbox" of an object is, in reality, the AABB (Axis-Aligned Bounding Box) of an object. This is done by performing a linear search through the co-ordinates of an object and computing the maximum and minimum in all three axes. This yields the coordinates of a cube which is the smallest area which encompases every point in a mesh's set of vertices.
|
||||||
|
|
||||||
|
Now, for very detailed models (such as character models), this can be an expensive process. Vertices are by no means sorted in size order (that would somewhat defeat the purpose of the search), so an entire cycle through is required each time we wish to calculate an AABB. This means that most engines either embed this information in the model itself, or they calculate it once at runtime. The reason we can do this is that we can calculate this bounding box once and then simply store it in model-local coordinates which will be translated via matrix transform with the model.
|
||||||
|
|
||||||
|
But wait! I just said that the bounding box is moved via matrix transform - the same transform that the model itself uses. Bingo. This is the key point. If the bounding box is in object local space, it is _physically impossible_ for their positions to be misaligned.
|
||||||
|
|
||||||
|
It is at this point that I point out why I said that "I believe" it to be wrong. The Source engine is quirky. Not only is it quite old and clunky to do some tasks, it also has some design decisions that are so _mind numbingly_ dumb that even I could do better in an afternoon for that particular purpose. A great example of this is Source's network code. It requires you to manually specify what object properties will be sent across the network from server to client. Additional things (such as interpolation and lag prediction) make networking in Source even less deterministic. So, it is fully possible that networking bugs and/or quirky replication of model updates _could_ be the cause of this to happen. But, this theory assumes that the hitbox and the model itself are separate entities. They are intrinsically linked, the same way a polygon and its associated material are in Source. In this way, the people who claim that the scout can "outrun" his hit box may also claim that he can outshoot his bullets. There is no way to do this other than cheating, and even that would require some kind of engine vulnerability. You may have noticed that, in Source, if you loose connection, even the local player freezes on the spot. The reasoning behind this is that the player is not controlled on the client at all. The current state of client inputs are sent to the game server each network tick for processing. This causes certain events to be processed as needed, such as movement. What does this mean? In contrast to many other game engines, this means that exploits of the local player, such as flying, noclipping or being invisible, are simply not trivially posible in Source. The downside of this is that players with bad network connections have to rely on their half-baked lag compensation and interpolation algorithms to hide the problem, rather than solve it. This architecture is great for security, not so much for performance.
|
||||||
|
|
||||||
|
In short, it is not trivially possible to outrun your hitboxes in any Valve game. The reasons why are linked with networking, AABBs and funamental engine networking design. I rest my case.
|
21
content/blog/old/2022/the-feeling-of-physics/index.md
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
title: "The Feeling of Physics"
|
||||||
|
date: "2022-05-04"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
coverImage: "formula-math-mathematics-physics-wallpaper-preview.jpg"
|
||||||
|
---
|
||||||
|
|
||||||
|
There is a certain fundamental feeling that comes alongside doing physics (particularly theoretical) which is unexpectedly heady and exhilarating - a feeling that you would never expect to experience when doing simple mathematical calculations.
|
||||||
|
|
||||||
|
The feeling of physics is when you can predict the future. Without performing any such investigation, predicting the motion of a pendulum, falling body or accelerating car. Predict exactly what would happen if the car impacted the pendulum, where the energy would go and what would happen to both. Scaling up, this can be used to predict the motion of the sun, stars and planets - the motion of the lunar lander and rockets launching at this very moment. We can predict phenomenon that we will never see and can never hope to see. We can predict anything about the future, given enough time and enough information about the present
|
||||||
|
|
||||||
|
The feeling of physics is being able to prove and know the existence of particles and concepts too microscopic for us to ever hope to see them, and yet to, nevertheless, understand them better than we could ever hope to otherwise. We can deal with immense quantities of energy, that which we will never use in a lifetime, and yet we can deal with the most miniscule of details so small that the number of them defies our understanding of numbers. We can know of theoretical concepts that could never possibly have a grounding in practicality, and yet which are logically sound when investigated. The feeling of physics is reading about things which you can never even hope to see, and yet which you can be confident are all around you as you speak.
|
||||||
|
|
||||||
|
The feeling of physics is the ability to think on paper and to see your paper map out into reality, as what you have on paper _is_ reality. Predictions of the movement of a space craft, the sun or even a baseball which proceed to follow your command to the very last detail. Design of buildings, machines or mechanisms which work on paper we can be confident will work in reality too. The feeling of physics is the ability to express immensely complex ideas with algebra and numbers. The motion of planets, coiling of springs and the movement of particles - all expressed using **π**, equations and simple multiplication. By solving for x, we can solve for the secrets to the universe.
|
||||||
|
|
||||||
|
The feeling of physics is to be transported to the center of the sun, edge of a black hole or distant galaxies terametres away all while sat in a laboratory or in school. We can see things that no human alive will ever see, like the core of a nuclear reactor, the planet or a thermal explosion. The knowledge that the concepts that seem so alien to us, concepts that _couldn't possibly_ be true are actually happening, in reality - _right now, as we speak._ The amazement felt as you realise that this enormous fantasy you have seemingly been taught is, in fact, very real and in the same world as you are.
|
||||||
|
|
||||||
|
The feeling of physics is to be able to look out at the crescent moon from your window and marvel at the beauty - not just of the moon itself, but also of the fact that we have the power to figure out (using simple optics and pi) what exactly is going on on the surface of the moon right now. And so, as I sit writing this staring at the moon, I can know that I know what is happening 238,855 miles away from me on that giant orb in the sky we call the moon.
|
||||||
|
|
||||||
|
All of this is the feeling of physics.
|
|
@ -0,0 +1,36 @@
|
||||||
|
---
|
||||||
|
title: "Neither voltage nor current kill"
|
||||||
|
date: "2023-09-03"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
Quite a common adage heard in HVAC schools or electrician training is that "Volts jolt, but current kills". I would like to put forward my argument today that this is completely incorrect. Instead, I will argue that it is, in fact, the work done by a circuit element which causes the danger.
|
||||||
|
|
||||||
|
## Voltage and Current
|
||||||
|
|
||||||
|
Any high school level student will be aware of the basic relation that the current in a circuit is proportional to the voltage across its terminals. The constant of proportionality is the reciprocal of the resistance, R. This gives us the basic relation of Ohm's Law:
|
||||||
|
|
||||||
|
**V = IR**
|
||||||
|
|
||||||
|
Let us consider what happens if I were to hold two terminals in my hands, one which is grounded and one which is at +5V with respect to the other. By Ohm's Law, a current flows through my body. However, also by Ohm's Law, this current is _proportional to voltage._ Therefore, as the voltage across my body increases, so does the current through it. Given that this is true, does it make sense to say that either the voltage _or_ the current could cause injury. No, of course not. In fact, without either the voltage or the current, the electrical circuit would not complete and no charges would flow at all.
|
||||||
|
|
||||||
|
As you can see, the essential truth which totally destroys this notion of either voltage or current being to blame for electrical injuries is that _a high voltage causes a high current._
|
||||||
|
|
||||||
|
## Well... sort of
|
||||||
|
|
||||||
|
Of course, this saying hasn't been around forever without reason. The "wisdom" which it attempts to convey is that, if no current flows, simply being at a voltage shouldn't necessarily cause you any harm. For instance, imagine in the first example if I were simply holding one terminal of the voltage source with one hand. Would any current flow? No, or at least not continuously. In this instance, assuming that you haven't already been charged by static electricity somehow, your body will act like a capacitor as a current flows for a fraction of a microsecond and charges are dumped into your body but cannot flow anywhere. As more charges are added, the electromagnetic forces which act against the EMF increase and, eventually (well, actually extremely quickly), no more charges can be added and you are in a state of electromagnetic equilibrium.
|
||||||
|
|
||||||
|
This is the key reason why birds can sit on power lines without being killed. They essentially act like a high-value resistor in parallel with that section of the power line. Typical resistances of power line segments may be in the milliohms, which is at least six orders of magnitude lower than the _minimum_ for that of a human body. By the principle of current division, we can say that at minimum 99.9999% of the current flows through the power line rather than the bird.
|
||||||
|
|
||||||
|
## Then why do volts jolt?
|
||||||
|
|
||||||
|
The old saying may be referring to a temporary arc which could be created by a high voltage. As already stated, your body may act like a low-value capacitor in some instances. For the temporary transient created by the high voltage when charging up your body, some current I will flow, rapidly decaying capacitatively. However, this initial transient current could be rather high. This is the "jolt" you can feel.
|
||||||
|
|
||||||
|
The same effect is felt with static discharge. Your body has acted like a capacitor, storing charges and, therefore, being at a higher voltage than another conductor temporarily. When the static electricity discharges from you, a current on the order of amps may flow, but only for a millisecond or less.
|
||||||
|
|
||||||
|
## What actually kills, then?
|
||||||
|
|
||||||
|
Well, the simple (but not quite correct) answer to this is that the energy deposited by the circuit into your body is what will kill you. The power dissipated by a component is equal to the voltage across it multiplied by the current through it. This means that, each second, the power source will do P joules of work on the component. As it turns out, this relies both upon the current and voltage. If you are wired in parallel with a 1 kiloohm resistor to the same 5V source as before, the majority of the current will take the kiloohm resistor path. However, the voltage across your body will still be the same. The difference in this case is that the current is much lower and therefore the power.
|
||||||
|
|
||||||
|
An additional factor to consider is that, when an electrical current flows through nerves, this can disrupt the closed-loop control of the human body, leading to break down of autonomous processes, such as heartbeat regulation and breathing, which just so happen to also be the most vital.
|
|
@ -0,0 +1,24 @@
|
||||||
|
---
|
||||||
|
title: "The Actual Definition of Physics"
|
||||||
|
date: "2023-11-19"
|
||||||
|
categories:
|
||||||
|
- Old Blog
|
||||||
|
---
|
||||||
|
|
||||||
|
I often hear a lot of very flowery definitions of Physics, such as "The Application of the Scientific Method to Natural Law" or "The Investigation of the Laws of the Universe". However, much of this appears to make Physics seem much more all-encompassing than it truly is. For example, a Physicist does not concern himself with questions of purely abstract philosophy. What is beauty? Perhaps he may have an opinion, but an objective answer evidently eludes him. Arguably, such an answer could never come from within Physics itself purely due to the nature of the question. If we were to take any of the above answers from above, though, it should be logically true that we can build on the foundations which Physics has given us to find an answer. This is obvious nonsense.
|
||||||
|
|
||||||
|
I would like to propose a much simpler and - in my opinion - more accurate definition of Physics:
|
||||||
|
|
||||||
|
> Physics (noun) - The Study of Rates of Change
|
||||||
|
>
|
||||||
|
> Ethan Marshall (2023)
|
||||||
|
|
||||||
|
That's it! Think about it: what is there in Physics which does not involve a rate of change? One of the core principles of Physics is time, a "substance" which does not really exist but which is made to exist through our perceptions of rates of change around us. Physics was shook most severely to its core by the discovery that time may pass at different rates for different observers by Einstein and some of the most important principles of Physics (time invariance or independence, for instance) rely entirely upon rates of change. Even fields of Physics in which no change occurs (such as statics) are simply defined by the rate of change being zero!
|
||||||
|
|
||||||
|
I think the perfect quote to illustrate this point is the following:
|
||||||
|
|
||||||
|
> Since Newton, mankind has come to realize that the laws of Physics are always expressed in the language of differential equations.
|
||||||
|
>
|
||||||
|
> Steven Strogatz
|
||||||
|
|
||||||
|
Of course, the language of differential equations is that of rates of change. I rest my case.
|
17
content/blog/old/_index.md
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
+++
|
||||||
|
aliases = ["old", "ancient"]
|
||||||
|
title = "Old Posts"
|
||||||
|
author = "Ethan Marshall"
|
||||||
|
+++
|
||||||
|
|
||||||
|
These are a collection of old posts from my ancient (pre-2023) website. The majority of these are pretty much the same character as this current website (i.e personal blog posts about stuff), but many of them pre-2016 are programming tutorial attempts and the like.
|
||||||
|
|
||||||
|
I think it's safe to say I'm a changed man.
|
||||||
|
|
||||||
|
![Morgan's a changed man too](changed-man.jpg)
|
||||||
|
|
||||||
|
The work I'm most proud of occurs at about 2020 onwards and is the sort of style I will be continuing with into the future. Although there is an RSS feed for this section, I'm going to be deliberately leaving this section alone as a sort of archive so I wouldn't bother subscribing to it.
|
||||||
|
|
||||||
|
Anyways, that's a wrap. Enjoy digging through the garbage I produced years ago (some of which I made when I was still in school!).
|
||||||
|
|
||||||
|
![My opinion on school](fuck-this-school.jpg)
|
BIN
content/blog/old/changed-man.jpg
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
content/blog/old/fuck-this-school.jpg
Normal file
After Width: | Height: | Size: 45 KiB |
|
@ -6,6 +6,8 @@ copyright = 'Copyright (C) 2024 - Ethan Marshall'
|
||||||
|
|
||||||
sectionPagesMenu = "main"
|
sectionPagesMenu = "main"
|
||||||
|
|
||||||
|
summaryLength = 10
|
||||||
|
|
||||||
[params]
|
[params]
|
||||||
noindex = false
|
noindex = false
|
||||||
|
|
||||||
|
@ -14,7 +16,7 @@ palette = "gruvbox-dark"
|
||||||
|
|
||||||
[params.about]
|
[params.about]
|
||||||
title = "Ethan Marshall"
|
title = "Ethan Marshall"
|
||||||
description = "A generic computer programmer. I like C, Go and math."
|
description = "A programmer who, to preserve his sanity, took refuge in electrical engineering. What an idiot."
|
||||||
|
|
||||||
[[params.socialLinks]]
|
[[params.socialLinks]]
|
||||||
icon = "fa-brands fa-github"
|
icon = "fa-brands fa-github"
|
||||||
|
|
7
siteupdate
Executable file
|
@ -0,0 +1,7 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
rm -rf public/
|
||||||
|
hugo
|
||||||
|
|
||||||
|
ssh root@ejv2.cc rm -rf /var/www/html/
|
||||||
|
rsync -r public/ ejv2.cc:/var/www/html/
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
{{ range .Pages }}
|
{{ range .Pages }}
|
||||||
{{ .Render "li" }}
|
<li><a href="{{ .Permalink }}">{{ .Title }}</a> -- {{ .Date.Format "2 January 2006" }}</li>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
|
@ -10,10 +10,29 @@
|
||||||
|
|
||||||
{{define "aside" }}
|
{{define "aside" }}
|
||||||
{{ if .Params.description }}<p>{{ .Params.description }}</p>{{ end }}
|
{{ if .Params.description }}<p>{{ .Params.description }}</p>{{ end }}
|
||||||
{{ if or (.Params.author) (.Params.date) }}
|
{{ if .Params.date }}
|
||||||
<p>
|
<p>
|
||||||
{{ if .Params.author }}By {{ .Params.author }}{{ if .Date }}, {{ end }}{{ end }}
|
{{ if .Date }}<strong>First Published</strong> {{ .Date.Format "2006-01-02" }}{{ end }}
|
||||||
{{ if .Date }}{{ .Date.Format "2006-01-02" }}{{ end }}
|
</p>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{if .Params.categories }}
|
||||||
|
<p>
|
||||||
|
<strong>Categories: [</strong>
|
||||||
|
{{ range .Params.categories }}
|
||||||
|
<a href="/categories/{{ . }}">{{ . }}</a>
|
||||||
|
{{ end }}
|
||||||
|
<strong>]</strong>
|
||||||
|
</p>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{if .Params.tags }}
|
||||||
|
<p>
|
||||||
|
<strong>Tags: [</strong>
|
||||||
|
{{ range .Params.tags }}
|
||||||
|
<a href="/tags/{{ . }}">{{ . }}</a>
|
||||||
|
{{ end }}
|
||||||
|
<strong>]</strong>
|
||||||
</p>
|
</p>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
|
|
|
@ -4,18 +4,14 @@
|
||||||
{{ .Content }}
|
{{ .Content }}
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
{{ range .Pages }}
|
{{ range where .Pages "Kind" "page" }}
|
||||||
<article class="post">
|
<article class="post">
|
||||||
<header class="post__header">
|
<header class="post__header">
|
||||||
<h1><a href="{{ .Permalink }}">{{ .Title | markdownify }}</a></h1>
|
<h1><a href="{{ .Permalink }}">{{ .Title | markdownify }}</a> -- {{ .Date.Format "2 January 2006" }}</h1>
|
||||||
<p class="post__meta">
|
|
||||||
{{ .Params.author }},
|
|
||||||
<span class="date">{{ .Date.Format "2 January 2006" }}</span>
|
|
||||||
</p>
|
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<section class="post__summary">
|
<section class="post__summary">
|
||||||
{{ .Summary }}
|
{{ .Description }}
|
||||||
</section>
|
</section>
|
||||||
</article>
|
</article>
|
||||||
{{ end }}
|
{{ end }}
|