Posted on

# TPP Topic topic-30: Transforming Programming

This post originally appeared on steadbytes.com

See the first post in The Pragmatic Programmer 20th Anniversary Edition series for an introduction.

## Exercise 21

Can you express the following requirements as a top-level transformation? That is, for each, identify the input and the output.

1. Shipping and sales tax are added to an order
3. Someone logs in to a web application
1. `initial_order -> final_order`
• `initial_order` represents the unprocessed data of an order - e.g. the cost and quantity of each item.
• `final_order` represents an order that has been processed/transformed into a shippable state with shipping and sales tax calculated and included appropriately.
2. `config_file_name -> config`
• The configuration file is read and it's contents are transformed into a data structure to be used for configuring the application.
3. `user_credentials -> user_session`

## Exercise 22

You’ve identified the need to validate and convert an input field from a string into an integer between 18 and 150. The overall transformation is described by

``````field contents as string
→ [validate & convert]
→ {:ok, value} | {:error, reason}
``````

Write the individual transformations that make up validate & convert

``````field contents as string
-> [convert to integer]
-> [18 <= value <= 150]
-> {:ok, value} | {:error, "value not 18 <= value <= 150"}
``````

## Exercise 23

In Language X Doesn't Have Pipelines, on page 153 we wrote:

``````const content = File.read(file_name);
const lines = find_matching_lines(content, pattern);
const result = truncate_lines(lines);
``````

Many people write OO code by chaining together method calls, and might be
tempted to write this as something like:

``````const result = content_of(file_name)
.find_matching_lines(pattern)
.truncate_lines();
``````

What’s the difference between these two pieces of code? Which do you think
we prefer?

The second piece of code uses a fluent interface, whereas the first 'chains' isolated functions together by explicitly passing the result one function call to the next. The difference here is that each function call in the fluent interface is a method on the object returned by the previous call; the object returned by `find_matching_lines` must implement a `truncate_lines` method. This introduces tight coupling to the 'pipeline' code and the objects used within it. Changing the pipeline behaviour is more difficult as one needs to decide which object a given transformation should be attached to. For example, say the requirements change such that the output must all be lower case. In the first piece of code, this is trivial:

``````const content = File.read(file_name);
const lines = find_matching_lines(content, pattern);
const lower_case_lines = to_lower_case(lines);
const result = truncate_lines(lower_case_lines);
``````

In the second piece of code however a decision needs to be made as to where the `to_lower_case` functionality should be implemented: perhaps it should be on the object returned by `File.read`, or maybe on the object returned by `find_matching_lines`. Depending on what those objects actually represent it may not make semantic sense to have a `to_lower_case` method in the general case. Furthermore, there is the possibility of breaking other code which uses the changed object.

I'm 100% certain that the authors prefer the first piece of code 😄