Customer Stories

Technology The New Normal How We Work Customer Stories Testing | All Topics

Streamlining Clinical Trials: A Case Study with Reify Health

Challenge

New, potentially life-saving treatments have to go through a series of lengthy, expensive clinical trials to reach patients. Biopharmaceutical companies must invest significant resources over many years to complete a number of clinical trials that show a new treatment is safe and effective. Any inefficiencies in the trial process make it harder to bring new treatments through clinical development. This means patients wait longer for new treatments to reach them and many potentially safe and effective new treatments don’t make it to patients at all.

The founders of Reify Health believe that the healthcare system can do better. They have developed a new way for biopharmaceutical companies to run clinical trials using modern web technologies to make the trial process more transparent and predictable. Ultimately, Reify’s products allow biopharmaceutical companies to complete trials more efficiently and get new treatments to the patients who need them more rapidly. They chose Clojure and ClojureScript as the technical foundation for their application; their team was able to pursue a more nimble development process, incorporating end-user feedback, to release a better application sooner. 

Solution

From the very start, Reify’s leaders wanted to build a system based on user feedback to ensure that it would solve their specific challenges. To do this, they wanted to be able to quickly iterate on the product and continually release it for validation by the target users.

Clojure enabled the development team to work in a single language across the entire application, from user experience to back-end services and everywhere in between. This reduced friction for the developers as they moved around the codebase, which increased the speed of and confidence in their releases. ClojureScript was used on the front-end and was able to provide all the benefits of Clojure with immutable data structures while still providing access to the whole JavaScript ecosystem. Clojure was used on the back-end and similarly, in addition to its inherent simplicity and power, brought the maturity and stability of the JVM and access to the Java ecosystem. 

To take their rapid development to the next level, the Reify team leveraged a unique feature of Clojure, clojure.spec. It enabled them to write specifications for all the data structures in the applications to not only ensure data integrity, but also generate sample data. This enabled them to build a rich, functional application front-end with life-like generated data for the express purpose of getting feedback to guide them in the design of the product.

After validating the fitness of the design, they were able to build out the server rapidly with code reuse due to the single language paradigm. Clojure.spec was put in place at the system boundaries to lay the foundation for data integrity. 

Technical Benefits

Using Clojure and clojure.spec enabled the development team to move fast, get feedback, and ultimately build an application to streamline clinical trials. By leveraging the unique aspects of clojure.spec, they were able to generate complex life-like sample data structures as well as later reuse them across the client and server to ensure data integrity. The use of a single language with Clojure and ClojureScript across the front and back-end allowed faster development and sharing of code. 

Business Benefits

With Cognitect and Clojure, the Reify team was able to rapidly deliver an application to streamline clinical trials. The ability to iterate quickly, with real end-user feedback, helped create a product that better met the needs of its audience and delighted its users. By using clojure.spec and the simplicity and composability of Clojure, they were able to save time and money and have a sound, quality product that will improve healthcare. 

Cognitect Consulting

Cognitect consulting provided embedded support for the technology and development. Partnering with Reify enabled the team to have seasoned developers working alongside them on a daily basis to bring the application to life. Their team had the confidence that any technology challenges that they encountered would have access to in-depth expertise that Cognitect provides as stewards of the Clojure language. 

Developing the Language of the Domain

2U, a company that provides the technology, services and data architecture to transform its clients into digital universities, asked for Cognitect’s help making their operations more efficient. They had a deep client-onboarding pipeline, constrained by the speed of content-creation, and they wanted to eliminate unnecessary bottlenecks in their software systems.

Iteration Zero

During our Iteration Zero, we worked with 2U engineers to sketch out a high-level view of their software architecture, with a particular eye toward information flows. As this diagram grew to cover most of a conference-room wall, it became clear that the architecture had a lot of moving parts and information silos, not surprising for a successful startup after several years of rapid growth.

The key insight of the architecture review was that 2U relied on people to move data between software systems — mostly content, but also configuration, access credentials, and design artifacts. Streamlining these processes meant not only building software systems that could communicate directly with one another, but also incorporating human work-products into an automated workflow.

The Language of the Domain

Working with a mixed team of developers and operations specialists at 2U, we set out to develop a model of the business domain. It started with a simple question: What types of entities — what kinds of stuff — do you work with? Programmers may recognize this as a classic object-oriented design exercise, but we weren’t limited to object-oriented nomenclature or a complex modeling language such as UML. Instead, we took advantage of our primary tools, Clojure and Datomic, to let the customer lead us toward a model that was meaningful to their business.

As we collected answers to these questions, we could quickly encode them in Clojure’s Lisp-like syntax:

(entity University
  "An institution of higher learning"
  (attr :university/shortname string identity #"[a-z]{2,4}"
    "Unique, human-readable abbreviation for this university")
  (attr :university/full-name string non-blank unique
    "Fully-expanded name of the university for public display"))

(entity Program
  "Something offered by a school or college culminating in
  a degree or certificate."
  (attr :program/full-name string non-blank
    "Fully-expanded name of the program for public display"))

(relationship offers
  "Every Program is owned by a single University"
  [Program :program/university University]
  [University :university/programs Program many])

Although this looks like Clojure code, it’s just data. Clojure’s edn reader and clojure.spec made it easy to parse and load this data into a Datomic database. Then it was a simple matter of programming to transform it into a variety of representations.

The very first artifact we deployed at 2U was an internal web app to explore the domain model, including a graph visualization of entities and relationships:

To gather feedback, we printed a poster-sized version of the same diagram, hung it in a corridor next to a stack of post-its, and asked everyone in the company to suggest improvements.

As we collected feedback, we learned that almost every team had a unique perspective on the business. Some of the most commonly-used terms had widely-divergent definitions. It was not exactly a blind-men-and-elephant scenario: None of the definitions was actually incorrect, but neither were any of them complete.

The fable of the blind men and the elephant: Each perceives only one part, on which he bases his (incorrect) conception of the whole animal. By contrast, one team's understanding of a domain concept may be entirely correct for that team's work, yet still inadequate to represent that concept for the business as a whole.

The fable of the blind men and the elephant: Each perceives only one part, on which he bases his (incorrect) conception of the whole animal. By contrast, one team's understanding of a domain concept may be entirely correct for that team's work, yet still inadequate to represent that concept for the business as a whole.

Many of our collaborators told us this was the most valuable part of the process for them, as it expanded their understanding of the business and their role in it. We were applying agile software development practices to a fundamentally cognitive task. The goal was not to produce software but to better understand the domain, helping 2U to learn about itself. The software behind the model and visualizations was merely a means to that end.

A Foundation in Data

Even while the model was still evolving, Datomic’s flexible approach to schema enabled us to start work on a database of domain knowledge. Since Datomic schemas are themselves expressed as data, we could automate the process of keeping the database in sync with the domain model.

;; Sample Datomic schema elements generated from domain model
[{:db/ident       :university/shortname
  :db/doc         "Unique abbreviation for this university"
  :db/valueType   :db.type/string
  :db/cardinality :db.cardinality/one
  :db/unique      :db.unique/identity
  :db/index       true}

 {:db/ident       :program/university
  :db/valueType   :db.type/ref
  :db/cardinality :db.cardinality/one}]

When data is the foundation, repetitive programming tasks can often be replaced by higher-leverage meta-programming. With Datomic, Clojure, and clojure.spec, we took an abstract model and generated a database. Adding Pedestal into the mix, we generated web-service interfaces for managing information about entities in the database. Using ClojureScript, Om, and React, we deployed a series of “mini apps,” rich interactive forms tailored to particular business roles, all sharing the common back-end.

Since 2U was already using Slack for inter-team communication, we integrated a Slack “bot” into various team channels, posting notifications and reminders with direct links into the associated web apps. All of this information flowed back into a dashboard view to help project managers track work-in-progress across the organization.

Lessons Learned

When we started, our stakeholders at 2U had hoped to arrive at a “canonical” data model for a new system which would be the “source of truth” for the rest of the organization. We set out to iterate towards a canonical model on which everyone could agree.

Of course, building consensus takes time. We were fortunate to be paired with an energetic 2U project manager willing to spend long hours asking questions and collecting feedback on our evolving data model. Even so, it took months to arrive at something we felt confident in. Fortunately, the flexibility of Clojure and Datomic allowed us to keep our models up-to-date as we learned about the business domain, even when that required revisiting some of our earliest decisions.

In the end, we realized there wasn’t any one “canonical” model. The various definitions of core business concepts were all equally valid and equally necessary. This led us to our final data model, in which the core entities were represented not as single objects but as faceted collections of views. Each team, each software system could shine a spotlight on one face of the entity, and the sum of those views made up the complete picture. The new services we developed with 2U allowed each team to continue working with the model that best served them while also bridging the communications gap between formerly-siloed systems.

Ultimately, we learned that “canonical” and “truth” are asymptotic targets. In any organization, teams tend to view the rest of the business through the lens of the system they interact with. A diversity of models is inevitable as each team adapts their understanding of the domain to fit the task at hand. For human beings, it’s a necessary cognitive shortcut. For software (and the people who write it) it’s a call to action: to adapt to reality rather than trying to reshape it.

Living the Lean Startup with clojure.spec

I remember when I first read the The Lean Startup. Afterwards, it seemed so obvious, (as is common with very good ideas). It was all about applying the scientific method to startups, coming up with hypotheses about what you think your product should be. Then building tests to validate them and, in the process, avoiding wasted time, effort, and resources. In software terms:

Build the minimum functioning features that can get the needed feedback.

One of the most interesting things that I've seen over the last year is the Lean Startup methodology enhanced by the use of clojure.spec. During an engagement with Reify Health, an innovative healthcare startup, it was used to great effect to get faster feedback and to build a better product.

Building Lean

A common modern web application is the single-page application (SPA) paired with a server API. Building out the entire API and front end application is a good chunk of work and requires not only a good understanding of the domain but also knowing what data is going to be important. To really know that takes feedback from users and requires putting a working system in their hands. From a Lean point of view, this should be done is the smartest way possible with the least waste.

This is where one of the unique aspects of clojure.spec comes in. By creating specs for our data using custom generators, we can make the fake data come to life. For example, consider the spec for a name. We can define a list of sample names:

(def sample-names #{"Arlena" "Ilona" "Randi" "Doreatha" "Shayne" ...})

Then create a spec for the name with a custom generator using it.

(s/def ::name (s/with-gen
                       (and string? not-empty)
                       #(s/gen sample-names)))

Finally, we can generate sample data for it. In this case, we are just getting one but we could ask for as many as we want.

(ffirst (s/exercise ::name))
;=> "Ilona"

These specs can be composed together in nested data structures that describe the application. Best of all, using the generators, the data is produced in a random but consistent way. It allows us to create a fake local database that can back the SPA and have it function in a realistic way. More importantly, the product owners can get feedback on the application without having to build out the back end part of it yet.

Building an application this way is smart. The front end features can evolve rapidly in response to actual user feedback and not incur any unneeded effort on the server side. Eventually, when the feature/hypothesis is proved out, the back end can be constructed and the specs can be leveraged even more with sharing.

Sharing specs across the front and back end

One of the killer features of Clojure is that you can share code between Clojure and ClojureScript with .cljc files. This means you can also share specs. Sharing specs in this way allows for the validation of the data flowing across the boundaries of system. For example, the data for a customer endpoint can be validated before it goes across the wire on the server side and again once it hits the front end application. Specs can be validated with the s/valid? function:

(s/valid? spec value)

If a spec fails this validation, an error can be integrated with the full explanation of what was wrong with the s/explain-data function:

(s/explain-data spec value)

For an quick example, let's take the case of an endpoint returning a list of customers. Each customer is a map of data consisting of a customer-id, name, and state. Using our ::name from above, we'll create a couple more specs for the customer id and state. Finally, we'll create a spec for the ::customer map and the collection of ::customers.

(s/def ::id int?)
(defn state? [s]
   (-> (filter #(Character/isUpperCase %) s)
         count
         (= 2)))
(s/def ::state (s/and string? state?))
(s/def ::customer (s/keys :req-un [::id ::name ::state]))
(s/def ::customers (s/coll-of ::customer))

At this point, it would be useful to have a function to validate a value against a spec and if it isn't valid, throw an error with the full spec problem.

(defn validate
  [spec value message]
    (when-not (s/valid? spec value)
      (throw (ex-info message (s/explain-data spec value)))))

Now we can validate a list of customers on the api-server to make sure that they are valid before sending to the client.

(validate ::customers [{:id 1 :name "Susan" :state "OH"} {:id 2 :name "Brian" :state "CA"}] "Bad customers")
=> nil
(validate ::customers [{:id 1 :name "Susan" :state "OH"} {:id 2 :name "Brian"}] "Bad customers")
;=> 
clojure.lang.ExceptionInfo: Bad customers
clojure.spec/problems: ({:path [],
:pred (contains? % :state),
:val {:id 2, :name "Brian"},
:via
[:mynamespace/customers
:mynamespace/customer],
:in [1]})

Likewise, the client can validate the customers when it receives it with the same spec before it does any processing on it. Let's take a step back and look at what this lean, spec driven development process gives us.

Summary

  • Using clojure.spec to generate realistic looking data allows product owners to get fast feedback from users without incurring the development expense of building out the back end portion on unproved schema assumptions.
  • Specs can be shared across the front and back end in .cljc files, enabling code reuse and eliminating more wasted effort.
  • Use of spec to validate data across system boundaries at the server and client ensure application stability and integrity, building a quality product.

After seeing clojure.spec used this way to build an application, it seems obvious, (again like most good ideas). It's a powerful tool for startups, or any business, to build applications in a smart and lean way.

Nubank Uses Datomic to Shake up the Banking Industry in Brazil

Datomic has helped us solve really hard business problems and, frankly, make impossible business problems possible for us.
— Edward Wible, CTO

Brazil is the world's 5th largest country in both area and population, has the 2nd most airports (behind the United States), and one of the highest credit card interest rates in the world. The Brazilian banking industry is both heavily regulated and extremely concentrated. Enter Nubank, whose founders have created a banking alternative in one of the world’s fastest growing mobile markets.

Traditional software wasn’t going to get the job done for Nubank. From the very beginning, the goal was “differentiation through technology.” They needed to plan for growth - in size and complexity to meet the constantly changing regulatory and business rules.

Nubank turned to Datomic, a flexible, simple database that allows them to access multiple data stores simultaneously, process transactions at scale and easily query historical data. Engineers can perform complex analyses on real-time data while the performance of the production environment is preserved. Along the way, the Cognitect team helped steer Nubank’s engineers on the right path as they built Datomic into their business.

Read the full case study to see how Datomic and Clojure are changing the banking industry.

Walmart Runs Clojure at Scale

Say the words "Black Friday" to a group of people and you'll get back a range of emotions. In 2014 this day of historically epic consumer enthusiasm on the Friday after Thanksgiving generated over $50 billion in sales from over 133 million U.S. shoppers. Although originally named for post-Thanksgiving traffic woes in Philadelphia in the 1960's, Black Friday has long been viewed by retailers (some of whom struggle "in the red" through much of the year) as a chance to get their financial numbers "in the black." But this massive surge in transactions is both an opportunity and a crisis for global retailers. Crowds of shoppers seeking pre-holiday deals can generate huge revenue boosts - along with massive spikes in web traffic and server loads. Last year several major retailers suffered system outages costing them $300,000 an hour, and substantially more during peak shopping times. While CFOs (and shoppers) may look to Black Friday with excited anticipation, many CTOs and IT Departments view their November calendars with increasing anxiety.

In preparation for the 2014 holiday season, project architect Anthony Marcar's team at WalmartLabs rolled out a new system designed from the ground up to handle the projected shopping frenzy. The result? After the staggering wave ebbed, his tweet following the surge said it all: 

Our Clojure system just handled its first Walmart black Friday and came out without a scratch.
— Anthony Marcar, Senior Architect - WalmartLabs

How did Walmart's eReceipts team of 8 developers build a system to process and integrate every purchase at Walmart's 5000+ stores, including online and mobile data? Simple - they used Clojure "all the way down" to build a powerful data system enabling the popular Savings Catcher, Vudu Instawatch, Black Friday's 1-Hour Guarantee, and other programs to improve the customer experience and streamline operations. 

Clojure uses anywhere from 5 to 10 times less code than other programming languages, speeding development time, reducing the instances of bugs, and lowering maintenance costs.

Take a behind-the-scenes look at how and why Walmart uses Clojure to reliably power one of the most demanding retail environments in the world as Anthony presents Clojure at Scale.

Breeze EHR Simplifies Healthcare with Clojure and Datomic

Along with complex electronic documentation requirements, medical professionals face an increasing number of factors beyond just symptoms when considering patient diagnosis. Breeze EHR is creating software with Clojure, Datomic, and React that helps doctors make decisions and simplify workflow. This scalable technology will enable all parties in the healthcare ecosystem to collaborate for positive outcomes across a wide range of goals, and enable the system itself to participate on their behalf during the medical encounter.

Clojure and Datomic are valuable as tools, but their radical stance toward simplicity goes beyond the products and also informs and shapes the people and designs that use them.
— Tyler Tallman, CTO

Learn more from Tyler’s Clojure/West presentation.

Yieldbot's Powerful Data Platform runs on Clojure

Yieldbot is using data science to revolutionize the way media value is created for consumers, brands and publishers. Yieldbot’s Clojure-based system processes over 1 billion page views per week and applies machine learning for realizing consumer intent. 

Why Clojure?

  • Leverage the power of the JVM with significantly less code
  • Rapid data exploration via the REPL
  • Zero delta between prototype code and production code

 Find out more from Soren Macbeth’s Clojure/West presentation.

Rally and Datomic

Rally is a fun customer for us - a company making software for companies who make software.  They were listed as a leader in Gartner's 2013 Magic Quadrant for Application Development Life Cycle Management. Their focus is on agile software development, which means their tools have to be fast and responsive - pushing live, actionable information to their users in close to real-time.  Rally uses Datomic to provide that real-time collaboration to their backend storage, while at the same time allowing them to de-couple their architecture from those storages and trade them out as needed.

You can read or download the full case study at http://datomic.com/rallys-story.html.

 

 

Room Key Innovates on AWS with Cognitect, Clojure and Datomic

 

Room Key competes in the crowded, conservative hospitality market. Its CTO Colin Steele chose Clojure before we even spoke to him, and you can read his original account of that decision. Clojure was the right combination of performance and simplicity – accelerating the team’s efforts and codebase. Room Key partnered with Cognitect for support and expertise in Clojure, and we embedded developers, designers and project managers with its team to deliver on its road map. Later, Room Key adopted Datomic to leverage DynamoDB more effectively, since its team built the system natively on AWS.

You can learn more about Room Key’s journey with Cognitect, Clojure and Datomic in this case study.

The Brigade and Datomic

The Brigade is a software team after our own hearts - a development partner with a keen focus on powerful, enabling technology and a deep sense of the power of good design, in every sense of the word.  When building a social music application for their customer, Spotify, they had already chosen AWS as a deployment platform and DynamoDB as the storage engine.  They turned to Datomic to add critical database features on top of DynamoDB, and to give their development team the flexibility to keep up with rapidly changing requirements.

You can read more about their story at http://datomic.com/the-brigades-story.html.

Pellucid Analytics and Datomic

Pellucid Analytics is a great partner - enthusiastically pushing the boundaries of technology to bring value to their customers, and willing to give back to the community at the same time. With Datomic as part of their solution, they are bringing mobile and cloud technologies together to solve the complex information management problems of financial professionals.  You can read or download the full case study at http://datomic.com/pellucids-story.html.