Refactoring To Closures in Kotlin & IntelliJ

I spent yesterday morning practicing a refactoring in Kotlin I wanted to potentially demonstrate for a workshop, and after half a dozen unsuccessful attempts, I found a way that seems relatively safe. I thought it might be useful to document it here, both for myself for the future and anyone else who might be interested.

My goal here is to encapsulate the data used in this function for calculating quotes for fitted carpets. The solution I’m thinking of is closures.

How do I get from this to closures being injected into quote() safely? Here’s how I did it in IntelliJ.

  1. Use the Function to Scope… refactoring to extract the body of, say, the roomArea() function into an internal function.

2. As a single step, change the return type of roomArea() to a function signature that matches area(), return a reference to ::area instead of the return value from area(), and change quote() to invoke the returned area() function. (Phew!)

3. Rename roomArea() to room() so it makes more sense.

4. In quote(), highlight the expression room(width, length) and use the Extract Parameter refactoring to have that passed into quote() from the tests.

5. Now we’re going to do something similar for carpetPrice(), with one small difference. Next, as with roomArea(), use the Function to Scope refactoring to extract the body of carpetPrice() into an internal function.

6. Then swap the return value with a reference to the ::price function.

7. Now, this time we want the area to be passed in as a parameter to the price() function. Extract Parameter area from price(), change the signature of the returned function and update quote() to pass it in using the area() function. Again, this must be a single step.

8. Change the Signature of carpetPrice() to remove the redundant area parameter.

9. Rename carpetPrice() to carpet() so it makes more sense.

10. Extract Parameter for the expression carpet(pricePerSqrMtr, roundUp) in quote() called price()

 

If you want to have a crack at this yourself, the source code is at https://github.com/jasongorman/kotlin_simple_design/tree/master/fp_modular_design , along with two more examples (an OO/Java version of this, plus another example that breaks all the rules of both Simple Design and modular design in Kotlin.

 

S.O.L.I.D. in Kotlin

My journey of demonstrating how S.O.L.I.D. design principles can be applied in a range of programming languages going back 50+ years gets bang up-to-date with an example in Kotlin.

Now, you could probably argue that Kotlin is a no-brainer where this is concerned. Anything I can do in Java I can do in Kotlin, if I choose to. Kotlin has classes, interfaces and constructors. We can make data private just as easily as in Java. But still, I hear objections from developers doing pure FP in Kotlin that either:

a. “OO” design principles don’t apply (which is why I’ve stopped calling them that – they’re modular design principles), or…

b. We don’t need to apply S.O.L.I.D. to functional programming, because FP is innately S.O.L.I.D. (Spoiler Alert: it isn’t.)

Whereas with older languages like C and Fortran 77, I’m working harder to get around some language limitations, with languages like Kotlin and Clojure, I’m having to work harder to get around cultural limitations. To be fair, this is not a new phenomenon. I can clearly recall programmers telling me – in the heydey of OOP in the mid-to-late 90s – that you didn’t need to think about things like modularity because OOP is innately modular. (Spoiler Alert: it wasn’t.) Give a C programmer C++ and they’ll write you procedural C++ code. And, as my previous post illustrated, give a C++ programmer C and they’ll find a way to create objects with it.

I define code that’s effectively modular by three key properties:

  • It’s made of discrete parts that do one job each
  • Those parts know as little as possible about each other
  • Those parts are easily swappable

There’s no programming language on Earth that forces us to write code that ticks all three boxes. You have to tick the boxes yourself by the design choices you make.

Granted, there are things we need from a programming language to enabe effective modularity:

  • The ability to break code up into discrete reusable units (i.e., modules)
  • The ability to control what client code can see of a module (or – in the case of Ruby, Python, JS etc – the ability to make that not matter with dynamic binding)
  • The ability to dynamically substitute a different implementation without re-writing the client code

These days, the vast majority of programming languages available to us score 3/3. There are some older languages that offer no mechanism for polymorphism, but you’re very probably not using one of them on a regular basis. You can even do it to a limited extent in Fortran 77. Any language that allows us to pass a function or procedure pointer/reference as a parameter is technically polymorphic.

Anyhoo, here we are in 2019, and the shiny new kid on the code block is JetBrain’s Kotlin. It’s a derivative of Java, with spiffy FP sensibilities. To an old Java hand like me, it takes no time at all to learn. Here’s the carpet quote example in Kotlin.

Again, the first problem that leaps out at me is that this function is doing more than one thing. It breaks the Single Responsibility principle. Let’s refactor each reason to change into its own function in its own module.

The next thing that’s bothering me is that our data classes Room and Carpet are unencapsulated. That’s always bugs me. In OO design, we say that data classes are a code smell. They hurt us in FP, too. A dependency’s a dependency. Let’s refactor our area() and price() functions into closures that hide the data from quote().

And yes, I would just as readily use a class instead of a closure. I’m not an FP purist.

This refactoring has killed two birds with one stone: we’re hiding the data from quote() and now we can easily swap in a different implementation for calculating room area and carpet price without changing quote().

For example, what about a circular room?

That ticks the O, the L and the D in S.O.L.I.D. – our dependencies are now easily swappable. So, so far, we’ve covered S.O.L.D. as well as Tell, Don’t Ask.

What about Interface Segregation? Well, unlike many languages that support FP, Kotlin also has direct support for classes that implement multiple client-specific interfaces. If we can do it in Java, we can do it in Kotlin.

Tick.

 

You can view the source files at https://github.com/jasongorman/kotlin_solid

Refactoring To Higher-Order Functions

In my last post, I demonstrated how we might refactor a simple object oriented piece of code into a functional style with a JavaScript example. The focus of that example was about how to get from instance methods that access mutable fields to stateless functions that use immutable data structures.

I wanted to follow that up with a slightly more sophisticated example to illustrate how we might refactor from an OO design that uses dependency injection to an FP design that uses higher-order functions.

Let’s do it in Ruby this time.

Here we have a class that writes customer data in a variety of formats – XML, HTML and andstrings – to a variety of output destinations – console, log file and NoSql database.

The serializers all present the same interface, with a write() method that accepts a customer parameter. A good first step might be to pass in lambda that invokes the serialize() method instead of invoking it on the serializer instance inside write().

So far, so ugly. Next we can make all our serialize() methods unique.

Then we can clean things up by turning these instance methods into standalone functions. e.g.

…allows us to re-write the client code more cleanly.

We can rinse and repeat for the output writers. Start by passing in lambdas that invoke their write() methods.

Then make each write() method unique.

Now, the next part is a little fiddlier. We want to turn these methods into standalone functions. For the console writer, it’s simple because write_console() is stateless, so we don’t have any fields to worry about.

But write_logfile() and write_nosql() access fields that are set in constructors. In the previous post, I illustrated how we can refactor from there. All the information those methods need can be passed in as arguments.

Now we can make them standalone functions.

And a final bit of tidying up: if we turn our write_logfile() and write_nosql() into closures, with the outer functions acepting all the messy extra parameters, we can simplify our client code.

Last, but not least, we get rid of the ResponseWriter class, making its write() method a standalone function.

 

 

 

 

 

Refactoring to Functions

While I’ve been porting the Codemanship Software Design Principles code examples to JavaScript – in both OO and FP styles – I’ve been thinking a lot about the relationship between those two programming styles.

Possibly the best way to illustrate might be to refactor an object oriented code example into a functional example that’s logically equivalent. This might also serve to illustrate how we might move from one style to the other in a disciplined way, without breaking the code.

This is the simple class I’m going to start with.

And these are its tests.

The first refactoring step might be to make each method of the class properly stateless (i.e., they don’t reference any fields).

To achieve this, we’ll have to add a parameter to each method that accepts an instance of BankAccount. Then we replace this with a reference to that parameter. This will work if the BankAccount we pass in is the exact same object this refers to.

So, in our tests, we pass in the BankAccount object we were invoking credit() and debit() on.

Now we can pull these instance methods out of BankAccount and turn them into global functions.

The tests can now invoke them directly.

One last piece of business: the BankAccount data object. We can replace it in two steps. First, let’s use a JSON version instead that matches the schema credit() and debit() expected. To make this the smallest change possible (so we don’t have to re-write those functions yet), let’s make them mutable.

Then we can re-write credit() and debit() to return mutated copies.

This will require us to re-write the tests to use the mutated copies.

So, there you have it: from OO to FP (well, functional-ish, maybe) for a simple class with no collaborators. In the next post, I’ll refactor some a code example that involves several related classes so we can examine the relationshi between dependency injection and high-order functions.

 

Tell, Don’t Ask in Functional Programming

In my last blog post, I illustrated how S.O.L.I.D. design principles can be applied to functional programming with five JavaScript examples.

There’s more to modular design than SOLID, though. For example, what about encapsulation?

As I continue to port the Java and C# examples for the Codemanship software design principles course, I’ve reached Tell, Don’t Ask. Take a look at the example code for calculating how much to charge for a new carpet.

Here’s the thing about functions: when they act on data structures (like JSON objects or tuples), the relationship between data and the logic that acts on that data inherently becomes unencapsulated. That’s just a fancy way of saying that carpet_quote.js knows too much. It knows how to calculate the area of a room based on the length and the width. It knows how to round up the area of a carpet if required. And it knows how to combine these things to get a price for that carpet in that room.

How could we encapsulate each of these jobs so that carpet_quote knows less? The answer may lie in closures.

We can encapsulate calculating the area of a room inside an outer function that takes the length and width as parameters.

And we can encapsulate the knowledge of calculating the price for that area of carpet inside an outer function that takes the price per square metre and whether or not to round up to the nearest square metre as parameters.

Then we can rewrite quote() as a higher-order function (just a fancy way of saying “inject the functions it uses”) that knows a lot less.

The data required is no longer exposed to carpet_quote. Instead, it’s passed to the outer functions of the closures in the client code – acting effectively as constructors. (Yes, closures are a lot like classes, dontcha think?)

Each module now only has one job, and has no direct implementation dependencies. And it makes the logic of calculating room areas and prices swappable. This design ticks all three boxes of good modular design:

  1. Each unit does one job
  2. Each hides its inner workings (especially its data)
  3. Their dependencies are swappable (by injection)

Let’s say we wanted to calculate the areas of more complex rooms (e.g., L-shaped, circular). In the refactored design we can extend the solution without having to rewrite carpet_quote. So this design is S.O.L.I.D., too.

 

If you’d like to have a crack at refactoring the JavaScript design princples examples, you can find the source code at https://github.com/jasongorman/JS_design_principles

Functional S.O.L.I.D. Explained In 5 Examples

I’m in the process of porting the Codemanship course materials to Python and JavaScript. After I did the S.O.L.I.D. examples from the Software Design Principles workshop in JS, I thought it might be useful to illustrate how these “object oriented” principles can be applied to a more functional style of programming.

Single Responsibility

“Classes should have one reason to change.”

The rationale behind the SRP is simple: editing classes risks breaking the code in them. Once code is tested and out there working, we’d ideally prefer to leave it that way. If a class contains code that changes at different times for different reasons, the risk is of breaking code that really didn’t need to change just because it’s in the same class as code that did. (There’s another, much more compelling reason for our classes – and methods and functions – to do only one job, which is explained on the course.)

But “class” is a red herring here. Really, it’s sources files. (Or modules.) Editing code in a source file risks breaking other code in the same file.

For example:

Here I can easily imagine wanting to change the XML output without changing the logic of a bank transfer. This module has two reasons to change. So we should split it up.

Open-Closed

“Classes should be open to extension and closed to modification”

Once a class is tested and released, modifying it risks breaking it – and any code that depends on it. A safer way to add functionality to an existing system is to extend the existing code without editing it.

This means our code needs to be designed in a way that makes extending easy. Now, this design principle arguably belongs more in the days of C++ and a few other statically-typed languages where, if you want a class to be open to extension, you have to design it a certain way (e.g., any methods you plan to override need to be declared as virtual. The love for pure interfaces for everything was born of this era.)

In the modern era of dynamic languages and duck typing, it’s very easy to swap one implementation with another – provided the client hasn’t directly referenced that implementation (which is what the D in SOLID is all about.)

Back in the day, we no doubt had inheritance in mind. But that has very much fallen out of favour in recent years, and now many developers prefer composition instead. A subclass that presents the same interface as a base class, and delegates method calls to an instance of the base class internally is logically the same as implementation inheritance.

The functional equivalent of that would be a function with the same signature as the “base” function that internaly delegates to it.

Imagine we wanted to extend a function for borrowing videos from a library so that we can prevent people from borrowing titles they’re too young to see:

All we have to do is create a new function that has an identical signature, that calls the original borrow() function.

Liskov Substitution

“An instance of a class can be substituted with an instance of any of its subclasses”

The example above solves the problem of syntactic swappability of a function with an extended version that has the same signature. But… it’s not quite as simple as just syntax in many cases of extension.

First of all, you may have noticed that the extended function relies on customers having an age, and videos having a rating. We didn’t just extend the function, we extended the data structure (in this case, the JSON object) the function accesses. Any client passing in the old data structure will cause an unhandled exception.

Also, the client could be in for a nasty surprise if the customer is too young for the video they’re borrowing, in the shape of an unexpected error. We’d have to rewrite the client code. Ths is how ripples start in our code that can spread from the module we changed/extended to the rest of the code, making even the smallest changes very expensive.

Ideally, we want to be able to extend the software without having to rewrite client code. And that means, in practice, that – as far as existing clients are concerned – the contracts for calling functions must still hold.

The original borrow() function has no precondition. Any customer can borrow any video. The extended version requires the customer be old enough. So there are scenarios for using borrow() the client thinks are valid that no longer are. (Imagine turning up to the airport with your ticket and your passport, and not being allowed to board the flight because, on your way to the airport, they added a requirement to bring the pilot a bunch of bananas.)

Consider this simple bank account module:

We’re asked to extend it so that customers can withdraw beyond the balance up to an agreed overdraft limit. In an FP style, this just means “overriding” the debit() function.

So far, soo good. This works syntactically. Anywhere clients expect the original debit function, we could substitute the new version. But have we broken the original contract?

One way to check would be to somehow run the original bank account tests against the new implementation. Right now, they look like this:

As they are, it’s not possible to swap in the new implementation because the tests directly reference the old one. What if we refactored the tests to look like this?

Now we can run the same tests with two different implementations of debit(), and two different versions of the account object. Now, I wonder what happens when I run these tests…

 

Interface Segregation

“Classes should present client-specific interfaces”

Back in the days when C++ ruled the world, if I changed a class’s interface (e.g., renamed a method), all the code that referenced that class had to be recompiled, re-tested and re-deployed. Unavoidable if those clients use that renamed method, but totally avoidable if they don’t, by extracting interfaces that only include the methods they actually do use.

In FP, there are no interfaces. Or, rather, every funtion can be thought of as an interface with only one method. Add to that dynamic binding, and the problem goes away. So, arguably, a discussion about Interface Segregation is moot.

But in the heat of battle, as functions evolve and move between modules, and dependencies change, it’s entirely possible for one module to end up directly referencing functions and modules they no longer use. The effect is the same.

Although this module only uses the rating() function from book.js, it references two other exported functions. If I were to, say, move summarize() to a different module, this code breaks.

So, in FP, we might re-frame Interface Segregation as:

“Modules should only reference things from other modules they actually use”

Dependency Inversion

“High-level modules should not depend on low-level modules. Both should depend on abstractions.

Abstractions should not depend on details. Details should depend on abstractions.”

This is a rather hifalutin way of saying that dependencies between modules should be swappable.

Consider this example:

This is a poor design. How do we add new kinds of output format without modifying this write() function? That breaks the Open-Closed principle. OO languages give us a simple mechanism for making choices without the nastiness of enums and conditionals: polymorphism.

FP gives us exactly the same mechanism. Two functions with the same signatures can be invoked by the same client, without the client knowing which implementation it’s using. From the outside, they look exactly the same.

If we refactor write() to remove direct references to the implementations, and inject the output function from the outside, we can make that dependency easily swappable and our design easily extensible.

Now the client decides which output function to use:

Notice that all the implementation references are at the top of our call stack now. This is the effect that composing functions (and objects in OOP) by dependency injection tends to have.

Dependency Inversion (and dependency injection that enables it) is as much a foundation of good, extensible FP as it is of good OOP. You may have noticed how many, many staples of the FP paradigm – e.g., map(), filter() and reduce() – work by allowing us to pass in functions that are invoked inside without having to anything about the function being called other than its signature.

 

So there you have it: S.O.L.I.D. applied to functional JavaScript in five examples. If you want to take a more detailed look at the example code and try the refactorings for yourself, it’s all on https://github.com/jasongorman/JS_design_principles

And if you’d like Software Design Principles training and coaching for your team, you know where to find me.