← Back to Kevin's newslettersPublished: 2018 Jul 1

Hi friends,

Stop Slacking

While we were traveling around New Zealand in a campervan, my girlfriend Nicki was on retainer with a company that communicated exclusively via Slack. Slack isn’t exactly usable on spotty rural cellular connections, so we built a service that bridges Slack with email. The service sends you an email whenever you’re mentioned or directly messaged, and your email reply gets posted back in Slack — you never have to open up the Slack app!

Call me old fashioned, but I’ll take email over GIF-filled real-time chat any day, regardless of my Internet connection speed.

Read my product design writeup, Nicki’s writeup, or just try it out yourself: stopslacking.com (I cannot believe this domain name was available!)

Watch Kevin Code!

Lately I’ve been trying to improve my ability to speak off the cuff while coding.

I’ve been practicing by recording myself and reviewing the tape to discover bad habits. This has been enormously helpful — not just for discovering and eliminating annoying verbal tics, but also because speaking out loud has helped me be more deliberate in my problem solving.

If you want to watch me stumble around in C, you can check out my practice videos and notes.

If you’re more interested in watching me code a realistic project, see adding image support to Clojure backend of Sketch.systems.

Not sure if these are useful or interesting at all — if you think so, let me know and I may record more videos and/or do a Twitch stream or something.

Solving brain teasers with Alloy

Last October I mentioned on the newsletter getting into TLA+. Since then, I’ve also gotten into Alloy, which I’ve found to be simpler and easier to get on with. (It automatically draws pictures!)

I’ve been learning Alloy by modeling and solving job interview brain teasers. For example, the water pouring puzzle: “Given 3 and 5 quart jugs, how can you measure 4 quarts?”

What’s neat about Alloy is that it lets you express relationships as predicates and facts, and Alloy handles the boring part of searching through all of the possible cases.

For example, this predicate relates two states, s and s', with the latter state created by pouring the 3 quart jug into the 5 quart jug:

pred Pour3To5(s, s': State){
  some x: Int {
    s'.fiveJug = plus[s.fiveJug, x]
    and s'.threeJug = minus[s.threeJug, x]
    and (s'.fiveJug = 5 or s'.threeJug = 0)

This fact expresses all of the things you can do with the jugs (fill, empty, or pour from one to the other):

fact Next {
  all s: State, s': s.next {
    Fill[s, s']
    or Pour3To5[s, s']
    or Pour5To3[s, s']
    or Empty[s, s']

To find the solution, you assert that it doesn’t exist and Alloy will show you wrong:

assert solution {
  no s: State | s.fiveJug = 4

(Read the pipe as “such that” rather than “or”.)

Anyway, you can check out my full solution if you want, but it’d be more fun if you tried to implement it yourself first!


Since the last newsletter, I also wrote about using websockets in Rust and how Finda coordinates with your browsers and editors.

That’s it for now! As usual, just reply to this email if you want to grab a coffee or nearby-time-zone Skype — I’m always happy to chat about your projects, work, consulting advice, etc.