jump to main content

2022 Retrospective

Attention Conservation Notice

A personal retrospective for 2022. You probably won't be exposed to anything new here. This is mostly for me to reflect on the past year and to reason about how I want to approach 2023

Overview of Goals for the Year

Each year I write out a list of goals to achieve in the coming year. Here is what was written out for 2022 (at the end of 2021).

Goal Type of Goal Progress Made
Finish 4 Quantitative Finance Books Computer Science + Mathematics ~ 7/4 books
Do 150 leetcode problems Computer Science 101 / 150
Finish Concepts, Techniques, and Models of Computer Programming Computer Science Not started
Finish chapters 8 - 14 of Apostol's Calculus Mathematics 2 / 7 chapters
Read 5 chapters of Elements of Statistical Learning Mathematics Not started
Finish syntorial Music Completed
Finish 80 pages of Keyboard Method Music ~60/80
Workout 100 times Exercise 91 yoga + 102 powerlifting
Read Dune Leisure 93/794
Read The Art of Doing Science and Engineering Leisure Completed
Listen to / read 25 non-textbooks Leisure 15/25

How did I do on the prescribed goals?

Finish 4 Quantitative Finance Books

This goal turned out the be the most passion-driven goal of the bunch. Here are the books that were read:

  • Introduction to Quantitative Finance by Stephen Blyth
  • Python for Finance by Yves Hilpisch
  • Financial Theory by Yves Hilpisch
  • Rule-Based Investing by Chiente Hsu
  • Algorithmic Trading in Python by Yves Hilpisch

I also ended up reading a textbook on macroeconomics:

  • Macroeconomics by Olivier Blanchard

Most of (~70%) a microeconomics textbook:

  • Microeconomics by Jeffrey Perloff

I grabbed these two econ books from the MIT introductory courses for econ majors. The math wasn't too bad, but I can see how hairy it could get down the line.

Most of (~80%) a book on asset management

  • Practitioner's Guide to Asset Allocation

quant books

My favorite of the bunch was Introduction to Quantitative Finance, followed by Python for Finance. Most of the books were heavy on options, but this could just be because I had a concentration of books by a single author. I'm thinking that finance is a very large field, and it would be good to understand more sub-industries outside of derivatives/options in the future.

Do 150 leetcode problems

This was born out of my discovery that leetcode offered Racket as a programming language that could be used. The problems themselves were fun and I enjoyed the challenges. Some problems proved too frustrating to bother since Racket makes it difficult to mutate data structures (by design!) and leetcode problems were likely designed with something like C++/Java/Python in mind.

Overall I liked doing the problems, but I don't have a terribly strong interest in competitive programming currently so I may try something else as an outlet to get me to write more lisp in my free time.

At the end of the year, I also ended up doing 10 Advent of Code problems in racket. This was more exciting since I was able to use community packages which included the excellent threading and megaparsack packages. I'm not thinking that AoC is a good replacement as a quick problem/puzzle generator though, maybe a mix of various sources (LC, AoC, Project Euler, Rosetta Code, and some larger scale projects) would be a better tactic going forward.

If you haven't seen racket code, here is AoC 2022 Day 7 with the use of parser combinators from megaparsack and threading macros:

#lang racket
(require racket advent-of-code threading
         megaparsack megaparsack/text data/monad data/applicative)

(define cmd-history (fetch-aoc-input (find-session) 2022 7))

;; parse commands
;; $ cmd cmd-args -> ('CMD (cmd cmd-args))
(define cmd-arg/p
  (do [initializer <- (char/p #\$)]
      [spacing <- space/p]
      [operator <- (many/p letter/p)]
      [cmd-space <- space/p]
      [operand <- (many/p any-char/p)]
      (pure (list 'CMD (map list->string (list operator operand))))))

;; $ cmd -> ('CMD cmd)
(define cmd-no-arg/p
  (do [initializer <- (char/p #\$)]
      [spacing <- space/p]
      [operator <- (many/p letter/p)]
      (pure (cons 'CMD (map list->string (list operator))))))

;; parse directory output
;; dir a -> ('DIR dir)
(define directory-name/p
  (do [dir-init <- (string/p "dir")]
      [spacing <- space/p]
      [dir-name <- (many/p letter/p)]
      (pure (cons 'DIR (~> dir-name list->string list)))))

;; file-size file-name -> ('FILE file-name file-size)
(define file-info/p
  (do [file-size-int <- integer/p]
      [spacing <- space/p]
      [file-name <- (many/p (or/p letter/p (char/p #\.)))]
      (pure (cons 'FILE (list (list->string file-name) file-size-int)))))

;; tries applying all the different parsers
(define (parse-input input)
    (apply or/p
           (map (λ (p) (try/p p))
                (list cmd-arg/p cmd-no-arg/p directory-name/p file-info/p)))

;; get list of inputs in parsed format
(define cmds (map parse-input (string-split cmd-history "\n")))

;; create files
;; set starting location
(current-directory "~/Documents/aoc22/")

;; make temp dir and switch to it
(make-directory (build-path (current-directory) "temp"))
(current-directory (build-path (current-directory) "temp"))

;; make file with a given size in bytes
(define (make-file-with-size fname fsize)
  (system (format "truncate -s ~a ~a" fsize fname)))

(define (dir-exists-else-create dir-path [switch-to #f])
  (if (directory-exists? dir-path)
      (current-directory dir-path)
      (if switch-to
            (make-directory dir-path)
            (current-directory dir-path))
          (make-directory dir-path))))

(define (file-exists-else-create file-path file-byte-size)
  (if (file-exists? file-path)
      (make-file-with-size (~> file-path
                               path->string) file-byte-size)))

(define (execute-command command)
  (let* ([cmd-type (first command)]
         [cmd-args (rest command)]
         [first-arg (first cmd-args)]
         [base-path ((curry build-path) (current-directory))])
  (cond [(equal? cmd-type 'CMD)
         (if (string? first-arg)  ;; ls, do nothing
             (let ([dir-name (cadar cmd-args)]) ;; operand
               (cond [(equal? dir-name "/") #t]
                     [(equal? dir-name "..") (current-directory (build-path 'up))]
                     [else (dir-exists-else-create (base-path dir-name))])))]
        [(equal? cmd-type 'DIR)
         (let ([dir-name (first cmd-args)])
           (dir-exists-else-create (base-path dir-name)))]
        [(equal? cmd-type 'FILE)
         (file-exists-else-create (base-path first-arg) (second cmd-args))]
        [else #f])))

;; create file structure
(for-each execute-command cmds)

;; part 1
;; get size of a directory
(define (directory-size directory)
  (~>> directory
       (find-files identity)
       (filter file-exists?)
       (map file-size)
       (foldl + 0)))

(define directory-sizes
  (~>> (find-files identity)
       (filter directory-exists?)
       (map directory-size)))

(~>> directory-sizes
     (filter (λ (s) (< s 100000)))
     (foldl + 0))

;; part 2
(define space-remaining
  (let ([total-space 70000000])
    (- total-space (directory-size (current-directory)))))

(~>> directory-sizes
     (filter (λ (s) (> s (- 30000000 space-remaining))))
     (apply min))


Syntorial is a synthesizer learning tutorial. It consists of 33 modules, which each include video instruction and ear training exercises. As they progress, each module gets a bit harder. Furthermore, there are group challenges that make you recreate sounds that use many different aspects of a synthesizer together. As a result, as you get further along the groups grow tremendously in difficulty.

This took me about 11 months, but I wasn't too consistent. I did roughly 2 modules a month on average, with a bunch up front and many fewer per month in the end. I believe this greatly increased my knowledge of sound design and my ability to listen and recognize how a sound is created by a synthesizer. I liked it so much that I will be doing their follow-up product next year.

workout 100 times

This one I roughly doubled (193/100). When I wrote this (at the end of 2021), I had a very persistent shoulder problem. As a result, I ended up doing yoga very consistently for the first half of the year (up to July) and never did any weightlifting.

For the second half of the year, I found a local powerlifting coach and gym and signed up. I still had shoulder issues, but working with a knowledgeable coach and consistently lifting again strengthened the shoulder and lead to a lot of fun. I plan on continuing my powerlifting training next year.

Outside the goals

So in total, I officially finished 4/11 of my initially planned out goals. That is <50%, so not too great. Looking back, I think that the goals varied widely in difficulty and there are likely too many of them. Some of them could have been rolled into others. Read Dune + The Art of Doing Science and Engineering could have been rolled into Listen to / read 20 non-textbooks. Syntorial and finishing 80 pages of the keyboard method could have been rolled into a meta-synthesizer goal.

I also think that a lot changes over a year, and my goals laid out before new years may not hold well throughout the entire course of the year. As an example, I did not feel like grinding through Apostol's Calculus after a couple of months of it. The problem sets take quite a long time, and I was really more interested in Quant and Computer study at the time.


Most importantly, I think that when interest hits it is a good idea to ride the wave of it and put the momentum to use. When setting rigid schedules beforehand, it can be easy to miss opportunities. In the explore exploit paradigm, our goals are usually "exploit", but "explore" is also necessary to avoid local minima.

Here are some of the things that I explored throughout the year that weren't related to my initial goals:

  • the Racket macro system
  • building a desktop computer
  • running a Dungeons & Dragons campaign as the GM
    • running Out of the Abyss
  • GuixSD
    • So far this is my dream distribution
  • set up and used StumpWM for most of the year
    • may switch back to EXWM
  • creating a blog (thanks for reading)
    • and writing posts for it!
  • Learning to use the Kinesis Advantage360 and rewriting all my key-bindings and macros
  • working through synthesizer patch books
  • building an automated FX trading bot
    • and stopping it :D
  • full stack development with react + nodejs
  • building a newsletter generator based on org-mode
  • building a web application with react and nodejs for wish lists

These things were all great fun and will color how I choose to design my goals for 2023.


This year also marks a new piece of my productivity framework. I have tracked what I did with a very simple kanban board.

It looks like this:


When I want to get something done, I add it to the To Do section. When it is being worked on it is in the In Progress section. When completed, it moves to the Done section. Around March I started adding dates when I added a task to the board in the right-most column:


This has been useful in 2 ways:

  • it gives me a visual indicator of what I am currently doing and what I have been doing. It also helped me go back and make sense of things that I did this year that are not on the goals list.
  • it reminds me to go back and clean up any leftover things (or ignore them as I did with the Interconnectivity Patch Sheet 3 in the first screenshot)

It's really easy to maintain and manipulate since it is just an org mode table. It probably doesn't conform completely to a lot of kanban systems, but it is just for me and I've found it easy to integrate into the rest of my record-keeping / personal productivity system without much added complexity.

Comments & Critique

After writing this up, here are some thoughts that jump out to me:

  • I think I need to make a refinement for my goals in 2023. 11 is too many. An idea could be to have 1 big goal for each type of action (computer science, mathematics, music, exercise), make them a bit more abstract then write out sub-plans to flesh the bigger goals out a bit.
  • Some goals can be better managed by an external professional. This year I tried out a strength coach and it has been tremendously helpful. Maybe I will try getting a music teacher or a math tutor.
  • For really large, sprawling goals like computer science / mathematics without a clear description of done, it might be good to trade off years with explore and years with exploit. Maybe one year I can dig deep into a sub-field, and the next year touch on several new places that I haven't been before.
  • Community plays a large role in shaping the way we experience the things that we choose to do. It is easier for me to learn something if I have a way to apply and reinforce what I am learning. To do this, when choosing goals I should add a social outlet to them. For example, if I decide to go deeper with Racket, I should be more active on the racket discord and attend meet-ups. If I dig further into quantitative finance, I should find meet-ups and industry gatherings and follow them. If I start making music in a specific sub-genre, I should make friends with people doing what I am trying to achieve and seek feedback. Nothing we human beans do is in a vacuum.

▽ Comments