declarative programming
What is declarative programming?
Declarative programming is a method to abstract the control flow for logic required for software to perform an action. Instead, it involves stating what the task or desired outcome is.
Declarative programming is a high-level programming concept, which is the opposite of imperative programming. It is a programming approach in which coders write code that describes what they want to do and what results they want to achieve, rather than how they will achieve the results. It is the job of the program's compiler to figure out the how.
Declarative models rely on preconfigured capabilities in the language without explicit case-by-case instructions on what steps to take to accomplish a particular task. Declarative programming is typically found in databases and configuration management software, paired with a domain-specific language (DSL).
Declarative programming and context independence
Since declarative programs only declare the ultimate goal (the what), but not the steps required to reach that goal (the how), they are said to be context independent. What this means is that the same expressions in that program have the same meaning and therefore can be used in different contexts.
For instance, in the C programming language, while/if expressions are permanently defined by the language along with the order of the following expressions. As a result, they always mean the same thing, regardless of where they are used. In other words, the expressions are context independent.
Benefits of declarative programming
Declarative programs are easier to work with since they only express computation logic without complicating the code with control flows. Such programs also have fewer unclear procedures, implicit dependencies and mutable states, which also simplifies programming.
And declarative programming minimizes mutability. Immutable objects in code improve its readability and make it easy to understand, even without a whole lot of comments. Immutable code is also easier to update, test and debug, and manage, and it remains safe and valid since background processes cannot cause changes without the programmer's knowledge. Finally, immutable code is traceable, so programmers can keep track of what data is changing and in which parts of the application, and accordingly reload only those parts with each change.
Declarative programming also minimizes state side effects, a situation where a function changes something that's outside its scope, such as changing the value of a variable or generating a nondeterministic output.
Declarative programming example
In configuration management, if an administrator needs to copy a file to a server, in pseudocode, an iterative approach follows this construction, with if/then statements:
A declarative programming alternative, in pseudocode, follows a different setup:
There is no conditional logic in the snippet of declarative code. Instead, it displays what action the user wants to happen, and what servers are involved in the action.
How declarative programming works
Declarative programming relies on constraints and logic (rules) to define the setup and outcome, as well as declarative sentences (hence the name) that simply declare the programmer's intentions.
Constraints define the properties that are true in a given programming scenario, such as equalities and inequalities. They are how variables relate to each other. Constraints are either embedded in the language or set up in software libraries.
Similarly, logic programming expresses facts and rules about the domain in which the developer is working. Control and logic are separated for this form of programming to work. Constraint logic programming combines both of the above practices.
Declarative programming is usually practiced with a DSL, because the control flow must exist separate from the logic, embedded in the language itself.
Types of declarative programming
The three main types of declarative programming are:
Constraint programming
Constraint programming, also known as constraint optimization, is a programming paradigm in which constraints are declaratively stated for a set of decision variables. The arbitrary constraints help with modeling the problem to be solved without specifying the steps to be executed.
Logic programming
Logic programming involves the use of logical sentences that express certain rules and facts as well as logical inferences based on available data. These languages use queries to display relevant data, a base of existing logic (predicates), and formulas that state facts (atoms).
Constraint logic programming
Constraint logic programs include constraints in a body of clauses. An interpreter is used for execution. It recursively scans the clauses (with its constraints placed in a constraint store) to prove a specific goal.
Declarative programming vs. imperative programming
Declarative programming relies on underlying components of a given language to carry out the necessary steps to reach the stated outcome. In declarative programming, typical programming constructs, such as loops and if/then conditions, do not exist because they are instructional.
Declarative programming focuses on the end result, while imperative programming focuses on how to get there. For example, when you jump in a taxi, you declare to the driver where you want to go. You don't tell him how to get there by providing turn-by-turn directions. The turn-by-turn directions are akin to imperative programming.
Declarative programming allows the compiler to make (how) decisions, while imperative programming does not. Also, it does not include mutable variables while imperative programming does.
Declarative programming builds on the capabilities developed by imperative programming but enables the developer to focus on problem resolution rather than intricacies of code setup. It also simplifies the code structure.
Many programming languages allow for imperative and declarative programs to be combined. For example, the Java programming language provides the ability for developers to place annotations on code, which adds declarative capabilities to traditionally developed code.
In the code snippet below, the @Enumerated annotation indicates that the property named clientGesture is an enumerated type that should be persisted to the underlying database as a text string:
@Enumerated(EnumType.STRING)
private Gesture clientGesture;
Other modern programming languages have similar declarative programming facilities.
Uses of declarative programming
The relational database is a popular declarative programming concept. A programmer writes statements in a DSL called Structured Query Language (SQL) to control the database. A SQL query that pulls a set of records from a database does not use loops or conditional logic. Instead, it includes SELECT * FROM <TableName>, which tells the database to return the requested records.
Configuration management tools such as Chef, Puppet and Microsoft PowerShell Desired State Configuration (DSC) all use the declarative programming approach. Each tool is built on an iterative language, including Ruby, Python and PowerShell. The user defines what they need the tool to do via the DSL, and the tool accomplishes the task without requiring information about how to do it.
Declarative approach to programming has proven useful when facing the demands for complex and feature-heavy business applications. Explore the basics of working with declarative programming languages.