Although building applications in KRL may require learning new language elements, developers gain access to events, opening a whole world of possibilities. The design of the expression language in KRL is purposely kept familiar, so this new language should not seem too foreign.
As discussed, event-based applications are different from request-based applications. Event-based systems react to occurrences such as a person visiting a Web page, receiving an email, or placing a call. A KRL application is the result of multiple, possibly interdependent, conditional actions taking place over a series of reactions to events. Rules are a natural way to structure programs that react to events.
KRL has declarative structures that reduce programmer burden:
- Eventexes provide a declarative means of specifying the event scenarios to which a rule applies. Developers should plan the eventexes they use in their applications with care.
- Conditions declare the contextual conditions under which actions should be taken. KRL's expression language provides a very capable means for computing the context.
- The embedded little languages for regular expressions, JSONPath and HTML DOM Query, are all declarative methods for computing results.
Developing a KRL application requires understanding the relevant events, their attributes, and determining the correct reactions to those events. More than one rule, even in a single rule set, might fire in response to a given event and the conditions that surround it. A KRL developer should plan the actions a rule takes so they play nice with each other. This is especially important when you realize that a user might have rule sets from other developers installed that respond to the same event and send directives to the same endpoints.
Because rule sets execute each rule once, in order, for any given event, developers can use the instincts they honed working with other statically scoped languages to understand their rule sets and the rules within them.
As you've seen, persistents provide a means of creating data values that are available across rule and rule set executions. Normal KRL expressions do not have the ability to cause side-effects in values. This is slightly more restrictive than what developers are used to from their experience with most programming languages, but limits effects to just the postlude.
Persistents are not currently available outside of a single rule set. Sharing data between rule sets requires using an outside data service or an explicit event. This prevents most problems where data isolation would be required to maintain the integrity of data values. Future versions of KRL will deal with concurrent data changes between rule sets as part of the language.
As mentioned, event languages like KRL can build applications that exhibit extreme loose coupling. Each rule is clearly identifiable with a specific portion of the experience based on its eventex, condition, and action.
Rules build experience layer upon layer. As more and more rules are added, they add to the overall experience. Where possible, KRL has been designed to ensure rules work together. Of course, that can't be guaranteed, but the goal is to allow rules to be added in ways that build the experience for the end user. As a consequence, when planning actions for rules, developers should strive to create actions that are idempotent and independent wherever possible:
- Idempotent operations can be carried out more than once without affecting the final value. Adding zero to a number is idempotent because no matter how many times you do it, you get the same result. When rule actions are idempotent, multiple rule applications from a single event create the desired result.
- Independent operations are careful to take actions that won't interfere with other actions in the same domain.
Idempotent and independent actions are not always possible. In addition, some domains are more prone to these types of actions that others. For example, in the domain of Web pages, it's fairly easy to make changes to the DOM in such a way that multiple actions will result in good results and also preserve the DOM structure so that other rules can fire without interference. In the email domain, on the other hand, while deleting an email by message ID is idempotent, forwarding it isn't. Further, deleting an email interferes with a latter action that forwards the same email.