A love letter to Objective-C
The nature of software is to always be evolving. COBOL jokes aside, it’s rare to find programming frameworks that reach a level of maturity and support that allow them to just exist without being supplanted by a newer language or a better abstraction. Which naturally is great. Who wants to find themselves writing software with the expectations of today while performing the tasks of manual memory management or manipulating strings that are just raw pointers in a block of memory terminating with a null (\0) character? But sometimes in this constantly evolving space, you find a framework that resonates, and you hold on to it tightly. I wanted to share how this happened for me, first with Ruby (no surprise) but then oddly with Objective-C.
Regex Isn't Hard
Regex gets a bad reputation for being very complex. That’s fair, but I also think that if you focus on a certain core subset of regex, it’s not that hard. Most of the complexity comes from various “shortcuts” that are hard to remember. If you ignore those, the language itself is fairly small and portable across programming languages.
It’s worth knowing regex because you can get A LOT done in very little code. If I try to replicate what my regex does using normal procedural code, it’s often very verbose, buggy and significantly slower. It often takes hours or days to do better than a couple minutes of writing regex.
An interesting mistake with Go's context package that I (sort of) made
I didn’t answer this correctly because I focused my attention on the wrong thing.
How can CharUpper and CharLower guarantee that the uppercase version of a string is the same length as the lowercase version?
Let's build a Full-Text Search engine
Today we are going to build our own FTS engine. By the end of this post, we’ll be able to search across millions of documents in less than a millisecond. We’ll start with simple search queries like “give me all documents that contain the word cat” and we’ll extend the engine to support more sophisticated boolean queries.
Using Go build directives to optionally use new APIs in the standard library
I mentioned recently that new APIs in the Go standard library were relatively easy to optionally support, because such new APIs only appear in new Go releases and you can conditionally build files based on the Go release that’s building your program. But that’s a pretty abstract description, so let’s make it concrete.
Why strace doesn't work in Docker
But I wasn’t interested in fixing it, I wanted to know why it happens. So why does strace not work, and why does --cap-add=SYS_PTRACE fix it?
Making Illegal States Unrepresentable
It’s a concept I find very helpful. But if you look for examples online almost everything either “let’s prevent dividing-by-zero” or “let’s enumerate the cases in a data type”. We can more creative than that! Some examples of “illegal states unrepresentable” that I found useful but have not seen anyone else talk about online:
Rust Ownership Rules
In this post, I took the opportunity to re-summarise what I consider to be the essence of this ownership rules in Rust.
Addressing of AF_INET, AF_INET6 and AF_UNIX sockets
A freshly created socket isn’t very useful. We have to tell it to either listen for incoming data, or connect to a remote peer. To achieve anything useful we need to perform a syscall dance, which involves either bind() or connect() or both.
And some notes about the DNS resolver rabbit hole.
kill tail(1) when sh exits
As a solution, the POSIX shell provides a built-in named trap, documented here. In short it allows to define actions to be executed upon signaling, and that includes shell termination. It is similar to atexit(3) in POSIX C.
Function Currying in Go
Go can be used to program in a functional style, previously I’ve written about how we can use this to implement Continuation Passing Style programming. As such, it is possible to implement currying in Go as well. Before we take a look at how we can implement this in Go, let’s take a practical look at what function currying actually is, and why we want this.
Beginner Problems With TCP & The socket Module in Python
Your operating system will deceive you and re-assemble the string you sock.recv(n) differently from the ones you sock.send(data). But here is the deceptive part. It will work sometimes, but not always. These bugs will be difficult to chase. If you have two programs communicating over TCP via the loopback device in your operating system (the virtual network device with IP 127.0.0.1), then the data does not leave your RAM, and packets are never fragmented to fit into the maximum size of an Ethernet frame or 802.11 WLAN transmission. The data arrives immediately because it’s already there, and the other side gets to read via sock.recv(n) exactly the bytestring you sent over sock.send(data). If you connect to localhost via IPv6, the maximum packet size is 64 kB, and all the packets are already there to be reassembled into a bytestream immediately! But when you try to run the same code over the real Internet, with lag and packet loss, or when you are unlucky with the multitasking/scheduling of your OS, you will either get more data than you expected, leftover data from the last sock.send(data), or incomplete data.
Not strictly a python problem, either.
This project contains small exercises to get you used to reading and writing Rust code. This includes reading and responding to compiler messages!
Execute Program is for people who already know a programming language. We’ll help you to fill in gaps in your existing knowledge.
At least in the beginning, seems introductory. Not sure how advanced it goes.
A program to detect mojibake that results from a UTF-8-encoded file being misinterpreted as code page 1252
It is not uncommon to see UTF-8-encoded data misinterpreted as code page 1252, due to file content lacking an explicit encoding declaration, such as you might encounter with the Resource Compiler. So let’s write a program to detect that specific kind of mojibake.
Why you should learn just a little Awk: An Awk tutorial by Example
In grad school, I once saw a prof I was working with grab a text file and in seconds manipulate it into little pieces so deftly it blew my mind. I immediately decided it was time for me to learn awk, which he had so clearly mastered.
Things I Learnt The Hard Way
This is a cynical, clinical collection of things I learnt in 30 years working with software development. Again, some things are really cynical, others are long observations on different jobs.
Weird Ruby: Positive and Negative Strings
Turns out that when frozen string literals were introduced in Ruby 2.3 a couple of unary methods were added to the String class - namely unary + and -. They made it possible to have “positive” and “negative” string literals. What does this mean exactly? Let’s figure this out together!
Representative Line: Log Every Error
This code knows that accessing the logger object is code that can throw an error, so if it gets an error fetching the logger object it… logs the error. With the logger object that returned some kind of error.
Recursive failure is best failure.