I’m Colten Webb, an MSCS student in the College of Computer Science at Georgia Tech.

Adding Record-Dot-Syntax support to Haskell Language Server

This page serves as a record of the work I did for Google Summer of Code 2022. I want to thank the community at #ghc and #haskell-language-server for being so welcoming and helpful this summer. And a special super thanks to Michael Peyton Jones for mentoring me!

Over the summer I added record-dot-syntax support to the haskell language server.

Record-dot-syntax was a highly-requested feature that GHC introduced in version 9.2.0 with the OverloadedRecordDot language extension. For years users had been frustrated by Haskell’s conspicuous lack of support for namespacing features common in other languages. Haskell provided a limited form of namespacing with qualified imports, but using it to namespace field selectors tended to require hacky file structures. Record-dot-syntax aimed to fix that with ergonomic field selectors that use the syntax myrecord.somefield.

To unlock the true potential of this language feature, users should be able to “dot into” records as they edit, seeing the fields available to select. This was the main contribution of this project. Additionally, users expect the editor correctly report type information when they hover over records, so this was another important contribution.

I decided to split my work into two phases: adding support for hover information first, then adding support for completions. The reason was that it would be easier to add completion information once the type information is properly exposed.

Phase 1: Exposing type information on hover

Relevant issues and commits:

What hover type information looks like in VSCode

Phase 2: Adding completions

Relevant issues and commits:

What record completions looks like in VSCode

Projects have mana bars.

Lots of games use these things called Mana bars. I have no clue where the word Mana came from, but in games it usually means “magical energy.” Just like you have a health bar which goes down when attacked, you have a mana bar that goes down when you use magic. Fun game mechanics emerge from the task of balancing health and mana and a load of other factors, and since games like to be fun, this is probably why they’re used so often.

I’ve found that my willingness to work on personal projects resembles the behavior of one of these Mana bars. Certain events make this willingness go up, and other events make this willingness go down. While looking at the different projects I’ve started over the years, and seeing which of them lasted and which didn’t, I’ve deduced some possible events that bump the bar around.

When I undertake a project, that bar starts filled some positive amount of project mana. Otherwise, why would I undertake the project in the first place. After that initial freebie mana, events will bump it up and down.

Some events that make the bar go up are

Some events that make the bar go down are

Showing what I’ve done to other people

For me, this insight is the most frustrating, but I think it is an inescapable conclusion: a powerful source of motivation is telling people about your project, in the right way (I’ll explain the right way in a bit). I’m intensely private, so sharing my work is frustrating to me. In fact, part of the reason I aim to write publicly, is to learn to combat this tendency of mine. People who are successful by any metric will agree that feedback loops were critical to their growth. I’m a coder so I see it as analogous to an edit-compile-run loop: you do something, and see what happens as a result. The space of outcomes to the things you do is most often larger than you can imagine, if you project those changes far out enough. /difficult to understand/

Showing what you’ve done is also useful because there are usually two levels of direction in a project: grand vision and the details. Testing your project out in the real world is a fantastic way to work out the details. It’s a terrible way to work out a grand vision, you should already have that. Some of my projects have died out just because I had a lot of details to work out, and I was exhausted from trying to sort it out myself. Sometimes it’s helpful to just see what sticks.

Intellectual pleasure

I wish I could say this accounts for more of why I work on projects than it does. If an obstacle is interesting, I’ll be more likely to work on it than if it’s tedious or for just not something I care about.

Hitting an obstacle

You know that JFK quote about doing things not because they’re easy, but because they’re hard? Yeah, that’s bullshit.

Hard things are sometimes a good indicator that what you’re doing is scarce, because people don’t like doing hard things. But it’s not a good indicator that what you’re doing is valuable. On a deeper level I think everyone knows this. That’s why once I hit enough obstacles in a project (depleting the project mana), I’ll take a step back and never return to it.

Hitting an obstacle and overcoming it isn’t necessarily a net plus according to the mana bar either. I think obstacles can lead directly to intellectual pleasure, but plenty of obstacles don’t lead to enough intellectual pleasure on their own. It’s helpful to complement it with showing other people that hard obstacle you overcame, or seeing what solving it made possible.

Time away from a project

In most games the mana bar will trickle up to a default level of 100%. Not so with projects. After the initial freebie mana, it’s trickling down, and you have to replenish it. If you spend enough time away from the project, the mana will get depleted.

Each time I’ve rebegun a project after a several week or several month hiatus, I’ve stopped again after a week. Part of this is probably because I work with code, and it’s more difficult to read code than to write it, making it an obstacle. But time away seems to make the potential projects seem lesser.

Sharing what I will do next

This is the tricky part of sharing a project. It’s critical to share what you have done, but not share what you will do next. This is for a couple reasons. First, it destroys autonomy. When you explain what your plans are, you will feel accountable. The whole point of a personal project is to do something where you are accountable only to yourself. If you are sharing your progress, it’s already done and there are no promises for the future, but your mind is racing with what you can do. Second, oversharing gives you the high of doing the thing before you actually do the thing. It’s a well-known fact that people who share that they will begin working out or dieting on social media are less likely to succeed than those who keep it to themselves until they’ve accomplished something. The principle is that sharing an accomplishment, even before you’ve done it, rewards you in the same way. This makes doing the work less interesting, because you’ve already received the reward.

Takeaways

Obviously personal projects can be fun and interesting. They’re even better when you finish working on them. Make sure you are keeping tabs on your project mana bar, and taking it seriously. You don’t want to hit an obstacle while it’s low.

We can induce flow.

Flow is the clinical psychology term for being in the zone. You may have found this mental state when shooting hoops, playing videogames, or coding. It has to do with an intense and focused concentration, where you lose self-awareness. The tricky thing is that it doesn’t happen every time–the state requires special internal and external conditions that are sometimes difficult to meet in everyday life.

The psychologist who coined flow, Mihaly Csikszentmihalyi, describes the activities that cause flow as being just difficult enough to not be boring but easy enough not to provoke anxiety. For the person to know whether they are succeeding or failing, the activity must provide immediate feedback, so not all tasks are naturally suited to flow. And since it’s a subjective experience, it’s difficult to quantify. But most describe it as a feeling of control, low self-consciousness, and intrinsically rewarding. It’s no wonder Dr. Csikszentmihalyi calls it the “optimal experience.”

I’m interested in how this flow state can be harnessed to help people do more of what they want to do. Given the covid pandemic, many people are left with a ridiculous amount of of uninterrupted free time. By carefully controlling a person’s environment, it should be possible to increase likelihood of a flow state. Since I believe harnessing a flow state is a way to make this free time more enjoyable, productive and memorable, this is the perfect time for self-experimenting. I also believe the principles I outline in this essay can serve as a platform to develop software that helps induce a flow state as well. To these ends, we need to precisely know what we are aiming for–we need to measure flow.

Measuring a subjective experience

Modern psychology looks a lot different from the days of armchair psychologists like Sigmund Freud, but a lot of the theories begin in much the same way. Psychologists look to some aspect of behavior, experience or whatever, and try to explain it with a theory. The biggest issue with a lot of Freud’s theories is they weren’t falsifiable: either you agree with the psychologist so the psychologist is right, or you disagree with the psychologist because you are repressing memories. Now, we need to quantitative measures and empirical evidence to be taken seriously. Theories are cheap, facts are expensive. Hooray for the scientific method!

There are several ways to measure flow in an experimental setting. Since it’s a subjective experience, this process involves asking participants questions. There are three ways to go about this. First, they may be interviewed before, during or after the experiment. This enables the psychologist to gather descriptive data about their mental state. Second, they can be given assignments. For example, participants need to fill out a diary describing how they feel whenever they partake in a certain task. Last, and most commonly used nowadays, psychologists use questionnaires, where participants rate how much they agree with a set of statements.

The first two measures are great for developing the theory and gaining insight into the mental state itself. But the questionnaires are more quantitative and therefore lend themselves to empirical studies. When deciding whether someone was in flow or not, your best bet is to give them a questionnaire. Though they are widely used in a research setting, a practical application that requires you to frequently fill out forms will quickly result in resentment. An interesting solution is to use biometrics.

Potential for biometrics

One study developed a model for predicting whether participants were in a state of flow with biometric data. They focused on improving productivity for software developers. They used three devices to infer the participant’s mental state: an eye tracker, EEG headband and Empatica wrist band. Using these sensors, they developed a machine learning model that predicted positive and negative emotions with 71.36% accuracy, and high and low progress with 67.70% accuracy.

Though questionnaires are a more accurate measure of flow, data from these biometric sensors could enable a machine to intervene while the user works in real time, rather than at checkpoints or interruptions.


Let’s now look at how researchers have tried to induce flow in a lab setting.

Matching challenge to skill

According to a 2010 meta-analysis, most researchers have tried to induce flow by having participants play simple videogames like Pac-man or Tetris, and then fiddling with the settings. Keeping the games simple lets them control task difficulty on a linear scale (increasing the speed the pieces fall in Tetris), which they then match to participant skill. According to the research, this work well. As we might expect, participants rate their subjective experience of flow higher at a difficulty level tuned to their ability than when the level is too low or too high.

Researchers have used two main strategies for tuning difficulty in the lab. As one strategy, they set up the game to adapt as they play. For Tetris, when the player misplaces several blocks, they decrease the speed. When the player completes several rows, they increase the speed. As the other strategy, they calibrate the game to the player’s skill beforehand using a trial run, then measure flow in a subsequent run. Both strategies induce a flow state about equally well.

The main problem with this method of matching skill to challenge is there are more factors about the setting and participant than just skill level and challenge that influence flow. Before experimental research with Tetris, psychologists did correlational studies on athletes and artists to research flow. They found that matching perceived skill to perceived challenge correlates with flow, but this doesn’t prove causation as many of these studies assume. Studies that have attempted to experimentally induce flow have for the most part neglected extra factors. But to create a system that reliably induces flow for an end user, they cannot be ignored.


There are many of these “third variables,” at play, like how important the task is, availability of distractions, and the participant’s personality. Let’s examine some of them.

Reward and importance

Flow is all about finding an intrinsically rewarding experience. Extrinsic incentives seem to undermine intrinsic motivation in an experimental setting. Counter-intuitively, a carrot on a stick will distract, not motivate.

As a first example, a critical extrinsic incentive is not making fool of oneself. To reduce the chances that a participant has this type of distraction, researchers removed the cameras, mirrors and people from where participants worked. They reasoned that a significant distraction was self-awareness. By removing stimuli that triggered this self-awareness, they increased the participants’ subjective sense of flow.

The pitfalls of self-awareness prove a challenge because many tasks require an opponent or coach to offer immediate feedback. According to the 2010 meta-analysis, there are two main strategies to maximize the benefits of having an opponent while minimizing its negative effect on flow. First, make sure the opponent is really necessary. If the opponent doesn’t need to be there in person, they might as well not exist since they provide no feedback. Second, de-emphasize the competition and any extrinsic reward. Try to help the participant focus on the task at hand, not on winning or impressing someone.

Another issue is the participants perception of the task’s importance. If the task is so important that they fear failure, they are less likely to achieve flow. This effect can be countered to achieve a sub-optimal flow state by reducing task difficulty to below the participant’s skill level. This is the effect you get when cramming for an important test and you grind out easy practice problems. Without the stress, you could probably reach a more rewarding flow state by engaging with more difficult problems.

Now let me put on my speculation hat. I think this finding that easy practice problems induce flow in stressful situations could be real helpful strategy in practice. Self-awareness inhibits flow, but that doesn’t mean you can’t build habits to facilitate flow based on how you feel. If you practice the act of doing easier problems when stressed, you can improve the likelihood that you will stay in a flow state. Once the easier practice problems become very easy, you can move up in challenge difficulty by remaining in the flow state. In other words, given the availability of many tasks with difficulties clear to the user, self-regulation of flow should be possible.

Character and flow

Characteristics of the participant, like what kind of long-term stress they are experiencing or certain personality factors, also affect how susceptible they are to flow.

Long-term stress is associated with a decreased level of flow, but a little short-term stress increases it. So we are looking for the type of stress that keeps you awake and aroused, not distracted. One study showed that in a workplace setting, flow states were made more frequent by giving employees clear goals for short term tasks like brainstorming. Factors that affect long-term stability, like clarity on what their role is, don’t have as much of a direct effect. But when someone has clear long-term vision of their role, they can likely come up with short term benchmarks to compensate.

Psychologists have noted that the volatility-persistence component of action-orientation correlates with a higher likelihood of entering a flow state when skill and challenge are balanced. Volatility-persistence is an indicator used in personality theory that measures how well a person maintains their focus on activities, persevering until they are finished. So someone who tends to be more persistent will find flow more consistently when tasks are suited well to their skill level. Someone who is more volatile will be less likely to find flow, and when they do, it has less to do with how their skills compare to the task at hand.


Now that we’ve looked at how flow can be managed in an experimental setting, let’s see how we can make flow states more likely in our own lives.

Software engineers stay in flow by intuition.

In a study that analyzed the correlation between progress in software development and flow, the researchers discovered three strategies participants used to avoid negative emotions associated with losing flow. These strategies likely apply to other projects that involve building multifaceted solutions, like solving a long math problem or writing a research paper.

First, the developers switch contexts when they are stuck. For example, a solo developer working on a game might switch to composing the music or making pixel art when they run into a roadblock while coding. This decreases their frustration, allowing them to return to the problem later with a clearer head. Positive emotions are correlated with more progress, so this strategy might be very effective.

Second, the developers set clear goals. A participant in the study explained:

For example, [I] work on this task until then and then, and afterwards, I will give myself some sort of reward, for example, take a break.

A reward like this makes sense because it doesn’t depend on performance. The break will come no matter how well they do at coding, they just need to finish. This creates positive emotions that are conducive to flow.

When working on projects, I’ve found that I often conflate a lack of clear goals with being stuck. When I complete a task, or decide that I’ve done good enough, I’ll take a break instead of deciding what to work on next. When using these two strategies to re-establish flow, it’d be prudent to be mindful of what broke the flow to begin with.

Last, they allocate enough time for the task, relieving time pressure that often leads to greater stress and frustration. Another strategy would be to focus on easier tasks, but this may not always be an option, especially in the workplace.

Guidelines for flow-conducive tasks

A 2013 study offered broad criteria for tasks that correlate to high flow states, some of which are listed here:

Intervening in flow

As the software developers have proven, it’s possible to deliberately enter a state of flow by taking certain actions once they’ve lost flow. This means maintaining a state of flow can be seen as a skill, to be improved with appropriate behavior modification and knowledge of task difficulty.

Task difficulty is largely a subjective experience, but some aspects of it can quantified. For example, for a given math problem, we can count how many of 100 students can solve it. A greater number of solves would mean it’s an easier problem. We could feed these math problems to a student based on their personal, subjective experience of flow. A machine could calculate an optimal task-difficulty for flow.


Students, developers, and researchers alike could all benefit from the deliberate pursuit of flow. Imagine a world where people don’t rely on deadlines to learn. They explore with a fluidity and absorption that matches that of a great artist or olympic athlete.