TODO: this page is still under construction! I'm generally satisfied with the current outline I have in place, but I still have yet to put all the content in place. This page is effectively a blog post about my experience with technology.
My GitHub has the majority of my projects, but here are some standouts.
TODO: I'm still thinking about how best to display this!
TODO: I'm still thinking about how best to display this!
My computer is named "photon" because it is all white, pretty heavy on the RGB lighting, and, having studied physics in my undergraduate education, I wanted to name it something physicsy. It's a beefy small-form factor desktop that I built mainly for programming but also for gaming. I wanted it to be portable because I expect to change locations soon. Noise was not something I selected for, but this does end up being way louder than what I'd've naïvely expected. Below are its specs.
TODO: put an image or multiple images of photon here (once I clean up the cables 😛)!
TODO: put an image of my rice here (once I'm ready to call it mostly done)!
My background image was obtained from a Reddit post by /u/ShotBot.
I'm running everything on NixOS. I used to dual-boot Arch and Windows on an older computer, but I was unable to install Windows on photon, so now it's just NixOS. I used to use Windows for gaming and Arch for everything else, but aside from a few hiccups, I'm finding that I can run games on NixOS. NixOS feels like a significant upgrade over Arch. In Arch, any small minute difference could cause my system to be borked (e.g. I change my location or I upgrade packages), and then I'd need to spend a while finding the relevant config file to change and fix. With NixOS, I need not search through the entire system for what is wrong, and I only have to find what relevant part of my configuration is wrong or needs updating.
I'm running Hyprland on Wayland with Waybar. I greatly appreciate Hyprland's emphasis on being visually appealing. Unfortunately, many applications appear like glitchy garbage on Wayland (e.g. Steam, Discord). I hope that this gets better with time, especially as Wayland picks up in use. I use the Alacritty terminal with tmux, and I generally develop on a terminal with NeoVim. In terms of visual style, I like status bars or toolbars to be at the bottom so that the rest of the screen can be dedicated to content. It is for that reason that I have my Waybar at the bottom of the screen and I keep Firefox tabs at the bottom rather than the top.
It is very important to me that applications do not show things like “Recently Used”. I care enough about that that I store my bash history file in the /tmp folder so that it gets deleted on shutdown. If a long command is worth keeping, then I should set up an alias or script for it or store it somewhere so that I make it systematically easier for myself rather than relying on history. Likewise, files should be well organized so I can easily find them rather than relying on the crutch of my history. Plus, I really like the feeling that my system is “fresh”, and a stored history impedes upon that. In general, I really like things to be very well organized and structured and clean.
I like Rust as a replacement for C and C++. Rust feels nice to use in many ways, and it also is nice to know that the generated software is performant and relatively minimal. I do wish though that it looked a little bit less ugly. Certain syntactical notations (e.g. turbofish) and the extreme use of abbreviations make Rust code always look ugly.
Kotlin is a very nice upgrade over Java. I really like the simplicity that Kotlin allows for. It is a shame that Kotlin is a JVM language though. I dislike the JVM on principle. Though Kotlin has a native compiler and a JavaScript transpiler, from my brief experimentation with them, they don't really feel all that usable to me.
The proliferation of JavaScript where it shouldn't be makes me sad, but TypeScript is a nice bandaid for that. Modern JavaScript itself isn't the worst (I personally much prefer it to Python which is also ‘too prolific’ in my opinion), but TypeScript is nicer. I really like developing with types as a crutch, and TypeScript is very ergonomic.
I have spent a lot of time writing code, and below are the ways in which I approach code and think about software development. Of course though, I'm just me, and me is just one guy who has opinions that can be wrong, so I'm of course not touting that these are optimal or anything like that. I'd always be happy to discuss or debate these though!
Code has aesthetic value and should be treated as such. Writing bad code is like making bad art: it feels painful and wrong. Even a simple problem can be approached in a multitude of ways, and the method of solution feels like a window into how the author thinks.
Naming things well is one of the most important tasks in programming. Using longer, more descriptive names costs nothing, and therefore should be done ALWAYS. How much time is saved by not typing a few keystrokes? I feel as though I save way more time from descriptive names because they save me so much mental effort.
Full names also up-front the requisite mental effort for figuring out what a variable is and does. That itself is valuable.
I have worked with a lot of scientific software, and it is unfortunately the worst in this regard. Everything is named with symbols as they appear in formulas and equations. Even if the symbol is well-established within the field (e.g. H for Hamiltonian in certain physics contexts), using the full name eliminates any ambiguity and should be what is done. If I had my way, I'd even call symbols like π or e something like ‘CIRCUMFERENCE_TO_DIAMETER_RATIO’ and ‘NATURAL_EXPONENTIAL_BASE’ in code, but I know that that battle's been lost.
Ideally, well written code describes what it is doing already. Good naming should play into that too. One should just be able to read the code to see what it is doing. Consequently, comments should be used to describe that which the code does not easily signify: intent. Why are things done the way they are? However, comments should be wielded carefully; comments are not checked for correctness and they become yet another part of the codebase that must be maintained. Old, or worse, wrong comments are more destructive than a lack of comments.
While I appreciate sexy UIs as much as the next person, what I care about more is functionality. An ugly UI is bearable, but a broken UI is frustrating. Only after I'm confident in my UI's functionality do I go back through and polish the visuals.
I like to start with unadorned UIs, but even when polishing them, I aspire to keep them basic to some degree. Simplicity comes with a litany of benefits. First of all, developing a simple UI is less time consuming. Simple UIs also tend to be easier to parse and use. Plus, it's easiest to make simple UIs accessible.
Software accessibility is also an important consideration. A lack of accessibility needlessly limits who can use an application, even though software is wondrous enough to make that a simple thing to accommodate. Accessibility is very much a part of usability.
In my mind, software durability comes through being reliable and working well. Software should also be able to last and consume as few resources as possible. Nothing is more frustrating than software that breaks for seemingly no reason; too much software manages to degrade inexplicably.
Programs should be small! There's no reason to bloat the size of programs unnecessarily. Even though disk space is free, it still feels yucky to take up more space than needed. Large programs also take longer to transfer.
Speaking of transfer speeds, most websites tend to be horribly bloated. Images and media can often be compressed and lots of bloat can easily be removed without harming a website's functionality. It's boggling that payload sizes are oft left by the wayside.
Most importantly, programs should run well. If something is slow in a piece of software I'm creating, I think it's important to explicitly consider whether the time cost is strictly necessary. Slow software just straight up feels bad, and so time costs should be minimized whenever possible.
The trend of having browsers be their own faux ecosystem makes me sad because it feels like having better native APIs and cross-platform wrappers would be a better solution. However, I'm probably being too idealistic. I understand that browsers just handle so much important stuff (text for me being the biggest one), that it's hard to not use browsers for certain types of applications. It still feels tragic though that that is the state of software development.
The art of writing code is the art of making contracts. Focusing on the contracts inherently means thinking about the high level design of the program before diving into the nitty-gritty. One must focus on making the right promises and then implementing them. For this purpose, I really like having strong type systems because they allow for enforcement of contracts during compilation. The contract is especially important because once the contract is set and in-use, it can be difficult to change. However, implementations are just details that can easily be changed.
Semantic correctness is also something under this purview that I find important. In HTML, for example, tags should be used correctly and respected. Using paragraph tags for headers is wrong, even if stylized to match header tags. It may be the case that a user is viewing your content in a non-traditional manner (e.g. screen reader), in which case using the right tags may allow the user to more accurately grok the page. However, semantic correctness applies not just to HTML.
Keeping track of state can get very complicated. Keeping things declarative instead makes programs much easier to reason about. In general, I try to create programs in as much of a functional-programming mindset as is possible.
I really want to get into test-driven development, but I unfortunately have yet to really grasp how to do it well. The benefits are apparent, but I know not how to structure my code well for testing. This is something that I am trying to improve upon though. Oftentimes, it feels like the tests I write are not very general and depend heavily on my implementation, and then writing tests feels like a burden or a chore rather than something that is adding to my codebase. This is something that I am actively trying to learn though and get better at.