PurelyFunctional.tv Newsletter 390: the elements of flow in a REPL environment

Free Beginner Workshop

From OO to Clojure Workshop!

Watch my free workshop to help you learn Clojure faster and shift your paradigm to functional.

Issue 390 - August 10, 2020 · Archives · Subscribe

Clojure Tip 💡

the elements of flow in a REPL environment

After last week's newsletter about missing the REPL, I got a lot of encouragement to promote REPL-driven development. Well, here it goes.

One of the coolest benefits of REPL-driven development is how easily it helps you get into flow. Flow is a state of mind where you feel energized, focused, engaged, and enjoying the process. It's the state of mind that optimally uses your mental faculties and it's key to having a successful REPL experience.

Psychologists have studied flow and have identified factors that appear to be necessary to achieve and maintain a flow state. There are many schools of thought on how to organize these, but they are all similar and vary only in the details. Here's the most accepted schema of requirements:

  1. Clear goals and progress
  2. Immediate feedback
  3. Balance challenge with skill

Of course, these are all interconnected. Good REPL-driven development can help us achieve these three factors and thus enter a state of flow. Let's see how.

Clear goals and progress

When I'm doing REPL-driven development, I often break down a problem into smaller, testable chunks. For instance, if I know I have to write a data transformation pipeline, I can test individual pieces of the pipeline independently. I can also test one step, then add a step and test it, then add another step and test it, repeating until the pipeline is completed. A good REPL-driven development workflow has a clear goal broken down into achievable steps.

Immediate feedback

Of course, if I had to wait a long time to test each step, it would feel more like a pain than a benefit. For example, if I had to write out a unit test for each step in the chain in order to know if it worked, that would be a chore. But a quick keystroke in my editor can execute an expression and show me the result. The immediate feedback means I know if I'm on track. If I'm not, I know very quickly that I should adjust my code. REPL-driven development gives you rich, fast feedback continuously.

Balance challenge with skill

Sometimes I break down the problem into tiny, easy steps and it gets tedious to test each step. And sometimes I don't break a problem down enough and I lose confidence that I'm on the right track. A flow state requires that the difficulty of the step be a little challenging for your current skill level. You have to find a middle ground between boredom and brain-busting. A good REPL-driven workflow lets you adjust the difficulty of the step to your current mental capacity. My step size is different from your step size. And my step size today might be different from my step size yesterday. The key is being able to adjust dynamically.

So let's summarize how to get into a stay in flow.

  1. Set a goal.
    For example, your goal might be "write a function that applies title case to a string." It should be a goal you can easily remember so you don't get sidetracked. "What was I doing again?" is not something people say when they're in flow.
  2. Pick a subgoal that will make progress toward the goal.
  3. The difficulty of the subgoal should be something you are ~75% sure you could get right the first time.
    I can concatenate strings 100% of the time. But can I split them into words? There are enough corner cases that I'm doubtful. So, for me, that is a good sized step.
  4. Write the thing.
  5. Test it quickly at the REPL.
    It's worth taking time to make this very quick and easy because you will be doing it many, many times. Any time you spend making it faster will pay back many times over.
  6. Loop back to Step 2 until you reach the goal!

That's the broad schematic. You should be adjusting all of the steps along the way. For instance, if you learn that the subgoal is too hard, you can always pick a new subgoal.

I have a paid course on REPL-Driven Development that goes over all of this much more completely and deeply. I've made the flow lesson and the RDD overview lesson free for a short time. Do check them out!

Quarantine update 😷

I know a lot of people are going through tougher times than I am. If you, for any reason, can't afford my courses, and you think the courses will help you, please hit reply and I will set you up. It's a small gesture I can make, but it might help.

I don't want to shame you or anybody that we should be using this time to work on our skills. The number one priority is your health and safety. I know I haven't been able to work very much, let alone learn some new skill. But if learning Clojure is important to you, and you can't afford it, just hit reply and I'll set you up. Keeping busy can keep us sane.

Also, if you just want to subscribe for a paid membership, I have opened them back up for the moment. Register here.

Stay healthy. Wash your hands. Stay at home. Wear a mask. Take care of loved ones.

Clojure Challenge 🤔

Last week's challenge

The challenge in Issue 389 was to implement English-language title case. You can find the submissions here.

Please do participate in the discussion on the gist where the submissions are hosted. It's active and it's a great way to get comments on your code.

This week's challenge

Factors to string

Any integer can be written as a product of prime numbers. This is called the number's prime factorization. For instance, 24's prime factorization is 24 = 2 x 2 x 2 x 3 or even better 24 = 2 ^ 3 x 3. For this exercise, we are given the prime factorization. We have to construct the string representation.

Examples:

(factors->string [2 2 2 3]) ;=> "24 = 2^3 x 3"
(factors->string [7]) ;=> "7 = 7"
(factors->string [2 2 7]) ;=> "28 = 2^2 x 7"

Just for clarity, here are the rules:

  • If the prime factor appears only once, just use the number by itself (i.e., "2")
  • If the prime factor appears more than once, use the exponent notation (i.e., "2\^3")
  • If there is more than one prime factor, separate them with an "x" for multiplication (i.e., "3 x 7")
  • Start the string with "n =" where n is the number that has been factorized. You can calculate this by multiplying all the factors together.

What's a first piece could break off of this that makes progress toward the goal? How can you write it and quickly test it at the REPL?

Thanks to this site for the challenge idea where it is considered Hard level in Ruby.

You can also find these same instructions here. I might update them to correct errors and clarify the descriptions. That's also where submissions will be posted. And there's a great discussion!

As usual, please reply to this email and let me know what you tried. I'll collect them up and share them in the next issue. If you don't want me to share your submission, let me know.

Rock on!
Eric Normand