PurelyFunctional.tv Newsletter 342: Tip: learn to read Javadocs

Sign up for weekly Clojure tips, software design, and a Clojure coding challenge.

Issue 342 - September 02, 2019 ยท Archives ยท Subscribe

Clojure Tip ๐Ÿ’ก

learn to read Javadocs

This tip is inspired by a list of great beginner mistakes by Jakub Holรฝ. Last week's was, too, but I forgot to mention him. Thanks Jakub!

Clojure relies on the host language more than other languages do. There aren't wrappers for even a lot of the common operations on basic data types. For instance, I still use a lot of the methods on String, a lot of the mathematical functions (on the Math class). And of course, when I'm using a Java library through interop, I'm dealing directly with classes and methods.

Java's auto-generated documentation is great. It was revolutionary at the time it came out (HTML documentation? in 1995?). It was way ahead of its time. It manages to fit a lot of dense information into a small space without feeling like you'll get lost. The standard library is pretty well documented, as are most popular libraries. When I'm doing interop, I spend a good amount of time in the Javadocs.

Read: Javadocs section of The Definitive guide to Clojure on the JVM Watch: Javadocs lesson of JVM Fundamentals for Clojure

Follow-up ๐Ÿ™ƒ

Sean Corfield had even more recommendations for ns declarations:

  1. Alphabetize your requires.
  2. Use more meaningful (less cryptic) namespace aliases. Use the last segment of the namespace as alias unless
  • It is ambiguous or uninformative (as in lib4clj.core). In that case, pick another segment.
  • It is unwieldy and an obvious abbreviation is better (str for clojure.string)

These sound like great recommendations to me!

Book status ๐Ÿ“–

My book is selling better than I could have expected. I'm getting lots of kind words about it and some good critique. I just want to say 'thanks'. You rock!

You can find my book, Grokking Simplicity, here. Manning is selling all ebooks for \$20 on Monday, so get my book and as many others as you can.

Currently recording ๐ŸŽฅ

Property-Based Testing (PBT) is challenging. It forces you to think. It forces you to understand your system deeply. It requires a lot of work.

But that work pays off. Property-Based Testing finds bugs. In the lesson I recorded this week, we test two systems. Each system had race conditions. And we wrote tests that failed because of those race conditions.

Race conditions are hard to reproduce. They only happen sometimes, so at best they create unreliable example-based tests. But with some threads and some loops, and some randomly generated input data, we manage to reliably trigger the race conditions. That's significant.

What's more, we got very small failing cases. The failures were reliable enough to shrink the input most of the time. That's another big win for understanding the failure.

This is where Property-Based Testing clearly has benefits over example-based testing. PBT seems like overkill at first, but once mutable state is involved, it can test a system more thoroughly than examples. It can find sequences of operations that break invariants. And it can find race conditions.

Check out the new lesson here: Testing parallel systems. It's almost 1.5 hours long, but it builds the tests up in understandable steps.

Brain skill ๐Ÿ˜Ž

master the basics

Should programmers be fast typists?

One answer is: Programmers don't need to type fast because programming is not about typing. Most of the work is done in your head.

Then why do programmers insist on using IDEs instead of text editors? Why do they invest in configuration and plugins? Why do they choose to memorize hundreds of keyboard shortcuts and arcane commands?

I think there are two reasons. One is that since typing is not important, you want to get it done as quickly as possible so that the time you spend on it is proportional to the importance. In other words, if you type slowly enough, programming is about typing. A slow typer spends too much time and energy pressing keys. That time could be spent thinking.

The other reason is that as you gain proficiency with text manipulation, you can operate closer to your thoughts. For instance, if you know paredit, you operate on s-expressions. You are performing operations much closer to the code you are trying to write than you are if you're backspacing and typing characters. Likewise for keyboard commands that jump forward a word or a sentence. If you're write a document, words and sentences are your bread and butter.

Speed is not directly important. If you could write the code correct the first time, it wouldn't matter if you were slower. But that's not how it works. You type it, you test it, and then you debug it. Slow typing gums up that whole process.

My opinion is that mastering the basics really matters. You want to be fast and accurate with the basic skills, such as typing, recalling the clojure.core functions and argument orders, the semantics of the common expressions, etc. These things are important because you need to get them right. But they are not the end goal, which is to be manipulating thought-stuff. So practice getting good at them to the point where they are automatic. That's where programming begins to get interesting.

Clojure Challenge ๐Ÿค”

Last week's challenge

The puzzle in Issue 341 was to write a function to return a lazy sequence of the permutations of a collection.

You can check out the submissions here.

This was a tough one. I'm glad we have clojure.math.combinatorics. I like the implementation there because it is a great example of the lift-solve-lower pattern.

It turns out it's easier to find the permutations of a sorted sequence, so lift the original problem into a sequence of indexes, permute the indexes, then lower them by mapping them back to the elements of the original sequence.

(let [v (vec items)]
  (map #(map v %) (lex-permutations (range (count v)))))

This week's challenge

ajax state problem

AJAX calls in ClojureScript go through a lifecycle. They are placed, they're in flight, then they either succeed or fail. We often want to show this state to the user. For instance, when the ajax request is in flight, we want to show a loading spinner.

Create a representation of the state of a value that can be fetched via ajax. I suggest using the variant entity or the variant tuple. It may help to draw out the sequence diagram of an ajax request to capture all the states it may be in. Be sure to define the operations on this representation which transition it from one state to the next.

If you want some inspiration, Kris Jenkins has a neat post about modeling remote data. I've also written up two ways of approaching ajax state here.

As usual, please send me your implementations. I'll share them all in next week's issue. If you send me one, but you don't want me to share it publicly, please let me know.

Rock on! Eric Normand