Mat Hill

← to home

# can you help me with x?

Hopefully! Email me :)

# how can I learn x too?

I find it best to read documentation and seek out good textbooks. This can be tiring, but the trick is to put zero pressure on remembering or understanding anything - there's no exam!
Lazily scanning through every function in a library / scale in a musical style / brush type in an art catalogue e.t.c. will go a looong way! You will be amazed at how much you recall when you get stuck.

For coders, I recommend learning some C (don't worry, it's small!) and doing an embedded software project (I highly recommend the Raspberry Pi Pico!). Much of modern programming practice is arguably a reaction to the decades spent doing similar tasks with low level languages and low-power hardware. Experiencing this really helps to contextualise things. I guarantee you won't look at your laptop / phone / washing machine the same way again :)

Some of my favourite and most rewarding tool choices have been in direct defiance of my prejudices. In fact, nowadays I actively recommend trying something utterly bizarre (like vim) on the off chance you fall in love (like I did, with vim).
Enjoying a tool is important. If you find that you do, use that energy to learn it inside-out :)

Honestly, thinking about recommendations with hindsight is tricky. Much of what I have learned was motivated by aspirations that have long since changed.
If I met my past self... I doubt I could convince them to relax, ignore what's trendy, and do more aimless studying!

TL;DR: just focus on changing your perspective, you will gain confidence over time :)

For specific more suggestions, check out my links & books page.

I also have a fine art learning adventures page :)

# what hardware do you use?

My main machine is a Framework laptop. I love it.
I used to buy relatively cheap gaming laptops, but I often found myself disabling the discrete GPUs to prevent excess heat and power consumption.
I hope to keep my Framework for as long as possible, perhaps upgrading to a RISC-V CPU years from now :)

I have a Pinebook Pro. It's really nice to use. If I only did systems programming, I would probably make this my main laptop.

I use an ErgoDox EZ for typing. I like the keyboards on my laptops, but the EZ helps with my RSI. It also encouraged me to improve my touch-typing, and use a more code-friendly symbol layout. I got the blank key caps, and labelled them with marker pens :)

I have a small Wacom Intuos tablet, which I use for digital modelling / painting. Blender is really powerful with a 3-button mouse, and my stylus has two thumb buttons which are great for RMB / MMB mapping.

My phone is a Fairphone 3 running iodéOS. I mainly use it for instant messaging, 2FA, or listening to music. I love what Fairphone are doing, but I hope to ditch Android someday for a more flexible mobile OS. The Pinephone Pro looks promising.

I love using Raspberry Pis for things. I have a Pi 3+ with a DAC board running Pianoteq. It can turn any midi keyboard into a great sounding piano!

For photos, I either use my phone, or an Olympus OM-10 35mm film camera.

For videos, I use an old Canon EOS M with a cheap CCTV camera lens, running Magic Lantern. I used to use a 550D (Rebel T2i in the US), but the EOS M offers similar quality and is much smaller and cheaper.

Oscilloscopes are wonderful. I primarily use one for making audio electronics, which has relatively low frequency requirements. Two channels is nice, but not required.
Make sure you understand how to not blow up your scope!

Most analogue audio projects require bipolar ±12v power! It's safest to set this up so that 0v is tied to earth ground, but this requires a dual output supply which can handle negative voltage. Moritz Klein has a tutorial on creating a simple synth power supply. This is great for powering finished projects, but a proper lab bench power supply provides desirable prototyping features, such as short-circuit protection.

I use the Hakko FX-888D soldering station. Soldering is deceptively difficult, especially without enough heat!

# what software do you use?

I have to use all sorts of applications & operating systems for my work... I like learning new things, but I rarely enjoy them beyond that!

Blender, Krita, Firefox, and KiCAD are generally the only GUI apps I keep installed. I love Houdini too though.

My personal laptop runs Ubuntu, as it stays out of my way more than Windows / macOS. I like to treat devices as being separate from my tasks & data, so anything with sensible defaults is great. I use the fish shell for this reason to.

Most of my personal stuff is done via command line interfaces, simple shell scripts, PGP encryption, and tabulated plain-text files. My growing collection of DIY tools has yet to fail me... although there were some nasty data losses while I was learning - backup your backups!

I use RSS feeds to keep up to date with blogs, youtube, tweets e.t.c.

# how can i pay you?

If you are looking to pay me for client work but have lost my invoice, or would like to reimburse me for something, please email me.

If you want to support what I do, thanks :) I don't accept donations, but I would love it if you donated to Abortion Rights UK, Mermaids UK, or Gendered Intelligence.

# how do you manage memory in c?

Languages such as C or C++ require devs to manually manage heap memory. Those who work primarily in Python or Javascript are often confused or intimidated by this, and many abstractions have been devised in the hopes of retaining blissful memory ignorance.
I've found that, with a consistent strategy, memory management is actually super simple!

When working with modern amounts of RAM, we can comfortably malloc a large chunk of memory up-front. In fact, I like to allocate memory up-front as much as possible, as any communication with the OS has an unpredictable duration, and could technically fail.

u64 memory_size = 1024 * 1024;
u8* memory = malloc(memory_size);

Now that we control a chunk of memory, how should it be used?
You could treat it as an array, writing and reading whilst keeping track of offsets and data layouts... but this would be a pretty complex system.
Sometimes such complexity is necessary, regardless of language. But for something as universal to coding as just data being in memory it is a waste of head space.
We want the ergonomics of automatic memory management, for the majority lines of code where we just need a place to put stuff and don't want to think about it.

I pass an alloc pointer into every function that needs dynamic memory (or calls one that does). Internally, they keep track of a chunk of memory, and use assertions to enforce limits and check for bugs.

void alloc_create(alloc* alloc, u8* memory, u64 memory_size);
u8* alloc_push(alloc* alloc, u64 size); // Allocate!
u64 alloc_top(alloc* alloc); // Number of allocated bytes.
void alloc_pop_to(alloc* alloc, u64 top); // 'Free' to a previous top.

If a function requires memory, it can allocate it without the overhead of talking to the OS, or the complexity of avoiding a leak.
Different allocator objects can be used (or even nested!) to control what goes where.
However, the trick to keeping APIs simple is to limit functions to one allocator parameter as often as possible.
But, what if alongside producing data, a function internally allocated intermediate data which is now redundantly occupying the allocator's memory?
We can simply copy said data to another location, and consider the function's original allocation 'free-able'.
Sticking to this pattern leaves us with an allocator solely for temporary allocations.

u64 checkpoint = pf_alloc_top(alloc_temp);

u64 data_size = 0;
u8* data = load_file(alloc_temp, file_name_str, file_name_str_size, &data_size);

copy_to_alloc(alloc_persist, data, data_size);
alloc_pop_to(alloc_temp, checkpoint);

The vast majority of my allocations are temporary, with occasional copying of persistant data. I'm mostly writing software with frames and update loops, so I just free my temporary allocator at the end of each frame.

Check out my implementation of pf_alloc to see this stuff in practice. I just use stack allocators, but pf_alloc could easily be a union of different allocator types, with different performance / space tradeoffs!

↑ to top

← to home