PurelyFunctional.tv Newsletter 395: types depend on context

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

Issue 395 - September 14, 2020 · Archives · Subscribe

Clojure Tip 💡

types depend on context

Longtime reader Tim Cross mentioned something important in response to my last newsletter. He said that when forced to use JavaScript, he prefers types (from TypeScript). On the other hand, he doesn't encounter nearly as many type errors in ClojureScript as he does in JavaScript. It's interesting to think about typed vs untyped as one aspect of overall language design. What are the aspects of a language that would make a type system less useful, to the point where having one would get in the way more than help?

I think one aspect is the abstractions over types that we have in Clojure. For instance, in Clojure, the sequence operations work on all collections, as well as Strings and nil. That abstraction lets us easily forget about the concrete types we have and think instead about sequence or non-sequence. Clojure provides a very useful handful of such abstractions and consistent operations over them.

Even still, we use fewer types in Clojure in general. At least it feels like we do. Strings, Numbers, Booleans, Vectors, Maps, etc. It's a small core list, then we have a few extra classes we might use in particular domains, such as URI or File. But otherwise, we're operating more on structure than on types.

I think Nil Punning has a lot to do with it as well. As we get more skilled in Clojure, we get a sense of what kinds of code will safely deal with nils without us doing anything. I wish it wasn't something you have to learn tacitly with a lot of experience. It's bad for beginners and it's not likely to be fixed or even documented because many people eventually grow out of it. But in my conversations with Clojurists, there seem to be people who complain a lot about NullPointerExceptions and those who don't encounter them that much. It would be really nice to figure out what secret they're using.

Finally, I think immutability plays a big role. Algorithms in a language like JavaScript often rely on local variables being set inside of conditionals. That means the type of the value in the variable changes depending on the branches that were executed. It's just easy to get things wrong with different types in different branches.

I don't think I've really gotten to the bottom of why types don't feel so necessary in Clojure. Either way, it was worth exploring. But this idea does point to types being used as a bandaid, like linting, to enforce a good subset of a bad language. I wonder what a type system that made Clojure feel better would look like.

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

Issue 394

There were tons of clever ways to do FizzBuzz without conditionals or loops.

Please do participate in the discussion at the submission links above. It's active and it's a great way to get comments on your code.

This week's challenge

Big change: Please submit your solutions as comments on the gist linked below.

Seasons

Well, it's Hurricane Season here in the Gulf South. But that's not the kind of seasons I'm talking about now.

Your job is to take a month (keyword) day (number) and a hemisphere (:north or :south) and determine which season it is (return a keyword), according to this handy table.

Start       End         North  South
March 1     May 31      Spring Autumn
June 1      August 31   Summer Winter
September 1 November 30 Autumn Spring
December 1  February 29 Winter Summer

Example:

(which-season :north :march 5) ;=> :spring
(which-season :south :december 25) ;=> :summer

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

Please submit your solutions as comments to this gist. Discussion is welcome.

Big change: Please submit your solutions as comments on the gist linked above.

Rock on!
Eric Normand