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
- Uses tmux with caps lock rebound to
- 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
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
- Worked on an Euler problem and Iām happy with how the final solution reads (full solution here: https://github.com/nicolecomputer/euler/blob/main/006/main.ts):
const result = difference(
squareOfSum, sumOfSquares,
{ start: 1, end: 10 })
console.log(result)
- I got my undo project underway. I scaffolded out a React site with Vite and then got state management working. Next is to think about canvas and drawing. Hereās the app: https://undo.nicole.computer/ and the code: https://github.com/nicolecomputer/undo
- I did some creative coding and thought about random walkers. Hereās a sketch thatās fun to watch evolve: https://creative.nicole.computer/2024-11-07-walker/
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!