Sign in

Heath

@heathhenley.dev
332 followers 1.7K following 489 posts

Señor Application Engineer at a small sonar shop. Writing about things here: heathhenley.dev

PostsRepliesMedia
Heath @heathhenley.dev · 26/08/2026
Cleaning out our office at work, we’re moving down the road - found these relics
Physical boxes for win7 and visual studio upgrades
030
Heath @heathhenley.dev · 25/05/2026
That’s one way to lighten up text book a bit…
Screenshot from math textbook, with inset quote from the opening paragraph of Alice’s Adventures  in wonderland: “…what is the use of a book…without pictures or conversation”
010
Heath @heathhenley.dev · 24/05/2026
If you've seen the Numberphile video about the red/black knight game on the spiral board making cool patterns (like the pic below) I made a little tool to explore them: heathhenley.dev/knight-spira...
An image made by places red / blue knights on a spiral grid. Each knight is placed in turn on the lowest spiral index available to it (not being attacked by the opposite color)
100
Heath @heathhenley.dev · 01/01/2026
If you asked me to guess what my most productive day was in 2025 (in terms of commits) I would never have guessed Monday! 🤯 My year in: - Books: www.goodreads.com/user/year_in... - Code: git-wrapped.com/profiles/Hea... (source of this image) - Everything else: heathhenley.dev/posts/2025-s...
Summary of github stats for 2025
000
Heath @heathhenley.dev · 23/12/2025
Here we go! Took a long break again, been mostly donating to the climbing gym every month - but definitely missed it.
Climbing shoes and chalk bag
030
Heath @heathhenley.dev · 17/11/2025
I don't buy it
Screenshot of github - "this repository has no secrets"
010
Heath @heathhenley.dev · 28/08/2025
Sometimes privacy is too much to ask for
Screenshot of a web browser showing an error response of: “Cannot GET /privacy” at the cnnespanol.cnn.com/privacy route
020
Heath @heathhenley.dev · 01/05/2025
I'm a little embarrassed to say which key is mapped to backspace lol
Keyboard heatmap indicating the number of times each key is used - red is more frequent, blue is less
020
Heath @heathhenley.dev · 17/04/2025
Kind of cool - these are going to be syntax warnings in Python 3.14 (and eventually errors) - same with continue / break in finally too I don't think I've ever got bit by this but looking at it I'm not sure how
``` python
def test_raise():
  try:
    raise ValueError
  finally:
    return 0

def test_return():
  try:
    return 1
  finally:
    return 0

print(test_raise()) # --> 0
print(test_return()) # --> 0
```
100
Heath @heathhenley.dev · 14/04/2025
Favorite language lacking tail call optimization? Just hack it in using exceptions...
Python snippet

```python

class TailRecurseException(Exception):
  def __init__(self, *args, **kwargs):
    self.args = args
    self.kwargs = kwargs

def tco(func):
  def func_tail(*args, **kwargs):
    while True:
      try:
        return func(*args, **kwargs)
      except TailRecurseException as e:
        args = e.args
        kwargs = e.kwargs
  return func_tail

@tco
def fib_tco(n, a=0, b=1):
  if n == 0:
    return a
  raise TailRecurseException(n-1, a=b, b=a+b)


def fib_tail(n, a=0, b=1):
  if n == 0:
    return a
  return fib_tail(n-1, b, a+b)


# no tco
fib_tail(1000) # --> ❌ RecursionError

# tco
fib_tco(1000) # --> ✅


# Heavily inspired by:
# - http://baruchel.github.io/python/2013/12/03/tail-recursion-in-python/
# - https://github.com/baruchel/tco

```
100
Heath @heathhenley.dev · 04/04/2025
The slow climb back to my normal typing speed with new keyboard layout (including minor set backs for adjustments along the way)
WPM before and after new keyboard layout
000
Heath @heathhenley.dev · 21/03/2025
What do you guys think of pear programming?
An AI generated pear wearing a hoody and sunglasses programming
010
Heath @heathhenley.dev · 28/02/2025
This leading slash caused me so much confusion yesterday:
screenshot of the following in the python repl

```python
import os
os.path.join(r"c:\dev\test", r"\test_dir\test_file.xyz")
# c:\\test_dir\test_file.xyz
```
000
Heath @heathhenley.dev · 26/02/2025
Now that's some cursed python!
A screenshot of a snippit of python code in the style of ocaml

```python

# based on ocaml implementation:
# by: http://typeocaml.com/2015/05/05/permutation/
def insert_all_positions[T](x: T, lst: list[T]) -> list[list[T]]:
  def inner(prev, results, orig_lst):
    match orig_lst:
      case []:
        return [(prev + [x])] + results
      case [first, *rest]:
        return inner(prev + [first], [(prev + [x] + orig_lst)] + results, rest)
  return inner([], [], lst)


def permutations_full_recursive[T](
    lst: list[T], r: int | None = None) -> Generator[list[T]]:
 
  r = len(lst) if r is None else r
  if r == 0:
    yield []
    return
  if not lst or r > len(lst):
    return

  match lst:
    case [x] if r == 1:
      yield [x]
    case [first, *rest]:
      # permutations of size r with first in them
      yield from reduce(
        lambda acc, p: acc + insert_all_positions(first, p),
        permutations_full_recursive(rest, r - 1),
        []
      )
      # permutations of size without first in them
      yield from permutations_full_recursive(rest, r)
```
110
Heath @heathhenley.dev · 14/02/2025
The cl docs for google cloud kms key create have a nod to LOTR
The output of gcloud kms keys create --help - normal command line documentation of the arguments and options. Lord of the Rings characters are used as dummy key names in the usage examples.
020
Heath @heathhenley.dev · 13/02/2025
I started using git log but with --graph, --oneline, and --pretty formatting: ``` git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --all ``` I just set up an alias for it trying this instead of gitk'ing all the time like a lunatic
Output of git log on a public git repo with more formatting applied so that you get similar output to the gui program gitk - one commit per line with author, msg, and time. Pipe and dash symbols show how commits are connected / how branches connect.
000
Heath @heathhenley.dev · 09/02/2025
Caught in the snow in NYC last night! ❄️
A bunch of strangers in the snow in Times Square in NYC
000
Heath @heathhenley.dev · 03/02/2025
you can see when I went on vacation and that I prioritize going outside to touch grass (actually rocks more likely) in the summer lol
A github contribution graph - fewer contributions during the weekends in the summer and clear chunks of no contributions
010
Heath @heathhenley.dev · 02/02/2025
If you want a hint
Results from running the code in utop on the list 1, 2, 3 with the map function (fun l a -> (l, a + 1)) - it should return the ([1; 2; 3], 3) but it returns ([1; 2; 3], 0)
000
Heath @heathhenley.dev · 02/02/2025
Anyone see the bug this ocaml n00b just wasted too much time on debugging? 🤦‍♂️
Ocaml code to map and fold a function over a list at the same time:

```ocaml
let map_and_fold ~f ~init lst =
  let acc_ref = ref init in
  let[@tail_mod_cons] rec go = function
    | [] -> []
    | hd :: tl ->
        let b, new_acc = f hd !acc_ref in
        acc_ref := new_acc;
        b :: go tl
  in
  (go lst, !acc_ref)
```
100
Heath @heathhenley.dev · 29/01/2025
TIL that since Python 3.11 you can use an ansyncio.TaskGroup with a context manager - pretty cool! Good examples in the docs: docs.python.org/3/library/as...
The displays the following python code snippet:

```python
# https://docs.python.org/3/library/asyncio-task.html#coroutine
import asyncio
import time


async def fetch_data():
  	print("start fetch_data")
    await asyncio.sleep(1)
    print("end fetch_data")
	
async def my_task():
    print("start my_task")
    await asyncio.sleep(2)
    print("end my_task")

# if you have >= 3.11 - you can use a context manager
async def main():
    async with asyncio.TaskGroup() as tg:
        task1 = tg.create_task(fetch_data())
        task2 = tg.create_task(my_task())
        print(f"started at {time.strftime('%X')}")
    # The await is implicit when the context manager exits.
    print(f"finished at {time.strftime('%X')}")
    
asyncio.run(main())
```
011
Heath @heathhenley.dev · 09/01/2025
Recently reread "If on a winter's night a traveler" by Italo Calvino - super meta about reading in itself, I appreciated it a whole lot more this time around. The reader/you begins reading a novel and it's cut off just when it starts to get good - you find the rest but it's the wrong novel... 💙📚
The cover of the book: "If on a winter's night a traveler" by Italo Calvino
030
Heath @heathhenley.dev · 25/11/2024
Just finished this short read - super interesting concept - they are in a hell comprised of a library containing all possible books and need find the one about their life to get out 📚💙
020
Heath @heathhenley.dev · 20/11/2024
More old advent of code problems for funsies - this one is turned out to be a modified Conway's game of life - used minttea to display it in ocaml 🐫 - such a cool little framework! github.com/heathhenley/...
2223
Heath @heathhenley.dev · 17/11/2024
I hope the magic dwarves are being well compensated
Screenshot for WIP blog section: "Magic dwarfs are working really hard on this section!"
110
Heath @heathhenley.dev · 17/11/2024
So I shouldn't be using recursion over loops, or I should? "... use explicit while loops when possible." Does that mean when it's too complicated to determine if it's tail recursive, just use a while loop to be safe? Otherwise this feels like the opposite of the FP vibe ocaml.org/docs/loops-r...
What did we really learn here?

One thing is that recursive functions have a dangerous trap for inexperienced programmers. Your function can appear to work for small inputs (during testing), but then fail catastrophically in the field when exposed to large inputs. This is one argument against using recursive functions; instead, use explicit while loops when possible.
021
Heath @heathhenley.dev · 17/11/2024
Here's the refactor based on the suggestions I got. Thanks to @kirancodes.me and @welltypedwit.ch 🙏! (and @sabine.sh for the share that probably go people to help 🙂) Full thing here: github.com/heathhenley/...
Refactored ocaml function for advent of code day 21, using the suggestions from the replies to the quoted post. The code is: 

```ocaml
let min_cost_to_win boss player =
  let memo = Hashtbl.create 10000 in
  let rec min_cost current s =
    match Hashtbl.find_opt memo s with
    | Some v ->  v
    | None ->
      let current_cost = 
        if player_will_win boss player s
        then get_cost_of_gear s
        else current
      in
      let neighbor_costs = List.map (min_cost current_cost) (neighbors s) in
      let best_cost =
        List.fold_left (fun acc x -> min acc x) current_cost neighbor_costs
      in Hashtbl.add memo s best_cost;
  best_cost in 
  min_cost max_int initialGearState
```
171
Heath @heathhenley.dev · 16/11/2024
Anyone up for constructively (or not) roasting my 🐪? I'm an Ocaml and FP newb in general It's an old advent of code problem (day 21 from 2015) - full code is here: github.com/heathhenley/... Problem is: adventofcode.com/2015/day/21
Screenshot of a solution to 2015 problem 21 advent of code in ocaml
361
Heath @heathhenley.dev · 15/11/2024
A white fluffy cat laying on the floor
2262
Heath @heathhenley.dev · 14/11/2024
This is fun way to make sure that everyone who follows your docs doesn't end up using the same value:
screen shot from documentation - to avoid everyone following docs and choosing the same time to schedule a reoccurring task, a random minute is selected
000
Heath @heathhenley.dev · 12/11/2024
that makes sense - I first saw them with yojson, I needed to match against the properties of the a json file. Thought I was going to be out of luck because no runtime type checks, but it's a polymorphic variant so it was straightforward to check against the tag for object, list, string, int, etc
ocaml to walk a json file and add up any numbers - for aoc problem 12 from 2015
320
Heath @heathhenley.dev · 12/11/2024
Anyone good at chrome extensions / styling want to hack on this with me? I realize it's going to be a giant waste of time once they ship bookmarks, but I've never worked on an extension before so it's kind of cool github.com/heathhenley/...
a screenshot of bluesky cats feed but with a bookmark button added to the ui to save posts locally
000
Heath @heathhenley.dev · 08/11/2024
Baby's first ocaml! 🐪 Look at how cute it is lol Decided I'll try to do a few of the old Advent of Code problems to learn some FP. It's crazy something that took a few minutes in the imperative way atm takes sooo much longer just to wrap my head around in fp...
4273
Heath @heathhenley.dev · 07/11/2024
I heard #cat pics are a thing here - this is Catniss, she likes bags a lot
011
Heath @heathhenley.dev · 06/11/2024
Ok bloomer
020
Heath @heathhenley.dev · 05/11/2024
Done! ✅ Now I guess we deserve whatever we get
010
Heath @heathhenley.dev · 02/11/2024
My lemon tree has flowers coming in!
020
Heath @heathhenley.dev · 24/10/2024
Obsidian doing their part to make sure no users get stuck in vim mode
030