Now that I'm finally finished with finals, and I'm done with the various post-semester plans I've had scheduled, I have some time to write about all the things that happened in my life and what I think about them.
This year was pretty academics-heavy for me, and I spent a significant portion of my academic time doing math. Off the top of my head, I think I took 8 math courses in college this year, along with 2 directed reading programs. In hindsight those directed reading programs were pretty important for my mathematical growth. I found myself somewhat disinterested in most of the math courses I took this semester, either because I knew most of the content already (something which is not reflected in my grades because of something I'll talk about later!) or because I was too busy with other things going on to devote enough mental real-estate to the course. This meant that the looser, socratic structure of the DRPs really satiated my desire for more math. There's also so much I've gotten out of working closely with grad students, especially their unique perspectives on the process of doing math. The DRPs were on Representation Theory and Measure Theory, two fields of math I wouldn't really have explored without the DRP opportunity. (Especially Measure Theory - I usually hate analysis!) I'm grateful for the opportunity the program gave me to explore new avenues of math, along with the guidance I received (both regarding those topics and regarding being a math major in general) from my mentors.
I was unfortunately not able to spend as much time as last year on projects. Most of my first semester was spent focusing on mathematics and surviving in a dorm, but once the semester was over I had much more time to devote to projects. That's when I started working on rano, a text editor written in Rust meant to be a nano clone. It's built using a thin wrapper over ncurses, so unfortunately there are many aspects of the editor that are broken, but I was able to get a simple editor working with some cool features (including syntax highlighting and clipboards, something that isn't really supported in nano). More than anything, the project was a good opportunity for me to learn some more Rust. (I still won't say I know Rust, but I like to think I'm slowly reaching that state.) I worked on rano on-and-off during the summer along with work, but I've abandoned it since in favor of more math and other projects since the fall semester started. In December (that's not even a month ago!) I started learning Prolog, and I thought it would be a good idea to do this year's Advent of Code in it. Unfortunately I was too busy that I didn't get past day 5, but I did learn a lot of Prolog by writing actual, nontrivial programs. I also forked pygyat to enable direct execution of native code, and I'm hoping I'll be able to devote more time working on cao.
Over the summer I had the opportunity to intern for X (which is fitting given my Twitter use this past year). I was on the search team, and I had the opportunity to work on models for the final search result ranking process. It was a great opportunity where I met lots of bright and friendly people, and I learned a lot about ML and ranking, about data pipelining, about tech debt and maintenance, and about what it means to be a programmer. In the process, I gained lots of opinions on how to "do things" as a tech company. Given the fact that I haven't actually had a programming job yet (only internships for me so far), those opinions are most likely wrong, or at least no more likely to be right than wrong (I'm reminded of an Eigenrobot tweet about not listening to political opinions of people under 30, which I think is somewhat correct). Anyways, it was lots of fun and I learned a lot and I'm looking forward to applying all the knowledge I gained in my next job.
Now for some reflection. I definitely wasn't able to devote as much effort as I could have into things that consciously mattered to me. For example, I realized maybe half-way through the fall semester that I probably should prepare for grad school, even if I don't plan on going - my reasoning is that doing math research without a PhD is really difficult, so I'd rather have that door open as long as possible before fully committing. Setting aside whether that argument is true, I definitely didn't put in the effort to guide myself towards that goal. One of the big mistakes I made this year was taking 6 courses (of which 5 were math courses) during the fall semester, which increased my overall workload and spread me too thin (especially given I was also doing a DRP at the same time). But that increase in workload didn't cut much into my free time, and I was able to scrape by with a mediocre-but-not-totally-awful grade in my classes while picking my nose and watching Northernlion streams every day. Something somewhat adjacent happened during my internship. On many days I had to choose between my independent work on the search ranker and some data pipeline refactoring job I was pulled into helping out with. The former required more agency from me, while the latter was writing boring pipelining code that my supervisor told me to write (think Apollo 13 square peg round hole) - "plumbing." I often chose the latter. I think the reason why was because I felt tired by my search ranking job (for one reason or another) and I enjoyed the complacency of the pipeline job. Of course, I learned less writing that kind of code (a lot of it was solved by the IDE). The common thread between these two failure modes for me was complacency. One of my new years resolutions will be less complacency, more agency, and more urgency.
I have some more goals for next year as well. I want to do some math research next semester, and I'm hoping that over the summer I can do an REU - I'm eyeing the UChicago one specifically, because I can work on a specific topic of interest. I'm also hoping to learn more prolog - I think it would be pretty funny if I can do technical interviews in it. kobo is also due for a refresh - the current publishing cycle is pretty awful and I can think of 10 better ways of doing semi-static site management. I'll also try to write something for shedding.bike before the start of next semester.
One last piece of positive news before the end of the year - we finally sold gamut.ink, my project with friends last semester. A lot of the ideas in gamut were groundbreaking at the time, and I think still ground breaking now, a year and a half later. We still see loads of LLM-based tools with awful interfaces, and one of the main reasons why is that they use text as their primary form of controlling the AI agent. There's loads of UI/UX improvements to be made in the space, and I think this is an underrated and underexplored aspect of LLMs (please steal this idea - I've stolen it from my friends, and you could steal it from me too! And you'd end up making a much better product than any other company!) Anyways, I'm glad we finally got closure for the project. I have loads of memories from gamut, working with my friends to build something cool over the summer. It was loads of fun and I gained so much from the process - both hard and soft skills, and also a strong bond with my friends. Even if I could re-live my life, I won't have it any other way. Here's to more projects with my friends.
Anyways, that's all for now. I wish you all have had a Merry Christmas - and I wish everyone a Happy New Year!
Sincerely,
Dylan Wallace
It's been a busy week, but here's a few updates from my life.
If you were excited for me doing Advent of Code in prolog... I decided I didn't have enough time. Around day 5, the problems became a bit tedious to solve and I was busy with some other things, and I couldn't help but put it off for the time being. Maybe I'll return to it during winter break. But if you were invested in my prolog journey, then you're in luck: I decided to write a regex parser in prolog. I'm hoping to update it when I have the time between studying for finals.
Here's another small project I've been working on: Last Wednesday, I saw the pygyat language on hackernews. As a language, it's literally just python with "brainrot" keywords, so there's not really anything interesting going on. But I did see a way I could improve the implementation of pygyat. In the original version, you need to run a script to convert pygyat files into python files, which you can then run with the python binary. But I know there's a better way.
Not many people know this (my good friend David told me about this actually), but you can define your own encoding schemes in python. By just defining a few functions, you can make the python preprocessor run arbitrary code to convert files into a python-readable format. Dropbox used this technique to do better html rendering; my friend David used it to implement C macros in python. And I used it to implement native pygyat support. (I think it was a Wednesday well-spent. It also only took me a few hours.)
Speaking of Wednesday, I had my measure theory presentation on that day. I think it went pretty well, and I've uploaded the slides if you want to read them. I also have a dedicated page now for all the talks I've done so far.
That's it for now - I have 5 finals coming up, so I'm imagining spending more time on schoolwork in the near future (and also twitter). Hope I have something interesting to update you guys on in a few weeks :)
I mentioned in my last tidbit that I was going to be doing this year's Advent of Code in Prolog, and I'm happy to tell everyone that I am! I've been posting my thoughts on the problems, prolog, and my problems with prolog on twitter every day, but I thought it would be valuable to reflect on my reflections in a more substantial form.
First, something I thought I would have more problems with but didn't. As a "functional" language, I was dreading Prolog's IO. But Prolog's stream objects are relatively easy to work with, and there are enough helper functions for extracting strings from streams, that I never really had problems with input. And the problems so far have just wanted a number as an output, so IO as a whole has been fairly easy to work with.
But I was right to dread working with strings. Prolog strings aren't secretly lists (like haskell), so I can't implicitly destruct strings like I would with list. I also can't use list predicates for strings; I'd have to convert to list, then manipulate the list in some way, then reconstruct a string. This was a bit annoying, but I didn't really have to deal with strings past the initial IO stage and I could just pass integers to format for output, so I was able to sidestep a lot of this annoyance.
There were a few moments where I was really happy that I was using Prolog. In part 2 of day 2, I needed a way of finding a subarray of a list with one element missing. This would have been annoying in an imperative language, but with Prolog I was able to just do
permute([], []).
permute(List, Sublist) :-
append(As, [_|Bs], List),
append(As, Bs, Sublist).
which is not just efficient, but also verbose. Compare that with Haskell's zipwith (++) (inits list) (tail $ tails list)
, which constructs the sublists explicitly (taken from alcuin).
There were also a few moments where I was pretty frustrated with Prolog. As a newbie, I struggled a decent amount with whether I could bind a variable or not (maybe 30% of my time spent on AoC was debugging my predicates to properly bind variables). The aforementioned IO and string handling weren't ideal, though I was fortunate enough to not have to deal with them very much. Prolog also doesn't have a very good library, at least compared to something like python. For example, I needed a regex module for day 3, and my only real choice was a port of PCRE. But I needed a way to replace all matches, and PCRE only provided a way to replace the first match, so I had to code my own replace_all
predicate. The documentation for the packages that do exist are also not the best. I kept on getting the wrong answer for part 2 of day 3, and I was so stumped that I ended up just using regexpr to manually solve the problem. But I felt guilty for not using Prolog for the whole problem, so I kept on debugging. Only after an hour or so of debugging did I realize that .
by default did not match \n
, which was messing up my matches.
But all in all, I'm having a pretty fun time doing these problems. I'm getting a better grasp of Prolog, and I'm hoping it can soon be ready-to-hand like Python is to me right now.