I'm working on some code that takes search criteria from a Rest API and uses it to query a remote API to return results. As an exercise, I wanted to try to separate all state changes to one place, as a language like Haskell would force you to (even though I'm programming in Java in this example).

At first this was straight forward: Separate the code that generates the query from the code that executes the query. The code that executes the query can be ignorant of the query it gets.

But now I have a new requirement that works like this: If someone searches for all things under a parent folder, then I need to run two queries. One to find the path of that parent folder then another to find all things that start with that path. I cannot use subqueries to do this in one query, the remote api does not allow it.

I can't figure out how I could cleanly design this. For this special case, the first query needs to get outside the "pure" code, be executed, then the result needs to be passed in to different "pure" code so the result can be executed as the second query.

How would this be cleanly designed in a functional programming language? Keep in mind, tomorrow I may get a new requirement that requires me to run 3 queries to get the final result.

  • What is a "mutation?" This isn't a genetic algorithm, is it? Feb 10 '15 at 23:48
  • 1
    @RobertHarvey I thought that is the opposite of immutability: mutability. And I thought the plural form is "mutations". Is there a better word/phrase? Feb 10 '15 at 23:50
  • Well.. State changes, it doesn't mutate. A mutation implies an error in transcription. Mutability is an adjective; there is no plural form (you don't say "mutabilities"). Welcome to the English language. Feb 10 '15 at 23:54
  • Thanks. Can you make your description of "queries" a bit more concrete? Also, the knee-jerk answer to your question is probably "use a monad." Feb 10 '15 at 23:58
  • 4
    @RobertHarvey A mutation doesn't have to be an error. It's simply a "change or alteration". I don't see any problem with saying a mutable object can mutate its state.
    – user76704
    Feb 11 '15 at 0:04

The most common pattern I see in these types of situations is to use a CompletableFuture, which most FP languages just call a plain Future. It allows you to execute something long-running like a query, then specify actions to take later. If the query succeeds, the result is passed to the next action in the chain. If it fails, all the subsequent actions are skipped, and a failure action is called instead.

I haven't personally done this in Java, so I can't speak to the ease of use of this particular implementation, but it's a lifesaver in JavaScript.

  • you're actually describing a type of exception monad (maybe, or either both fit your description of "success continues, failure halts"), which is actually something I've used for graph walking/filtering etc in just the way you describe in C#, it's quite a handy approach for this purpose. A future is more about pushing off asynchronous work, composing queries doesn't require asynchrony so much as some variable that can hold the query so it can be passed around for composition (higher order functions for instance tend to fill this purpose). Feb 11 '15 at 16:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.