SAIL: Appian’s UI Framework

By Jonathon Blonchek

Enterprise software users require more than just a beautiful UI. They want to view their apps on phones, tablets, surfaces, desktops and more. It is vital to a business’ success that this value be delivered to employees as fast as possible.

The industry is chock full of different technologies and frameworks that simplify the model for how we build UIs. Any number of technologies will make life easier for the interface developer, yet there is still much to be desired. To bridge the programmer to non-programmer gap, we wanted to create a way for anyone to easily design a powerful, modern application that stands the test of time. We reduce the responsibilities of the developer to a simple task: tell us what you want your UI to do — we’ll handle the rest. Dorothy didn’t know she needed to follow the yellow brick road, meet some friends, and kill a witch. She just wanted to get to Oz. Why should Dorothy have to know? We all probably could’ve been spared the details anyways.

Our mission is to change the way software is written. We created SAIL (Self-Assembling Interface Layer) in fulfillment of that vision.

Consider the following javascript example:

var article = document.createElement(“article”);
var paragraph = document.createElement(“p”);
var text = document.createTextNode(“Lots of text”);

We’re simply trying to put some text in a paragraph, and put that paragraph inside of an article. Why worry about how to create the elements and how to stitch them together? Why not say what you mean? Try declarative:

Lots of text

Declarative code describes what you want to do, and not how you want to do it. This restricts the concern of the developer to what they want to happen. In other words, the developer just needs to describe the end result, not caring about how we get there. Why is this important? It’s much easier for developers to reason about a black box. As code becomes easier to reason about, the level of skill required to write the code approaches zero.

I Feel a Change Comin’

It’s pretty easy to understand the example I presented above without much knowledge. The real complexity comes when you want that UI to change in response to an event. The developer must be able to specify interactive behavior. In typical event-driven application, an event (typing, clicking, push notification, etc.) causes some imperative code to be called. The developers are then responsible for the propagation of those changes across the UI. Reactive programming allows the designer to declare the state change that a given event will trigger. That state is automatically propagated throughout the UI.

Modern MVC frameworks have done a lot of work to shoehorn imperative languages into declarative constructs. While these frameworks offer a well-defined set of rules for how one should develop, those rules are easily broken, undermining the power that the framework is supposed to provide. Restricting developers to the confines of a declarative and reactive world makes a framework much more accessible. We make it much easier to develop the right way, and much harder to develop the wrong way.

Make it Functional

Functional paradigms in our framework solidify the simplicity of our UI design experience. A few key principles:

  • Functional programs have no mutable state. Simply put, what you see is what you get. There is no risk of side effects, and it makes it very easy for us to share and cache state. Immutability saves blood, sweat and tears down the road.
  • Functional programs use first-class and higher-order functions instead of explicit control flow. No for or while loops. A long if/else statement can become a single assignment using a function.
  • Functions are referentially transparent. No surprises. Every time you call a function with the same inputs, you should get the same result.

Our pure functions output UI elements. When a customer defines an element, there are no side effects. When you describe that element, the business logic can be collocated with its appearance. Most importantly, your interface appears and behaves exactly as you describe it no matter what. We create small, self-contained UI functions that act as building blocks for our users to work with to easily create complex UIs. Think Excel spreadsheets:

When you update a cell, everything in that sheet will automatically update based on the rules that you have defined for each UI element (cells and charts).

Appian’s UI Framework

SAIL is Appian’s patented reactive UI framework based upon our own functional expression language. Consider this expression:

: "John",
last: "Smith",
display: lower(concat(first, ".", last)),
textField(label: "First", value: first, saveInto:first),
textField(label: "Last", value: last, saveInto: last),
textField(label: "Display", value: display, readOnly: true)

The designer wants two input text fields, and one read only. The designer declares that the display variable will be the concatenation of the first and last names, and that the value inside of the text field will be saved back into the first and last name when the user interacts.

The user types a new last name, automatically updating the display name as declared in the expression.

When a developer is designing a UI in SAIL, they are describing the UI at any moment in time. Functional Reactive concepts guide our declarative control flow structures. There are no callbacks, no event handlers. Views are given the power to define what pieces of state they depend on and how. An event triggers an update of state, and each building block responds accordingly with deterministic output.

Appian follows similar patterns to those discussed above:

  • Appian UIs are created from functions that describe the state of the UI at any point in time.
  • Data propagation changes are automatic and implicit. There are no manual updates of the UI.
  • Side effects can only be triggered by user interactions as part of a unidirectional data flow.
An high-level look at unidirectional data flow in SAIL

The SAIL Context (current state) and the designer-configured SAIL expression combine to create a model for the interface that is to be rendered. User interactions trigger reevaluations that are handed to the SAIL runtime. Updates propagate and are deterministically reflected on the interface exactly as the designer declared in their expression. Magic!

SAIL architecture closely resembles that of Elm, a popular language for developing front-end applications. These frameworks are the arbiters for all state changes triggered by the user. The view cannot directly update the model, the FRP runtime will handle the request. These are referred to as Managed Effects. In both SAIL and Elm, the developer simply has to describe to the runtime the set of rules for handling updates to values. The runtime handles the rest. Because all of these rules are referentially transparent, it gives great power to the framework to optimize — if we receive the same input, why re-evaluate? Just return a cached result. Even better: any and all side effects are managed through the framework, so they can be easily recorded and replayed.

Why use a UI Framework like this?

Our framework allows the designer to stitch together a robust interface using functions as the building blocks. It is our mission to make custom application development accessible with low amounts of code and SAIL was a giant leap towards that vision. Because we are confident that our functions are always going to behave in the same way in production, we can easily give developers a structured, graphical, design experience that lets them see what they are building in real time.

Business logic and functional relationships of components can be defined in one location. Our framework allows the designer to state his or her intent for a UI. Once we have captured that intent, we define how a given client should render the UI by implementing a client specific version of each building block (e.g. a drop-down). As UX trends and industry standards change, we can evolve these building blocks and give customers the latest and greatest user experience without touching functionality. The customer writes an application once and can expect it to appear and operate beautifully on all platforms throughout time.

Consider the simple example of our multiple dropdown component. Both of the components you see are sourced from the exact same UI definition. We were able to update the rendering of the component to a modern, more attractive, more compact and more accessible design without touching our customers work.

Multiple Dropdown circa 2015
Multiple Dropdown circa 2016

SAIL simplifies the development process so that it can be effective in the hands of non-programmers. FRP allows for extreme functional complexity with minimal development complexity. Businesses no longer need to hire expensive development teams for each custom software solution they require. Just about anyone can build robust applications in Appian simply by stating what you want to see and do, sans the typical concerns of many popular UI frameworks.

Kudos to Marco Pescosolido, Antonio Andrade, Justin Kenel, and Alison Cowley for their help.

SAIL: Appian’s UI Framework was originally published in Appian Engineering on Medium, where people are continuing the conversation by highlighting and responding to this story.

Read more >

Published on Jun 19, 2017

Alert me about jobs

Sign in with LinkedIn
Autofill my information with LinkedIn

Not ?

Thank you

Recommended Jobs

Quality Engineer

Tysons Virginia United States Tysons, Virginia, United States University Recruiting University Recruiting
MYTH: You need a CS degree to break into the software industry and get all the cool high-paying tech jobs. FACT: Slinging code is just one of many things High Tech Companies need to do to create cool new products. If you are student in any Math, E...

Associate Solution Engineer

Tysons Virginia United States Tysons, Virginia, United States University Recruiting University Recruiting
Looking for a position that allows you to engage all of your many technical talents? Do you particularly excel at not only solving complex technical problems, but also at communicating the solution clearly and effectively? As an Associate Solution...

Software Engineer - Intern

Tysons Virginia United States Tysons, Virginia, United States University Recruiting University Recruiting
Think you can code alongside some of the most talented software engineers in the industry? Want to contribute to the development of a product that is the market leader,  a product so innovative, that it’s revolutionizing the way people work? We’re...

Associate Consultant

Tysons Virginia United States Tysons, Virginia, United States University Recruiting University Recruiting
Are you looking to marry your passion for technology with your penchant for strategic problem solving? As an Appian Associate Consultant, you’ll build and deploy web-based applications on the Appian platform to support our customers’ business stra...

Software Engineer

Tysons Virginia United States Tysons, Virginia, United States University Recruiting University Recruiting
Are you equally as talented at as you are passionate about writing sophisticated code? Are you ready to dive deep into the intricacies of one of the world’s most cutting-edge software platforms in the industry? As a Software Engineer working on th...

Senior Consultant - Italy

Milan Lombardy Italy Milan, Lombardy, Italy Professional Services Professional Services
Appian is looking for Senior Technical Consultants to create, present, and implement Appian's technical solutions. As a Senior Consultant, you will be a key leader for the business of consulting as well as the business of our clients. Appian’s gro...
People, Person, Crowd, Skin
People, Person, Clothing, Overcoat, Suit, Team
Bridge, Cruise Ship, Ferry, Freighter, Ship, Tanker, Vessel, Ocean Liner, Boat, Yacht