External Links

My Work

Randy Pausch's Time Management Lecture

Randy Pausch was a professor at Carnegie Mellon, a virtual reality pioneer and human-computer interaction researcher, co-founder of Carnegie Mellon's Entertainment Technology Center, and creator of the Alice software project. This particular lecture was on time management, given at the University of Virginia while he was battling pancreatic cancer.

5 things that stuck with me:

  1. There are no shortcuts for experience.
    That's why we pay a lot for someone who has experience. Good judgment comes from experience, and experience comes from bad judgment.
  2. Thank you notes.
    People will remember you for them. Even with Randy's status, he took the time to write them because it mattered to him (thank you notes aren't really a thing anymore). My take: no matter how "busy" a person you are, you can still be a person who makes large gestures. Paper recycling bin, his dog, little details like that. Point is, take time not just for "work" stuff but for people, for loved ones.
  3. Make your office comfortable for you, and optionally comfortable for others.
    People come into each other's offices and suck the life out of you, so think about the opportunity cost and learn to say no. When someone interrupts, tell them "I only have 5 minutes," and later, if you choose to, you'll have the privilege of extending that.
  4. Find your creative time and defend it ruthlessly.
    Find your dead time for phone calls, meetings, mundane stuff, so it doesn't eat into the creative time.
  5. Delegating ≠ dumping.
    Trust people enough to give them resources, time, budget, but do the ugliest job yourself. You can't be vague, you have to be specific: the exact thing that needs to be done, date, time, penalty or reward. Reinforce the behaviour you want repeated.

Research Questions: Programming Languages

1. Why did we move from punch cards to programming languages?

The biggest reason was abstraction. Early computers ran on machine language, which was basically long strings of binary code, and even after assembly language showed up, programmers still had to write almost one line for every single machine instruction. FORTRAN is probably the clearest example of why things changed. John Backus and his team built it at IBM because programming had gotten so labor intensive that something had to give. IBM has pointed out that a task which once took around a thousand handwritten instructions could sometimes be done in about 47 lines of FORTRAN instead. Grace Hopper's A-0 system was another big step in the same direction. According to the Computer History Museum, A-0 let people use English-like words instead of raw numbers to give the computer instructions, and it already had several traits we'd now recognize in a compiler. So really, a programming language exists to bridge what a person wants to do and what the machine actually executes. And that says something important about their purpose: they exist to manage complexity.

2. Why do we need so many programming languages?

We end up with that many because there's no single set of trade-offs that works for every kind of problem. CMU's programming languages material points to languages built for very different purposes: COBOL for business processing, C for systems work where low level control matters, BASIC, Pascal, and Logo for teaching, Java and JavaScript for the web, and APL for compact array manipulation. Python is a good example of one set of priorities. It leans into readability, quick development, and expressive high level code, and its own documentation talks about its simple syntax and dynamic typing as reasons it's suited for building things fast. C takes basically the opposite approach. It hands programmers direct control over memory and hardware, which systems programmers need, but that same control opens the door to bugs that higher level languages try to guard against.

3. Drawbacks of a language you use

I ran into this myself while working on the perfect cube problem. Floating point behavior in Python isn't always intuitive. Computers store floating point numbers using finite binary representations, so calculations can end up slightly off from what you'd expect mathematically. Python's own docs even have a section explaining why this happens. So a result that should be exactly 1234.0 might actually come out looking like 1233.9999999999998 internally. That gets confusing fast if you're checking for exact equality and don't know why it's failing. If I could change one thing, I wouldn't get rid of floating point entirely, it's too fundamental and efficient for that. But I'd want the language to be more upfront about precision issues, maybe with clearer warnings or beginner friendly error messages whenever an operation runs into floating point limits.

4. Creating a new programming language

The first question I'd ask is what problem the language is actually supposed to solve, since that shapes everything else. From there I'd need to define the syntax, basically the grammar for what people are allowed to write. That covers how variables get declared, how functions are written, how blocks are structured, how expressions are formed, and which operators exist. I'd also need to decide what data structures the language supports, things like strings, arrays, lists, and maps or dictionaries. And then error handling. What happens when something goes wrong, like dividing by zero, using an invalid index, passing the wrong type, referencing a file that doesn't exist, or writing invalid syntax. Once the language design is set, it'll need an actual implementation and heavy testing.

Research Questions: Decision Problems

1. What is a decision problem?

A decision problem is basically any question that can be answered with a yes or a no, given some input. What makes decision problems so central to computer science is that a huge number of practical problems can be reformulated as decision problems even when they don't look like it at first. If you want to know the shortest path between two cities, you can turn that into a decision problem by asking "is there a path of length less than k?" and then adjusting k until you narrow in on the actual shortest distance.

2. What does it mean for a decision problem to be decidable?

A decision problem is decidable if there exists an algorithm, a Turing machine in the formal sense, that will always halt and give the correct yes or no answer for every possible input. The key word there is always. It's not enough for an algorithm to work most of the time or to eventually get the right answer if you wait long enough on some inputs but run forever on others. It has to terminate, and it has to be correct, on every single input you could throw at it. Alan Turing showed back in the 1930s that not every decision problem is decidable. The most famous example is the halting problem, which asks whether a given program will eventually stop running or loop forever on a given input. Turing proved, using a clever diagonalization argument, that no algorithm can solve this in general. So decidability isn't a given. It's actually a fairly special property that a problem needs to have before we can even start asking how we can solve it.

3. What is the class P? What is the class NP?

P stands for polynomial time, and it's the class of decision problems that can be solved by an algorithm whose running time grows as some polynomial function of the input size. So if your input has size n, a P algorithm might take time proportional to n, or n squared, or n to the fifth power, but not something like 2 to the n, which grows explosively. Sorting a list of numbers is in P, since you can do it in roughly n log n time. Checking whether a number is prime is in P too, though the algorithm that proves this (the AKS primality test) wasn't discovered until 2002, which itself says something about how not obvious these classifications can be. NP stands for nondeterministic polynomial time, though the more intuitive way to think about it is as the class of problems where a proposed solution, sometimes called a certificate or a witness, can be verified in polynomial time even if finding that solution in the first place might take much longer. The classic example here is Sudoku, or more formally the graph coloring problem, or the traveling salesman decision variant. If someone hands you a filled-in Sudoku grid, checking whether it's a valid solution is fast and mechanical. But finding that solution from scratch, especially as the grid grows large, can require searching through a massive number of possibilities. Every problem in P is also in NP, since if you can solve something quickly you can certainly verify a proposed answer quickly too.

4. What is the intuitive meaning of the "P versus NP" question?

P versus NP is asking whether verifying a solution is fundamentally easier than finding one, or whether these two things are secretly the same difficulty. If it turns out that P equals NP, it would mean that for every problem where checking an answer is fast, there also exists a fast way to find that answer, we just haven't found the right algorithms yet. It would mean that huge swaths of problems currently considered intractable, things like optimal scheduling, certain cryptographic systems, complex logistics and route optimization, could suddenly be solved efficiently. Cryptography as we currently use it online, things like RSA encryption that banks and websites rely on, depends on certain problems being hard to solve even though verifying a solution is easy. If P turned out to equal NP, and if the algorithm involved were actually practical rather than just theoretically polynomial (there's a difference, since a polynomial time algorithm with, say, an enormous exponent could still be useless in practice), then a lot of modern encryption could become breakable. Most researchers in the field actually believe P does not equal NP, meaning they think there really is a fundamental gap between finding and verifying, but nobody has managed to prove it.

5. If you resolve the P versus NP question, how much richer will you be?

The Clay Mathematics Institute pledged to pay one million US dollars for the first correct solution to each of its seven Millennium Prize Problems, and P versus NP is one of the seven. for the P versus NP problem specifically, settling the question in either direction, whether you prove P equals NP or prove they're different, earns the full prize. That's not true of every Millennium Problem, some of which require a specific kind of resolution, so P versus NP is a little more forgiving in that sense. The person who cracked it would likely also receive a Fields Medal or Turing Award, immense academic prestige, and probably no shortage of lucrative consulting offers, speaking engagements, and book deals afterward. The million dollars from Clay would honestly be the smallest part of the reward.

Research Questions: HCI

1. What is HCI and which disciplines feed into it?

Human-computer interaction is a field concerned with designing, evaluating, and building interactive computing systems for people to use, along with studying the bigger picture of what happens when people and machines meet it is described as a discipline concerned with the design, evaluation and implementation of interactive computing systems for human use and with the study of major phenomena surrounding them. It's not owned by computer scientists alone though. Psychology contributes theories of cognition and behavioral analysis, sociology and anthropology look at how technology fits into work and organizations, and industrial design shapes the interactive products themselves. Human factors, linguistics, and graphic design usually get folded in too, since interfaces involve language, visuals, and physical ergonomics all at once. Basically, HCI sits at a crossroads rather than inside one department.

2. Usefulness vs. usability

These two get mixed up a lot, but they answer different questions. Usability asks whether someone can figure out how to use a thing without much friction. Usefulness asks whether the thing actually does something worth doing. Usability is about ease, while usefulness is about impact, meaning whether the product actually solves a meaningful need. A product can nail one without the other, and an appointment app could be pleasant and easy to navigate, yet if it can't actually let someone book an appointment, none of that ease matters. Another example could be a bike-sharing app with a clean layout, quick sign-up, and clear map. It's genuinely usable. But if there's no docking station anywhere near someone's neighborhood, the app is useless to that person no matter how smooth it feels. Usability lives in the interaction, usefulness lives in whether the interaction gets someone somewhere they actually need to go.

3. A confusing everyday interface: the "Norman door"

Doors sound too simple to mess up, yet they're one of the most common design failures around. Don Norman wrote about this so often that badly designed doors are now just called Norman doors. A Norman door is one where it's unclear whether to push or pull, usually because the design favors looks over usability. The person's goal is straightforward, they just want to walk through, but when the door's shape suggests one action while the actual mechanism requires the opposite, people end up guessing, and get it wrong. Often this happens because flat bars get placed on both sides of the door for symmetry, when normally a bar affords pulling and a flat plate affords pushing, so the visual cue and the real function stop matching. A simple fix is keeping the hardware honest. Put a flat plate only on the push side and a handle only on the pull side, so the shape itself tells you what to do before you even reach for a sign.

4. Prototypes, user testing, and the limits of "do you like it?"

A prototype is basically a rough stand-in for a finished product, built early enough that changing it costs almost nothing. It could be paper sketches, clickable wireframes, or a working mock-up, depending on how far along the idea is. Testing one with real users matters because it lets teams make decisions based on how people actually behave with the design rather than relying on internal guesses. Watching someone attempt a task shows exactly where they hesitate or click the wrong thing, which is far more informative than asking their opinion afterward. Asking "do you like it?" mostly just collects politeness. It nudges people into evaluating the design instead of exploring it naturally, and turns the session into an opinion poll rather than a real usability test. It also can't tell you whether someone would actually complete the task correctly, since people are generally bad at predicting their own future behavior, and tend to answer in whatever way avoids hurting the researcher's feelings.

5. Interaction beyond keyboard and mouse: tangible interfaces

A tangible user interface lets someone manipulate digital information through physical objects instead of a screen and pointer. This includes things like grabbing and moving interface elements directly, or using full-body movement as input. One well-studied use case is elderly users interacting with communication technology through personalized physical objects rather than menus and icons. Research on this shows elderly people benefit from tangible interfaces through clear, simple forms, personalized elements tied to their own lives, and interfaces that are easier to learn than typical screens. To test whether this actually helps, a researcher could hand a group of older adults both a tangible version and a standard touchscreen version of the same task, something like picking a person to call, and compare completion time, error rate, and how much guidance each version needed. Watching hesitation points and asking people to think aloud while trying it would reveal more than a survey ever could.