~mrlee/www.leemeichin.com

f0b9db493a40953921c3178c8384c44b5c81c752 — Lee Meichin 13 days ago d21dc11
Update headers
M posts/can-you-crack-the-code.org => posts/can-you-crack-the-code.org +3 -3
@@ 35,7 35,7 @@ I presume you've seen this kind of puzzle before: there is a lock that requires 

-----

◊h2{A brief introduction}
** A brief introduction

If you're unaware of Prolog, it's a /logical progamming/ language that, in its most simplest terms, takes a bunch of facts and rules and then gives you the tools to query them to get the outcome you want. In more complicated terms, a cursory search on the intertubes will lead you to a vast collection of academic papers that explain more. This is not the kind of language that is casually blogged about by the masses, as with more mainstream ones like CSS, HTML, or ColdFusion.



@@ 96,7 96,7 @@ Let's try one more thing, which should explain enough about Prolog to be dangero

This is more or less the essence of Prolog, and your program is essentially a database of facts and rules, and then you use the program by querying those facts and rules. You'll make a query by providing what you _do_ know, and then placing a variable (or a placeholder) in the spots where you don't know the answer. You don't tell Prolog how exactly to compute that answer. And with that explained, I think we can try and crack this code.

◊h2{Doing some l33t haxx0ring}
** Doing some l33t haxx0ring

Here's the puzzle again, for reference:



@@ 265,7 265,7 @@ Did you solve the puzzle yourself? Do you remember the answer? If you don't care

The exercise of writing that in a less brute-force manner is left to you, my beloved reader.

◊h2{The grand finale}
** The grand finale

So ends 2020, so ends this post. Did your brain-grown answer match the one this Prolog program gave you? What do you think about logic programming in general now you've seen some of it? Why not share it with your friends or whoever, if they're interested, and see what they think?


M posts/gettin-ziggy-with-it-pi-zero.org => posts/gettin-ziggy-with-it-pi-zero.org +4 -4
@@ 22,7 22,7 @@ Ready to... get Ziggy with it? Oh, I bet you are. 😋 If you want to skip to th

-----

◊h2{Hello, Pi.}
** Hello, Pi.

The first and most complicated part of any low-level project is the bit where you try and establish a build system of some sorts. We're going to forget about that completely for now and apply some elbow-grease to the situation.



@@ 83,7 83,7 @@ We're at a good point now to try and compile this thing and then run it on the P

-----

◊h2{Build and Push}
** Build and Push

Zig comes with a nice little build system out of the box, but we're not going to use it right now because it's a work in progress. I'll leave that as an exercise to you, the reader, and I urge you to contribute any documentation you come up with to Zig. Instead, we'll use the CLI which is just as powerful and, gracefully, a bit more discoverable for our purposes.



@@ 119,7 119,7 @@ Let's move on and make this kitten purr. Meow 🐈.

-----

◊h2{Getting this show on the road}
** Getting this show on the road

In true /draw the rest of the fucking owl/ fashion◊^[11], what follows is a bit of a code-dump since the primary method of communicating with your OLED display is to, literally, write a few bytes to a file. The registers available and what can be written to them are often described in a meticulously detailed datasheet◊^[12], but they're not exactly light reading and we can save a bit of time by grabbing the info from elsewhere. A lot of the constants that follow are gracefully derived from those listed in a certain ~owenosborn~'s wiringPi-based driver.◊^[13]. Credit where credit's due, eh.



@@ 224,7 224,7 @@ This ~fill~ function will (rather quickly) turn the display solid white, updatin

-----

◊h2{A zig-a-Zig aaaahhhh...}
** A zig-a-Zig aaaahhhh...

◊aside{
  Reach out to me at pleasemakeitstop@mrlee.dev if this is too much for you.

M posts/ruby-sorcery-ractor-2.org => posts/ruby-sorcery-ractor-2.org +2 -2
@@ 29,7 29,7 @@ While simple, this isn't something you'd call 'production ready'. There is at le

◊aside{Hint: what does or does not happen when the client's connection is lost or terminated?}

◊h2{Building an HTTP server with Ractor}
** Building an HTTP server with Ractor

In the beginning, the HyperText Transfer Protocol was (and still is!) a purely text-based specification layered on top of TCP. It has grown a hell of a lot of complexity over the years, in order to power more complex interactions over the web, but it is still easier to build a server that understands HTTP (even just HTTP 1.1) than it is to build the browser that handles all of the rendering.



@@ 42,7 42,7 @@ So, it sounds like a good time to turn this toy TCP server into a basic HTTP ser

There is, of course, a lot more to serving HTTP than this. For a start, there's no HTTP response! And then there are the other HTTP methods. Much of that will be covered in the following chapters.

◊h2{Parsing the request}
** Parsing the request

The anatomy of an HTTP request is divided, essentially, into three parts:


M posts/ruby-sorcery-ractor-3.org => posts/ruby-sorcery-ractor-3.org +2 -2
@@ 44,7 44,7 @@ And this bit of code in particular is what needs some attention:
  # ...
}

◊h2{HTTP responses in a nutshell}
** HTTP responses in a nutshell

A response has a similar structure to a request, comprising a status line, an arbitrary number of headers, and then optionally the response body.



@@ 66,7 66,7 @@ This is not the only way to define a response, as it can also be split up into c

For the sake of simplicity, the server will handle only the simple case for now: given a request to the server, it will respond with ~200 OK~ and a string of HTML.

◊h2{Building an HTTP Response in Ractor}
** Building an HTTP Response in Ractor

This is the example HTTP request from the previous chapter◊^[1].


M posts/ruby-sorcery-ractor.org => posts/ruby-sorcery-ractor.org +2 -2
@@ 29,7 29,7 @@ The final missing piece is that an actor can hold internal state, or in other wo
How does it fit together? An actor can have multiple addresses, and many actors can share the same address. This means that you can achieve scaling by having more actors listen on an address, effectively load-balancing incoming messages, and you can create more powerful actors that perform different tasks based on those same messages.


◊h2{Actor languages}
** Actor languages

If you've used Erlang◊^[4] or Elixir◊^[5] to any degree, you have already built something around this model and, perhaps, were not aware of it. This is because the actor model is an intuitive aspect of those languages that makes them what they are, and therefore everything is implemented in terms of it.



@@ 39,7 39,7 @@ In Erlang/Elixir, one key feature is that programs are designed to be fault-tole

◊aside{WhatsApp, Discord use Erlang/Elixir in their operations. It also powers telephone exchanges and 3G networks across the world.}

◊h2{Actors in the wild}
** Actors in the wild

You can consider technologies like Kubernetes◊^[7], Kafka◊^[8], and Web Workers◊^[9] in the browser to each be an application of the actor model in some form. This doesn't necessarily mean they were built with that in mind, just that you can find that they share many characteristics in common.


M posts/ruby-sorcery.org => posts/ruby-sorcery.org +6 -6
@@ 11,7 11,7 @@ I recently realised that despite many new additions to the Ruby language and eco

The first part of this series of posts is all about /Pattern Matching/.

◊h2{Pattern matching}
** Pattern matching

Ruby's pattern matching support, introduced experimentally in 2.7, is a lot more powerful than you may expect. All you need is to replace ~when~ with ~in~ and your ~case~ statements become capable of matching against /anything/.



@@ 44,7 44,7 @@ Ruby's pattern matching support, introduced experimentally in 2.7, is a lot more
  # NotAllowedError (forbidden)
#+end_src

◊h3{Custom destructuring}
*** Custom destructuring

You can deeply match any object in Ruby so long as you define a method to represent it as a hash, or a method to represent it as an array. Or both.



@@ 86,7 86,7 @@ This ~PlayingCard~ class is now capable of pattern matching.
  #=> false
#+end_src

◊h3{Pinning}
*** Pinning

That's fairly basic, what about pattern matching poker? Matching one card is easy, but suppose you want to match a hand.



@@ 135,7 135,7 @@ This particular solution depends on the hand being ordered, but that's fine, a l

The clever bit here is that the first part of the match (~[1, c, s]~) is used to constrain the rest of the pattern. So if ~c~ is ~:red~, then ~^c~ also has to be ~:red~ in order to match.

◊h2{Pattern guards}
** Pattern guards

You'll see this a lot if you're familiar with Elixir or other languages that do pattern matching well. Essentially, you can add conditional logic to your patterns so that a match is only possible if a separate condition is met.



@@ 160,7 160,7 @@ Building on the poker example, maybe it's valid to play the Joker, but only if t
  # => true
#+end_src

◊h2{Destructuring assignment without ~case~}
** Destructuring assignment without ~case~

One of the odd side-effects of this pattern matching functionality is that you get a new kind of assingment. In fact, in Ruby 3 this gets a syntax of its own with the rightward assignment operator, but you can still use something similar in 2.7.



@@ 183,7 183,7 @@ You also have to be absolutely sure you're matching the right thing.
  end
#+end_src

◊h2{Optimisations}
** Optimisations

If you recall earlier examples, I defined ~destructure_keys(*)~, which meant that I was explicitly ignoring the arguments normally passed to the method. This is useful in simple cases, but when dealing with complex objects you might want to be a bit more thoughtful about how you return a value. For example, converting the entire structure of the object into a hash might not be appropriate.


M posts/the-bookshelf.org => posts/the-bookshelf.org +4 -4
@@ 17,13 17,13 @@ Programming books are almost disappointingly over-represented as they're possibl
I added a few new books to the collection this year, and have been reading them as they arrive. Here's a quick run-through of what 2021 has looked like for me:


◊h2{The Phoenix Project}◊^[1]
** The Phoenix Project◊^[1]

As far as Corporate Thrillers for Business Analysts go, The Phoenix Project easy enough to read and has some entertainment value. The cast is awash with wholly unsympathetic characters, the corporate setting oozes with toxicity, and it's impossible to turn a page without /someone/ being an asshole.

I didn't rate it and if its follow up /The Unicorn Project/ is any similar, then I think I'll give that one a pass. The Devops Handbook is still on my list, though.

◊h2{Extreme Ownership}◊^[2]
** Extreme Ownership◊^[2]

I had to keep an open mind when starting this one, but eventually I gave up because I could no longer ignore what I was really feeling while reading this. Extreme Ownership glorifies the war in Iraq and the US's role in it and uses those experiences to teach you about accountability. 



@@ 33,13 33,13 @@ Let's be fair, the advice is sound if you can put the chest beating and the hoo-

This one just wasn't for me.

◊h2{Metro 2033}◊^[3]
** Metro 2033◊^[3]

Like many people, my first intro to Metro 2033 was the game that was released a decade ago, and I've greatly enjoyed Artyom's journey from then up until the release of Metro Exodus. The post-apocalyptic setting is remarkable and I was sucked into the world in a way that Fallout could never manage. The stories feel more grounded in humanity and they're not quite as distracted by commentary about the excesses of capitalism.

I decided to revisit the world again this year, except this time by reading the books. I haven't finished this yet, as I've wanted to take my time with it. 

◊h2{Crucial Conversations}◊^[4]
** Crucial Conversations◊^[4]

I revisit this book every now and then, although it has the dual purpose of selling consultation along with offering a taste of advice. Once you get used to the relentless sales pitch for Crucial Conversations™ you can actually take away a great deal of learning from this.


M posts/things-ive-changed-my-mind-on.org => posts/things-ive-changed-my-mind-on.org +13 -13
@@ 12,55 12,55 @@ A lot of things can happen in ten years, and if nothing else my 30-something yea

This will probably come across as a bunch of hot takes that work better on Twitter, but that's one dumpster fire I'd prefer not to climb into. So here we go, in no particular order...

◊h3{I feel happier in myself when I don't pretend to have an answer to everything.}
*** I feel happier in myself when I don't pretend to have an answer to everything.

Corrollary: Having an answer to everything (or being overconfident) is a hard habit to break.

◊h3{A boring tech stack is nice, but you have to allow some scope for innovation if you don't want to stagnate.}
*** A boring tech stack is nice, but you have to allow some scope for innovation if you don't want to stagnate.

One idea is to set up an innovation budget◊^[2], but it's not the only one.

◊h3{PHP is a legitimate--if not /superior}--option to start a new project with and it deserves another chance./
*** PHP is a legitimate--if not /superior--option to start a new project with and it deserves another chance./

The language has matured spectacularly since 7.1 onwards.

◊h3{It's up to me as a software engineer to research ideas and proposals and judge them on merit, not anecdata.}
*** It's up to me as a software engineer to research ideas and proposals and judge them on merit, not anecdata.

I used to find things like Domain Driven Design (DDD) silly and enterprisey, because I used a poor implementation of it to judge the process itself.

◊h3{The cloud is not a foregone conclusion.}
*** The cloud is not a foregone conclusion.

You can still get a lot more bang for your buck with a VPS, and you'll learn something about systems administration too.

◊h3{QA is only a bottleneck when you treat the team as part of a deployment pipeline.}
*** QA is only a bottleneck when you treat the team as part of a deployment pipeline.

So many issues can be fixed at the design phase, before a line of code is even written, if you involve your QA engineers.

◊h3{Not every people problem can be solved with technology.}
*** Not every people problem can be solved with technology.

Automate everything away and you have no humanity left.

◊h3{My greatest learning moments came from maintenance programming and working with legacy code, rather than building new features.}
*** My greatest learning moments came from maintenance programming and working with legacy code, rather than building new features.

Debugging is a skill, fixing bugs is a skill, and the depth of your domain knowledge will be limited if you don't know how to do it well.

◊h3{When talking about User Experience, your users aren't just your paying customers, they're your support team and your developers.}
*** When talking about User Experience, your users aren't just your paying customers, they're your support team and your developers.

Dedicating some resources to internal productivity can do wonders for your team, which eventually leads to increased user satisfaction.

◊h3{Technology isn't invalidated by its age, it is strengthened by it.}
*** Technology isn't invalidated by its age, it is strengthened by it.

I occasionally hear people saying things like people don't use Rails any more because it's old and serverless or some shit is the hype. Don't use hype as the foundation for your business, use stability.

◊h3{You can write much better code if you don't micro-manage the structure of it; be judicious with your linters and formatters.}
*** You can write much better code if you don't micro-manage the structure of it; be judicious with your linters and formatters.

Setting limits on things like function length or class length sounds ideal, but these kind of linters are ultimately shaping your code through blunt force and, possibly more often than not, making it worse by enforcing needless indirection.

◊h3{If it's in a pull request (PR) it might already be too late to change course.}
*** If it's in a pull request (PR) it might already be too late to change course.

The sort of feedback you can give in a pull request is not of the same quality you can get with a conversation held before committing code.

◊h3{It's better when I'm not sentimental about the code I write or the ideas I present.}
*** It's better when I'm not sentimental about the code I write or the ideas I present.

Rejection isn't always so easy to handle, but there's always another time and a 'no' is still better than not being acknowledged at all. It's a great opportunity for constructive feedback and learning.


M posts/time-travel.org => posts/time-travel.org +4 -4
@@ 18,7 18,7 @@ So, I've been binging all the music I used to listen to as a kid that now makes 

Continue reading if you'd like to join me on a musical trip down memory lane.

◊h2{Grizzly Bear - Veckatimest (2009)}
** Grizzly Bear - Veckatimest (2009)

/Two Weeks/ was arguably the hit single from Grizzly Bear's sophomore record and it got major play time on XFM and BBC Radio 6. I would eventually get massively into this band and see them play live in Leeds, but that's not what I remember so vividly.



@@ 32,7 32,7 @@ This was probably one of the first times I really embraced spontaneity and went 

Oh to be ignorant.

◊h2{Arctic Monkeys - AM (2013)}
** Arctic Monkeys - AM (2013)

I was hooked by the Arctic Monkeys as soon as I heard their first single, /I Bet That You Look Good On The Dancefloor}, a little bit before they released their debut album in 2006. I can still put on ◊em{Whatever People Say I Am, That's What I'm Not/ and recite the lyrics from heart, as I'd sing along with it in the car so much when driving home from sixth-form, or from meeting friends further up in Lancashire.



@@ 42,7 42,7 @@ I've always enjoyed riding the DLR over using the Tube or traditional trains, an

It was also the time I worked at an agency called New Bamboo, which was my first job in London and still my favourite. My best friend and I connected quite a bit over this album.

◊h2{Milky Chance - Blossom (2017)}
** Milky Chance - Blossom (2017)

Blossom was released while I was living in and working remotely from Jūrmala, Latvia. I had an appointment to get my hair cut in Rīga, which was about 20-30 minutes away on the train depending on the timetable that day.



@@ 58,7 58,7 @@ Returning the the music, I returned to the beach that same day and worked quite 

I miss that feeling.

◊h2{The Killers - Hot Fuss (2004)}
** The Killers - Hot Fuss (2004)

/Hot Fuss/ was the first album I ever bought with my own money. It's hard to point to one specific moment for this, but it takes me right back to my teenage years.


M posts/using-ruby-c-in-ruby.org => posts/using-ruby-c-in-ruby.org +1 -1
@@ 77,7 77,7 @@ Now we have all of the ingredients to make the actual call, which syntactically 

Run it again a few times, and with different strings. If you're feeling experimental, attach more functions in ~LibRuby~ and see what else you can print out! Ruby's extension documentation should be a good place to start◊^[3].

◊h3{So, why disable the GC?}
*** So, why disable the GC?

For every step in this post up to creating a ~String~ object, we've been using function bindings and global variables. Global variables and constants won't be garbage collected, because the global scope will always maintain a reference to them; besides which, it would be quite bad if your classes and modules suddenly disappeared after a GC pass.