What will increase your programming productivity the most?
This is an episode of Thoughts on Functional Programming, a podcast by Eric Normand.
Lisps have traditionally been highly interactive. This allowed AI researchers and language developers to iterate quickly and learn about what works and what doesn't. How can you tap into this in your workflow?
Eric Normand: What is the single most important thing you can do to both increase your productivity and programming and also to learn faster?
My name is Eric Normand and these are my thoughts on functional programming. This is not actually directly related to functional programming; it's orthogonal to the paradigm. It's kind of related because the answer that I want to give is that you want fast feedback.
The language that started the whole live coding thing, as far as I know, is Lisp. It's a functional language. It's kind of tangentially related. In Lisp, you have a REPL and you're coding to a live environment. The compiler is always available to you. You're in an environment, you're adding code, you're compiling it and you're adding values to the global namespace.
That lets you do so much in terms of learning. You're going to very quickly test something out, change one little thing, see what it does, change another little thing, see what it does. For learning, you're actually always learning two things. You're learning the domain, like what are you programming about. Is it an accounting system? Is it a database? Is it an e-commerce system?
You're learning about the domain and how best to represent it. You're also learning the language, and the system and the environment it's in. You're learning, "What does this function do if I can put in a nil for the second argument? Can I access this database in constant time so I can do it in a loop?" You're constantly asking these kinds of questions.
The REPL has the answers. The REPL has all the answers because it's just like the live system. It's just like running in production. The learning and the programming are actually just the same things. You're always learning about how best to program the system and how best to represent your domain. That's what programming is.
I actually was talking to someone yesterday who, totally new to Clojure, got [inaudible 3:19] up and running with a framework that was totally unfamiliar to him. Because it had such fast feedback, he could change one little value in the program. He had a simple program that came with the [inaudible 3:39] tutorial. He could change one thing and see what happen, change another thing and see what happen.
Because he could make such small changes, he was never that far away from the working program. He could really understand every little bit that he needed to, to get what he needed done, done. Now imagine if you had a slower feedback loop, he could do this within a second. Make a change, save the file and within a second you see the difference in the GUI and on the web browser.
Not exactly a REPL, but for something that's very GUI and intensive, that's what you want. You want to see the change right away. He was able to learn this thing. Imagine if he did have a slower feedback loop, he would start to feel the pain of, "God I want to try one more thing. Why don't I think about it a little more? Why don't I try to guess what it's going to do?"
It's faster to guess. Sometimes you guess right and you save that time of having to test it, whereas if you had a fast feedback loop you wouldn't have to guess. You could get it right or you could get it wrong ten times and finally find the right answer. This is the thing that I probably think Clojure does the best. Clojure is pretty good at functional programming. It's pretty good with concurrency.
Those things are important and it's pretty good. It's good. It's good enough. It's better than good enough for those things. There's a lot of competition for functional programming. There's a lot of competition for concurrency. That fast feedback, I don't know if anyone can keep up. I mean, maybe other Lisps. Common Lisp makes it really easy. Racket makes it easy. Skin makes it easy.
Clojure also makes it easy on both GVM and ClojureScript and the browser or on node. It's one of the things that I set up. I spent a lot of time setting up so that I can move quickly. I don't want to have to guess so much and make assumptions. I just want to be able to try it out, ask questions.
If there's one thing that marks an expert Lisp programmer over a beginner Lisp programmer, it's reliance on the REPL. A master will do the REPL more. One thing I encourage my students to do as much as possible is, don't ask me questions like, "What does map do again?" It's like don't ask me, ask the REPL.
What if I don't know? What if I'm wrong? The REPL is never wrong. I'm wrong all the time and sometimes I don't know and I'm going to ask the REPL. That's going to be my way to figure out the answer to your question. Figure out a way to do a tiny little experiment that you can do right in the REPL that will have a hypothesis. The hypothesis is that nils are going to crash this function.
Then run it on NIL and see. If you are trying to get better at Clojure or any other Lisp for that matter, I would say that a huge thing is asking the REPL more questions. If you're confused about how does this thing work, get into a REPL, set up a little experiment and try to figure out yourself using the REPL the answer to your question.
Besides that, the other technique that is very common for working in the REPL is to work inside out. In small pieces, evaluate the forms that you would put in the function. Write the function and if there's four steps that you want to complete, make it output the first step and see if that's right. Then, do the second step with the output of the first step and see if that one is right.
Then, add the third step and add the fourth step. Eventually, you've got a debug. If debug did one step at a time instead of writing out all four steps down, then seeing if the answer is wrong, you don't know what happened. If you did do that and you're like, "I don't know what happened", break it down. Comment out the three steps and just start with one. "Did I get that first thing right?"
It might seem slower because sometimes you would get it right the first time in those four steps. In general, you're not going to get it right. Doing smaller steps is easier to stay within a working program. This is my thoughts on fast feedback.
Not exactly functional programming related but tangential, and still something I'm super interested in. Those are my thoughts. Do it. Fast feedback. As fast as possible. See you all later. Bye.