W11 - The beginner's mind

Functional programming

I've been watching a couple of Bret Victor videos recently. In this video, he mentioned how there was a lot of hostility towards assembly when it was first introduced. Assembly allowed machine code to be represented in words, for example writing `add $t1 $t2 $t3` to mean add values in $t2 and $t3 then place it into $t1, instead of say `0000 0001 0000 1001 0101 0000 0010 0001`.

Despite improving developer productivity and reducing likelihood of errors, those who had been programming in binary didn't see much value to assembly. This resistance to new ways of working, to unlearn what you've already learned and think in new ways, is present in 2020 as it was in the 1950s. If anything, it's a more concerning anti-pattern today given how much faster the world is changing.

This thought motivated me to look into category theory. Perhaps understanding more theoretical aspects could help illuminate why things were implemented the way they did. Perhaps doing so would highlight concepts that we take for granted. In last week's post, I mentioned consuming more of Bartosz Milewski's content. I thought I'd complete all three parts before starting Haskell. I'm almost done with Part 1, and then realized I want a bit more intuition on what applying the theory looks like.

Instead of more Haskell, I actually found Chet Corcospost on functional JavaScript super helpful. A pure function is a function where the return value is only determined by its input values, without dependencies or side effects. He describes how pure functions "bound the cognitive load of programming", because pure functions forces you to be concerned only with the body of the function.

A core concept in category theory is composition; the following is from the preface of Milewski's book.

Composition is at the very root of category theory - it’s part of the definition of the category itself. And I will argue strongly that composition is the essence of programming.

In Corcos' post, he emphasizes how writing code through composition of pure functions makes it much easier to trace errors - you'll get a stack trace through every function all the way to the source of the bug. This is in contrast to object-oriented programming, where the state of the object may not be exposed.

What's very cool is seeing how, in implementing a map operation of two successive functions on a list, the version applying a single map of the composition of the two functions is faster than the version applying two successive maps of each function individually! The sections on lazy loading (with similarly getting performance gains) are fascinating, though perhaps best described in the post itself.

Like all things in life, there's always trade-offs. Gabriel Gonzales' blog Haskell for All has an excellent post on how Haskell is better for long-term productivity because it enforces best practices. I first came across the Option type in Rust, perhaps this was inspired by Haskell's Maybe. In any case, this framing forces you to invest time at the start dealing with edge cases, as opposed to investing time later on when things break.

The post goes on to talk about the flip side of Haskell. I didn't realize Haskell implements its default String type as a linked list (perhaps a counter-example to those claiming linked lists only come up in interviews). While abstraction is a 'good thing', any good thing in excess is bad - Haskell makes advanced abstraction syntactically cheap and thus easy to get carried away. Amusingly there's even a Hitler parody for that...

Content: Naval Ravikant podcasts

There are a number of content formats I've collected but not enough for a series. I'll feature them this week.

First is podcasts. I enjoy listening to Naval Ravikant, the co-founder of AngelList but perhaps best known for his How to Get Rich series of tweets. On Samantha Ryan's podcast, his response to the question of how we decide what to do with our limited time (at 25:39) emphasizes the importance of being honest and effective.

It's very important to be honest with yourself so you can actually succeed without hurting yourself, without being in self conflict all the time and without being ineffective. Because if you're effective and you just get what you want, you can trade it for other things.

On Tim Ferrisspodcast, he elaborates a tweet in the series which talks about gaining financial freedom through ownership of equity. The discussion (at 31:22) echoes Bret Victor above, on the hard part of any endeavor is getting over one's resistance to change.

The hard parts are not the learning, it is the unlearning. It’s not the climbing up the mountain. It’s the going back down to the bottom of the mountain and starting over.

It’s the beginner’s mind that every great artist, or every great business person has, which is: you have to be willing to start from scratch. You have to be willing to hit reset and go back to zero. Because you have to realize that what you already know, and what you’re already doing, is actually an impediment to your full potential.

Content: Sam Altman talks

On the theme of inertia, I learned a lot at Square but I did go through a phase of feeling comfortable. Towards the end of that phase I realized that by not pushing harder I did a disservice to the company, and perhaps more importantly, I did a disservice to myself.

I thought a change of environment would be a good wake up call. I moved from the 3,000+ person company to a 30+ startup. To help prepare the transition I listened to a number of Y Combinator talks, in particular the ones with Sam Altman. This talk is from Work at a Startup Expo 2018 (at 16:20).

Every job I've ever had I've been wildly unqualified for, and doing that is the #1 secret to having a really great career. That's the way you have a super fast rate of personal growth, and I think the way careers go is you should put in the most of the effort at the beginning. Because it's this compound interest-like thing, where the work you do now, the learning the you do now, the improvement you make early in your career gets to pay off for all the rest.

The talk from How to Succeed with a Startup discusses staying positive as a team, stepping up and a bias towards action (at 8:17).

The spirit of "we'll figure it out" is my favorite thing to hear among early startup team members. A lot of things go wrong, the situations that startups win in tend to be incredibly dynamic, and so this idea that even if I'm not qualified on paper, even if I haven't solved this problem before, even if this problem feels like it's going to kill the company (which many problems will feel that way), the spirit among the team of "we've got the people we need, we're gonna figure this out, we're gonna get this done", that's super important.

Content: Credit card processing flow

The final content format is static visuals. I know, spending time in payments makes this flowchart more interesting for me personally. It's also curious that this comes up in an article about Chinese payment apps.


Content: A Day at the Park

On questioning our own assumptions, especially long-held beliefs, this comic makes for a nice finish.