Morning Conversations

  • This morning @ywenk and I sat the lunch table and chatted
    • Uses tmux with caps lock rebound to <ctrl> and uses that key as the leader key
    • Uses lazy vim in the terminal with neovim which is an IDE-like experience that looks really nice
    • Uses exa and other tools bound to alias’s to replace their in-built tools
    • Uses wezterm because it’s faster than iTerm or other terminals and there’s less latency with key input
  • Chatted with @ywenk and @NBeing about NYC and recommendations for exploring
    • Prospect park is nicer than central park
    • Recommended vegan restaurants
      • Modern Love: Vegan Junk Food
      • Planta Queen: Asian fusion (the watermelon sushi is especially a highlight)
    • The Brooklyn library is worth spending time at

Euler Problem

It’s said ā€œproject oilerā€ (even if it’s spelled differently). h/t @ChiWilliams

Today’s problem was fun (solution on Github). Here’s the solution:

function range(start: number, end: number): number[] {
    if (start > end) {
        return []
    }
 
    const length = end - start + 1;
 
    return [
        ...new Array(length).keys()
    ].map(i => i + start)
}
 
 
function sum(n: number, total: number | undefined): number {
    return (total || 0) + n
}
 
function square(n: number): number {
    return Math.pow(n, 2)
}
 
function squareOfSum(start: number, end: number): number {
    return square(range(start,end).reduce(sum))
}
 
function sumOfSquares(start: number, end: number): number {
    return range(start, end).map(square).reduce(sum)
}
 
function differenceOfSquares(start: number, end: number): number {
    return squareOfSum(start,end) - sumOfSquares(start,end)
}
 
function main() {
    console.log(differenceOfSquares(1,100)) //?
}
 
main();

I enjoyed this problem because it fell out so naturally. I wrote range and sum for previous problems. The solution feels so mathematical. One place I think it could be different (but maybe not better?) is to implement a difference function that takes as its arguments two functions and a set of parameters to apply to both of the functions and then returns the difference. I’m not sure this is better, though. That would look like:

type Range = {
    start: number,
    end: number
}
 
function squareOfSums(r: Range): number {
    return square(range(r.start, r.end).reduce(sum))
}
 
function sumOfSquares(r: Range): number {
    return range(r.start, r.end).map(square).reduce(sum)
}
 
 
function difference<T>(fn1: (args: T) => number, fn2: (args: T) => number, args: T): number {
    return fn1(args) - fn2(args)
}
 
function main() {
    const result = difference(
        squareOfSums, sumOfSquares,
        { start: 1, end: 10 })
    console.log(result)
}

This could further be improved by making difference generic over any number of arguments but I’m not sure that’s needed for this. I do like that the solution of the problem reads like this:

difference(
        squareOfSum, sumOfSquares,
        { start: 1, end: 100 })

That feels correct. One problem is that programmers mostly don’t read programs in the way that we wish they would. It would be helpful to say ā€œthis is where you should startā€ and then have details emerge as they are needed (Swift has this idea too and they call it ā€œprogressive disclosureā€; also article chatting about progressive disclosure )

Movement Keys in VSCode

I am missing Mac OS’s built in emacs keys SO much. (it has a default keybinding dictionary that binds <ctrl>+a to start of line, <ctrl>+e to end of line, ctrl>+k to put the current line in a yank buffer).

@ywenk suggested that I take a look at vim keybindings for VSCode. So I’m doing that today

Undo Project

project-undo

Goals for today

  • First commit
    • Vue
    • Redux or redux-like library
  • Deployed somewhere (github pages)

Tooling

  • Vite: This is my first time using vite. In the past I used react-create-app to scaffold out a minimal react app. I took a look at nextJS and it looks, *ahem* , ā€œvery full featuredā€. Honestly, love that for projects that need that. I don’t. I’m not deploying something that’s going to need things like streaming or module splitting. It’s too much cognitive overhead
  • deno I LOVE deno. It’s becoming the javascript runtime I reach for first because of it’s ā€œbatteries includedā€ philosophy and because it has typescript as a standard feature. Just having a testing library and typescript is usually enough for me to get started. I’m using it for my project euler solutions
  • redux Redux is the heart of my exploration. It will let me undo events by keeping track of the event stream and playing back events to get back to previous states. I’m not sure if I’ll directly use the redux library of if I’ll just use ideas from redux. Learning Redux was one of the those moments that completely changed how I thought about software (h/t to the elm architecture too which really helped me understand some of the ideas)

Scaffolding with Vite

  • Vite asked which web framework I wanted (I said React because I know it)
  • Vite asked whether to use Typescript or Typescript + SWC. I said typescript because I think it’ll be easier for deno? Not sure if this was the right choice

Deploying to Github Pages

Published at: https://undo.nicole.computer/

The deploy script for deploying deno using vite to Github pages looks like this:

name: Deploy
 
on:
  push:
    branches:
      - main
 
jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
 
    steps:
      - name: Checkout repo
        uses: actions/checkout@v3
 
      - uses: denoland/setup-deno@v2
        with:
          deno-version: v2.x
 
      - name: Install dependencies
        run: "deno install"
 
      - name: Build project
        run: "deno task build"
 
      - name: Upload static files as artifact
        id: deployment
        uses: actions/upload-pages-artifact@v3
        with:
          path: dist/
 
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    needs: build
    permissions:
      pages: write
      id-token: write
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4
 

The ā€œUpload static files as artifactā€ needs to set the id key (id is deployment) in this case. If it’s not set then the next step, the deploy, won’t be able to find the page_url. I was stuck on this for a bit.

State management

React has built in state management! It’s the useReducer hook! Until I have a need for more complicated state management I’ll stick with it. I gave a quick look to zustand but it looks like it makes the simplification of removing actions as objects. I’m going to need actions to be concrete, serializable objects so I can undo so that’s not an optimization that works for me.

Talking about Recurse

Conversation with @embernier

We chatted about:

  • Am I behind? No, it’s super normal to spend the week being overwhelmed.
  • Is it ok to change projects? Yes, lots of RC’ers do
  • What makes for a good RC batch? Thinking about what you want to focus on and what you want to get out of it. For some people that’s intense coming time. For others that means working a core set of hours. For others it means a new job or new technologies.
  • How to prepare for a next-job? There’s a room on zullip! Schedule time
  • When to be in the office? At least 11-5. Other than that it’s up to me
  • Advice:
    • Don’t aim for perfection, people who are perfectionists struggle
    • Join the volitional muscles group (it happens tomorrow)
  • We check in again in 2 weeks!

Creative Coding

Nature of Code: Chapter 0

This is exploring a ā€œrandom walkerā€. It feels strange to work with ā€œimmediate modeā€ rendering. The history of where the walkers has been is just gone forever. But it’s pretty and fun to just watch do its thing.

A nice color palette helps.

Gaussian Distribution

This is just a quick sketch to show off a normal distribution:

const ITERATION_LIMIT = 120;
 
let iterators = 0;
 
function setup() {
  createCanvas(400, 400);
 
  background("#f8edeb");
}
 
function draw() {
  // Play with these values:
  // 200 is the center of the distribution and 40 is the standard deviation
  const x = randomGaussian(200, 40);
 
  if (iterators < ITERATION_LIMIT) {
    const c = color("#90BE6D");
    c.setAlpha(20);
    noStroke();
    fill(c);
    circle(x, 200, 40);
  }
  iterators += 1;
}

Linux annoyances

  • There isn’t something like ā€œPreview.appā€. I took a screenshot and wanted to do a quick crop. I ended up gthumb which feels more geared towards managing a library rather than doing quick operations on an image
  • VSCode is crashing a lot. I can’t tell if its deno’s Language server, or if its the VSCode Vim bindings or if it’s just my laptop being unstable but it’s crashy. It’s super annoying and I’m hoping a restart fixes things up

Presentation day at RC

Every week RC does a big batch of presentations. Today there were so many interesting things. A couple stood out to me:

  • There was a presentation of the LC-3 Computer (not that LC-III) and programming it in assembly
  • There was a presentation showing off implementing threads from scratch
  • Finally the last presentation was a selection of inspiring things including an AI that plays pokemon and a shader exploration toy

End of day

I’m still finding my balance on being social / staying focused on the problem I want to think about / being drawn in by all of the interesting things that are happening around me. I appreciated Emily’s call to ā€œlet joy be your compassā€

Worked on Today

    const result = difference(
        squareOfSum, sumOfSquares,
        { start: 1, end: 10 })
    console.log(result)

I did lots of other smaller stuff, if you’d like to peek here’s today’s notebook page: https://notes.nicole.computer/daily/2024-11-07

Tomorrow

Tomorrow is Arduino day! I have a kit and I’m ready to go and I’m really excited for it!