Switch Feels

I’ve always had a thing for mechanical keyboards, but one of my good friends has been slowly bringing me down to his level of obsession.

Currently, I own a Corsair K70 (Cherry MX Blues) and a Noppoo Lolita Spyder 87 (Kailh Browns). At work, I was lucky enough to be lent a Happy Hacking Keyboard. I also have an order in for a KBD75 (Zealio 67gs).

So, I’m still at the very tip of the iceberg when it comes to this hobby. And what did I do? I ordered a 25-switch testing board, just so I can see how far down the rabbit hole I’m willing to go.


25 Switch Tester
I’ve labeled the switches and their respective placement on the board:

Cherry MX Blue Cherry MX Brown Cherry MX Black Cherry MX Red Cherry MX Clear
Cherry MX Green Cherry MX Silent Black Gateron Black Gateron Red Gateron Green
Gateron Blue Gateron Brown Kailh Bronze MOD-L Tactile MOD-M Tactile
MOD-H Tactile MOD-L Linear MOD-M Linear MOD-H Linear Zealio 62g
Zealio 65g Zealio 67g Gatistotle 80g Spring Invyr Panda Jailhouse Cherry Blue



The choice in switches resulted from a desire to have a good standard of comparison, rather than simply picking up a bunch of exotic switches… though I will admit some I just had to get for funsies.

Anyway, here are some of my thoughts on each. It’s not really meant to be a potential buyers guide, nor an indepth review of each switch. Just how my dumb fingers felt while pressing them!

Cherry MX Blue:

This is generally my go-to switch. You just can’t go wrong with that super tactile, clicky goodness!

Cherry MX Brown:

Browns are the blues for people who want to keep their job. You still feel a slight bump, but don’t get that deafening clack.

Cherry MX Black

I’m not really a fan of linear switches, but I do appreciate how blacks feel. The stiffness means that doesn’t feel mushy like a red.

Cherry MX Red

Honestly, do not enjoy reds at all. It feels too “empty” for me. The lack of stiffness and no feedback makes it very hard for my fingers to actually register that they’re pressing a key.

Cherry MX Clear

Wow! These feel really good. Putting weight behind the brown makes a good switch great. I’d like to try a full typing setup with them though.

Cherry MX Green

Okay, I’ve never tried a green before this and I’m really upset that I haven’t. Of the Cherry MX switches I’ve tried, this is now my favorite. It’s simply a better blue.

Cherry MX Silent Black

I heard this switch was interesting, but I really don’t see it. It feels like a slightly mushier black.

Gateron Black

Obviously similar to the Cherry MX Black. This feels smooth and it has some resistance. I actually kinda like it.

Gateron Red

Yeah, I don’t like this switch at ALL. The same problem as the red, but it somehow feels even less present.

Gateron Green

Huh! A green with an even sharper bump. Even better! But by God is it loud.

Gateron Blue

I’m really digging the bump on these Gaterons. Nicer than Cherry MX blue, but I still prefer greens.

Gateron Brown

Huh, I thought I’d like this more than the Cherry MX browns, but I actually don’t. It feels more “damp” to me, if that makes sense?

Kailh Bronze

I got this because I was told it had a two-way tactile bump. It’s really gimmicky and I don’t enjoy pressing it. This is probably the loudest switch by far.

MOD-L Tactile

Similar to a brown, but the tactile bump feels “all at once.” I really don’t have a better way to describe it!

MOD-M Tactile:

Identical to the light version, but slightly stiffer. Quite pleasant!

MOD-H Tactile

Same as the previous two, but even stiffer. Pretty much a clear.

MOD-L Linear

As you might have guessed, I really don’t enjoy it.

MOD-M Linear

A little stiffer, a little better! I could see myself using these with only a few grumbles.

MOD-H Linear

Muuuuuch better. Not my ideal, but it could do!

Zealio 62g

I’m a big fan of this distinct bump. If I had to pick between this and similar switches, I’d definitely lean towards this.

Zealio 65g

Wow, this is simply pleasant. It has just enough give to make it welcoming to a touch, but enough resistance to make you really feel that actuation.

Zealio 67g

Believe it or not, stiffer isn’t necessarily better. But I’m not saying it’s bad either– I like this only a little less than the 65g.

Gatistotle 80g Spring

You like clacks? This is it. It feels very good to actuate, with a very responsive feel and loud click.

Invyr Panda

Eh, wasn’t really feeling this one. One of the better linear switches, but still a far cry from some of the other switches in this list.

Jailhouse Cherry Blue

Alright, so this took me completely by surprise. I honestly downright love everything about how this feels.

So after playing with a bunch of these switches and trying to describe how they feel and what I like about them, I kinda realized my vocabulary for switch critique was kinda limited; there were certain experiences with specific switches that I didn’t have a word for. A good example of this is the tactile MODs, which had a very nice feeling after you hit the bump and actuate. This is something I want to work on a bit, because if it’s hard to talk about how they feel, it’s hard to communicate my opinions effectively.

As for which switches I liked the most, it came down to the stiffer tactile switches. My top five ended up being Gatistotle 80g Spring, Zealio 67g, Zealio 65g, Jailhouse Cherry Blue, and MOD-M Tactile. Notable mentions include MOD-H Linear, Gateron Green, and Cherry MX Clear. I don’t see this as a final ranking in my mind either. I think the real test would be actually getting some of these on a full board to have the full experience; it’s one thing to press a switch 100 times with your index finger, another to use it in your day to day and getting a feel for it.

As for where we go from here… one step at a time! My KBD75 ships by the end of the month and I absolutely cannot wait to get my hands on it. But until then, I think it’d be best to take a step back before I start soldering boards with all these cool switches on them.

Type Curious

So, one of my first assignments at Edlio was helping implement our new staff directory feature. It was super fun to work on and allowed me to really stretch my legs and explore a mostly unfamiliar codebase!

While the links above only show off the public side of things, a big part of this was providing a lot of customization options for our customers. Selecting which fields to display, how e-mail links should be handled, templating, et cetera. Of course, we also support different sorting and grouping options.

And here is where we get into the real topic of today’s post.

For the staff directory, we needed to represent both sorting and grouping as a single option. It’s all well and good when being fetched and processed, but when it comes to shipping it to FreeMarker, we had to do this:

if (order.isGrouping()) {
    final Collection<Pair<String, List<User>>> sortedStaff = order.sort(staff);
    data.put("staffList", sortedStaff);
} else {
    final Collection<ClassicUser> sortedStaff = order.sort(staff);
    data.put("staffList", sortedStaff);
}
data.put("isGrouping", order.isGrouping())


Yeah… not great.

The idea here is that every template needs to support both possible types of Collection (a list of users or a list of grouped users), while reusing most of the same infrastructure. Unfortunately, that means we gotta get a little messy on the backend.

We need to know exactly what we’re getting back before moving on– we can’t just leave it at Collection<?> and call it a day! A little bit annoying, but I get it. We can’t reasonably expect Java to accept any of two types for a declaration.

But, know what can? Ceylon, Red Hat’s homebrewed JVM language.

It supports a myriad of useful features (quite a few will be very familiar to Kotlin devs!), but we’re only concerned with union types for now.

(I want to apologize for my Ceylon beforehand!)

// Some SAM that can return EITHER a String or a Boolean
interface HasValue {
   shared formal String | Boolean get();
}

// Concrete implementation of HasValue that returns a Boolean
value booleanValue = object satisfies HasValue {
        get() => true;
};

// This implementation returns a String
value stringValue = object satisfies HasValue {
        get() => "string";
};

// Both foo and bar can expect either type!
String | Boolean foo = booleanValue.get();
String | Boolean bar = stringValue.get();


The basic idea here is that we can define methods that return any one type from a list of types. You can think of it as A OR B OR …, where A can be a sequence of Strings, B can be a sequence of tuples, so on and so forth.

Revisiting the staff directory hack, we could probably write something like this:

// Ceylon is ref immutable by default by the way!
User[] | [String, User][] sortedStaff = order.sort(staff)
data.put("staffList", sortedStaff);
data.put("isGrouping", order.isGrouping)


Obviously, I haven’t tested this in production, but it’s fun to think about! I’ve never really done a deep dive on type systems / theory, so I find this and intersection types deeply fascinating. Additionally, I coincidentally encountered an article on higher-rank and higher-kinded types while browsing the Rust subreddit. Strangely enough, it was written in a Java-esque fashion, but that actually helped me grasp the core concepts very easily.

As I explore these ideas, I’m wondering if more languages could benefit from such rich typing. It might seem a bit convoluted at first, but when you see them in action you get a sense of elegance and purpose. Maybe I should try programming in Ceylon for a month or so, it could be a fun little experiment!

New Job, New City, New Site

This past month, I took a job as a backend engineer at Edlio and moved to Los Angeles, all the way from Brooklyn. Whew.

Needless to say, this brought a lot of change into my life. And while it’s been a little rough adjusting, it’s been a good change overall!

I figured that if I was going to go through all these changes, so should my personal site. It used to be a simple résumé page with some (ugly) pictures, which wasn’t too exciting.

When thinking of what I should replace it with, I thought of Jonathan Blow’s blog. But unlike him, I don’t consider myself an authority on anything nor do I have as much to really say (which is why I find Twitter great). So… should I?

Eh, why not? I mean look, I have nice code snippets with ligature support:

// This is a simple translation of an example from
// the Jai "quick lambda" compiler demo

// This actually wouldn't compile as the compiler needs 
// explict type information
fun main(args: Array<String>) {
    doIt(10, ::squarePoly)
}

fun <T> doIt(x: T, func: (T) -> T) {
    print("Result is ${func(x)}")
}

fun <T> squarePoly(x: T): T {
    return x * x
}


Pretty nice right? In all seriousness, I expect to do a few write-ups as I grow and learn as an engineer, so this feature is pretty important. I wanted to be able to communicate my ideas clearly and effectively as they are demonstrated through not only prose, but code as well.

That being said, I don’t expect this to just be a programming blog. I want to write about things that interest me, even if they might seem mundane to others. Trying to communicate effectively is a big part of why I’m doing this. I often find it hard for me to thoroughly explain things and forcing myself to practice doing so is the first step to fixing that. Chris Poole, who is one of my biggest inspirations, wrote an excellent post on this very thing!

As weird as it sounds, I feel as though writing is an important part of being human. Literacy is part of what separates us from the rest of the animal kingdom, isn’t it?