I recently had to debug a whole bunch of code that manipuates pointers, so I
need to stare at random things like 0x7f7d6ab2c0c0, like so:
mkClosure_capture0_args0 (0x7f079ae2a0c0:) -> 0x556b95a23350:mkClosure_capture0_args0 (0x7f079ae2a0e0:) -> 0x556b95a3f3e0:mkClosure_capture0_args2 (0x7f079ae2a000:, 0x556b95a23350:, 0x556b95a3f3e0:) -> 0x556b95a232e0:evalClosure (0x556b95a232e0:) ⋮evalClosure (0x556b95a23350:) ⋮ ⋮mkConstructor1 (MkSimpleInt, 0x1) -> 0x556b9596c0b0: ⋮=>0x556b9596c0b0: ⋮isConstructorTagEq (0x556b9596c0b0:MkSimpleInt, MkSimpleInt) -> 1 ⋮extractConstructorArg 0 -> 0x1: ⋮evalClosure (0x556b95a3f3e0:) ⋮ ⋮mkConstructor1 (MkSimpleInt, 0x2) -> 0x556b95a23190: ⋮=>0x556b95a23190: ⋮isConstructorTagEq (0x556b95a23190:MkSimpleInt, MkSimpleInt) -> 1 ⋮extractConstructorArg 0 -> 0x2: ⋮mkConstructor1 (MkSimpleInt, 0x3) -> 0x556b95902a30:=>0x556b95902a30:I got annoyed because it's hard to spot differences across numbers. So I wrote a small '''algorithm''' that converts this into something pronounceable:
char *getPronouncableNum(size_t N) { const char *cs = "bcdfghjklmnpqrstvwxzy"; const char *vs = "aeiou"; size_t ncs = strlen(cs); size_t nvs = strlen(vs); char buf[1024]; char *out = buf; int i = 0; while(N > 0) { const size_t icur = N % (ncs * nvs); *out++ = cs[icur%ncs]; *out++ = vs[(icur/ncs) % nvs]; N /= ncs*nvs; if (N > 0 && !(++i % 2)) { *out++ = '-'; } } *out = 0; return strdup(buf);};which gives me the much more pleasant output:
mkClosure_capture0_args0 (0x7fbf49b6d0c0:cisi-jece-xecu-yu) -> 0x561c5f11f9d0:suje-zoni-ciho-komkClosure_capture0_args0 (0x7fbf49b6d0e0:qosi-jece-xecu-yu) -> 0x561c5f12f1b0:leda-guni-ciho-komkClosure_capture0_args2 (0x7fbf49b6d000:ziqi-jece-xecu-yu, 0x561c5f11f9d0:suje-zoni-ciho-ko, 0x561c5f12f1b0:leda-guni-ciho-ko) -> 0x561c5f11f960:kuhe-zoni-ciho-koevalClosure (0x561c5f11f960:kuhe-zoni-ciho-ko) ⋮evalClosure (0x561c5f11f9d0:suje-zoni-ciho-ko) ⋮ ⋮mkConstructor1 (MkSimpleInt, 0x1) -> 0x561c5f129c10:qifa-duni-ciho-ko ⋮=>0x561c5f129c10:qifa-duni-ciho-ko ⋮isConstructorTagEq (0x561c5f129c10:MkSimpleInt, MkSimpleInt) -> 1 ⋮extractConstructorArg 0 -> 0x1:ca ⋮evalClosure (0x561c5f12f1b0:leda-guni-ciho-ko) ⋮ ⋮mkConstructor1 (MkSimpleInt, 0x2) -> 0x561c5f120200:nuhi-zoni-ciho-ko ⋮=>0x561c5f120200:nuhi-zoni-ciho-ko ⋮isConstructorTagEq (0x561c5f120200:MkSimpleInt, MkSimpleInt) -> 1 ⋮extractConstructorArg 0 -> 0x2:da ⋮mkConstructor1 (MkSimpleInt, 0x3) -> 0x561c5f100010:kuqi-koni-ciho-ko=>0x561c5f100010:kuqi-koni-ciho-koThe strings of the form ziqi-jece-xecu-yu makes it way easier to see control flow.
I can also see if two pointers are close, based on shared suffixes: ciho-ko is
shared, which means the numbers are themselves close.
- It turns out there's a system called proquints that allows for such a thing already!