What is the difference between declarative and imperative paradigm in programming?
Asked Answered
K

22

818

I have been searching the web looking for a definition for declarative and imperative programming that would shed some light for me. However, the language used at some of the resources that I have found is daunting - for instance at Wikipedia. Does anyone have a real-world example that they could show me that might bring some perspective to this subject (perhaps in C#)?

Kowtko answered 23/11, 2009 at 17:24 Comment(4)
Imperative goes to a restaurant and orders a 6oz. steak (cooked rare), fries (with ketchup), a side-salad (with ranch), and a Coke (with no ice). The waiter delivers exactly what he asked for, and he's charged $14.50. On the other hand, Declarative goes to a restaurant and tells the waiter that he only wants to pay around 12 dollars for dinner, and he's in the mood for steak. The waiter returns with a 6oz. steak (cooked medium), a side of mashed potatoes, steamed broccoli, a dinner roll, and a glass of water. He's charged $11.99.Viviparous
Another good example I found is maybe how you do Docker files and commands... e.g an imperative approach is, that you define all your steps one by one in the command-line, e.g create a container in aws, create a network and then put your ressources somehow together... the DECLARATIVE approach would then be: you DECLARE a Dockerfile (or docker-compose.yaml), where you essentially put all your commands (or you just name what you want it to do) inside one file, and then simply execute that file. Its declared all at once beforehand, so it should behave always similar.Neral
You feel the nature of a declarative program and declarative programming better if you see them as a configuration and configuration process.Ptolemaeus
The guy who goes to the restaurant and orders a steak cooked rare is most certainly declarative. He DECLARES he wants a rare 6oz. steak. It's no different than the guy who DECLARES he wants to pay 12$. The level of abstractions are maybe slightly different, but the distinction between "imperative" and "declarative" are completely random here.Decimeter
D
1085

A great C# example of declarative vs. imperative programming is LINQ.

With imperative programming, you tell the compiler what you want to happen, step by step.

For example, let's start with this collection, and choose the odd numbers:

List<int> collection = new List<int> { 1, 2, 3, 4, 5 };

With imperative programming, we'd step through this, and decide what we want:

List<int> results = new List<int>();
foreach(var num in collection)
{
    if (num % 2 != 0)
          results.Add(num);
}

Here, we're saying:

  1. Create a result collection
  2. Step through each number in the collection
  3. Check the number, if it's odd, add it to the results

With declarative programming, on the other hand, you write code that describes what you want, but not necessarily how to get it (declare your desired results, but not the step-by-step):

var results = collection.Where( num => num % 2 != 0);

Here, we're saying "Give us everything where it's odd", not "Step through the collection. Check this item, if it's odd, add it to a result collection."

In many cases, code will be a mixture of both designs, too, so it's not always black-and-white.

Demagogic answered 23/11, 2009 at 17:29 Comment(19)
+1. However, you first mention LINQ, but what has the examples to do with that?Rhpositive
collection.Where is using the declarative LINQ extension methods. It's not using the C# language features, but rather the declarative API. I did not want to mix messages here, which is why I avoided the language additions built on top of the declarative methods.Demagogic
It seems to me that declarative programming is nothing more than a layer of abstraction.Endure
@ReedCopsey Reading your answer, I have a sense that Declarative programming is "just trust and use that function, someone else made it ready for you to use", am I right ?Ticket
@JoshBjelovuk That statement seems to be true, but different from classic levels of abstraction, things like attributes and lambda expressions let us write static logic inline that can be passed to an API and allow injection of logic much easier than implementing an interface like the old IComparer way of sorting. The big benifit seems to always end with creating flexible interfaces like LinqNabob
This is a good answer, but it's answering the difference between impure functional and imperative programming. collection.Where is not using the declarative syntax Linq provides - see msdn.microsoft.com/en-us/library/bb397906.aspx for examples, from item in collection where item%2 != 0 select item would be the declarative form. Calling a function doesn't become declarative programming just because that function is in the System.Linq namespace.Thoughtless
@PeteKirkham The syntax you use isn't the issue - declarative vs imperative is more about declaring what you want to have happen vs. explaining exactly how it needs to occur. Using the integrated syntax or extension method syntax is a separate issue.Demagogic
Sort of. The syntax doesn't exactly matter - with method syntax the compiler will still choose the declarative Where (IQueryable..., Expression...) instead of the functional Where (IEnumerable.., Func..) if the arguments allow. The difference in is that in Linq to SQL the parse tree is inspected and the order of operations is not in the control of the library, but the Linq to objects it is applying a function to a list - which is the canonical example of functional programming. So perhaps a better edit will be to give an example of declarative generation than merely the syntax.Thoughtless
Thank you for this answer, I have a follow up question, so if I enclose the mathematical implementation inside .Where(num) and just receive the array of numbers based on your first example and use that instead of the for loop does it make the code declarative in that case?Taam
@Taam for that portion, essentially yesDemagogic
@DrazenBjelovuk This is very true for current computers, as code will eventually become, in some sense, imperative. Some languages don't have an internal conversion from declarative to imperative, but will compile directly to assembly, so the mapping (declarative -> imperative) is still the same. Machines that are "pure" declarative do exist and might someday be more efficient than imperative ones. Currently they pollute a lot, are very ineffective and have a lot of overhead as they are poor at prioritising work, so instead of computing they do other tasks, like writing comments on SO.Combustion
Good examples: tylermcginnis.com/imperative-vs-declarative-programmingSpier
when the most voted comment gets twice the votes as...Left
@Spier yeah, i like that example better. unfortunately it's not code but the code here could easily be interpreted as "both look the the same." i like the way it was explained though so the point was well taken.Fiedler
Citing "Designing Data-Intensive Applications" by Martin Kleppmann: Imperative languages specify the step-by-step algorithm that is used to determine the result/results, whereas Declarative languages specify only the patterns of the result/results.Capuche
But don't the compilers optimize our code? For example, division by 2 will get transformed to bit shift by 1. So we are not really forcing the compiler how to do these small things. That means, this example is also declarative, just at a small scale.Unsophisticated
Exactly, @Ferazhu. The only real difference between declarative and imperative programming, as it's defined above, is what layer of abstraction you're operating at. LINQ is an abstraction on top of Lists. Lists are also an abstraction on top of Arrays. I think the true difference is that declarative code describes it's intent, without orthogonal concerns. However, there must be more code (relatively imperative code) elsewhere that executes that intent.Case
@DrazenBjelovuk You say that like it's a bad thing.Mosstrooper
Interestingly, this example is more powerful to me as a non-C# programmer. It's immediately clear to me how the declarative version is understandable. I could even debug it if asked to. Not so, the procedural version.Mosstrooper
Q
205

Declarative programming is when you say what you want, and imperative language is when you say how to get what you want.

A simple example in Python:

# Declarative
small_nums = [x for x in range(20) if x < 5]

# Imperative
small_nums = []
for i in range(20):
    if i < 5:
        small_nums.append(i)

The first example is declarative because we do not specify any "implementation details" of building the list.

To tie in a C# example, generally, using LINQ results in a declarative style, because you aren't saying how to obtain what you want; you are only saying what you want. You could say the same about SQL.

One benefit of declarative programming is that it allows the compiler to make decisions that might result in better code than what you might make by hand. Running with the SQL example, if you had a query like

SELECT score FROM games WHERE id < 100;

the SQL "compiler" can "optimize" this query because it knows that id is an indexed field -- or maybe it isn't indexed, in which case it will have to iterate over the entire data set anyway. Or maybe the SQL engine knows that this is the perfect time to utilize all 8 cores for a speedy parallel search. You, as a programmer, aren't concerned with any of those conditions, and you don't have to write your code to handle any special case in that way.

Quassia answered 23/11, 2009 at 17:27 Comment(16)
That Python example IS NOT declarative.Carencarena
Prolog is a declarative programming language.Carencarena
@Juanjo: It IS decalarative.Muzhik
How is the first statement in here any more declarative than the second?Longwinded
Agreeing with Juanjo and zenna - a loop construct does not magically transform into a declarative program when refactored into a shorter notation.Sunless
Disagreeing with @FelixFrank, and leaning towards @missingfaktor's "bold" statement. The traditional, "fully" declarative way to do this is filter(lambda x: x < 5, range(20)), is just another refactoring into a shorter notation. This is not in any meaningful way different from the list comprehension expression (which has clear "map" and "filter" sections), which was created (see pep 202) with the explicit intention to create a more concise notation. And this list comprehension would be more clear/idiomatic in this case.Apc
As I see it, if something is declarative or not will depend on the way you code it, and not on how it's actually executed/compiled. If the code you are writing describe what you want and not how to achieve it, then is declarative. So, even if the call is a simple construct, it may be still declarative. At the end everything is compiled into processor instructions, that is always imperative.Dermot
LINQ is not declarative. It may look like it, but it is still executing the expression left to right exactly as written.Squabble
@JonathanAllen that's certainly true when dealing with an IEnumerable, but in the case of IQueryable, a chain of statements may be in fact "executed" at the same time and in a different order, as is the case when Linq ends up generating SQL. Since exactly the same statements would be written in either case, I would consider most of Linq a good example of declarative style. Our knowledge of the implementation details shouldn't change the "declarativeness" - if the code is expressing intent but not explicit implementation, then in the vast majority of cases it would be considered declarativeBog
At the risk of committing the genetic fallacy, I would say list comprehensions are eminently declarative constructs, they come from Haskell, which is a purely functional programming language, and that is unabigouslly in the declarative paradigm. The fact the there is a for-loop and .append underneath the hood is not relevant. You can always go deeper and find, fundamentally, an imperative program due to the nature of common computer architectures.Lusaka
@FelixFrank Disagree. I think there's a fundamental misconception here. Declarative programming is simply a style. It's a property of the syntax, not the semantics. A "shorter notation" that "magically transforms into a loop" is exactly what declarative programs are.Patroon
Can we agree that using python as an example for declarative vs imperative is a poor choice? I'd argue that using JavaScript for(let i=0; i <= array.length; i+= 1){} loop vs Array.map would be better (and optionally using Math.pow as the transform function would be good)Petrick
@PhilippeHebert python has a map function as well, OP just chose to use a list comprehension instead. That doesn't mean that "using python as an example ... is a poor choice".Percolation
@Percolation Not looking to rustle some feathers here - I still think that using range(n) is a poor example of imperative programming (due to its rather declarative API). AFAIK Python doesn't have a clear imperative increment-each-loop-execution construct like in JS.Petrick
@PhilippeHebert No rustled feathers here. I am still quite new and still trying to understand the differences between each programming style. I think you make a fair point with regards to range(n) being declarative. Would a python while loop be a better example? i = 0; while i <= array.length: i += 1Percolation
@Percolation It's definitely a better example, but it's really not a standard way to do this in Python (if you see this in a codebase, run away).Petrick
B
177

Declarative vs. Imperative

A programming paradigm is a fundamental style of computer programming. There are four main paradigms: imperative, declarative, functional (which is considered a subset of the declarative paradigm) and object-oriented.

Declarative programming : is a programming paradigm that expresses the logic of a computation(What do) without describing its control flow(How do). Some well-known examples of declarative domain specific languages (DSLs) include CSS, regular expressions, and a subset of SQL (SELECT queries, for example) Many markup languages such as HTML, MXML, XAML, XSLT... are often declarative. The declarative programming try to blur the distinction between a program as a set of instructions and a program as an assertion about the desired answer.

Imperative programming : is a programming paradigm that describes computation in terms of statements that change a program state. The imperative programs can be dually viewed as programming commands or mathematical assertions.

Functional programming : is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data. It emphasizes the application of functions, in contrast to the imperative programming style, which emphasizes changes in state. In a pure functional language, such as Haskell, all functions are without side effects, and state changes are only represented as functions that transform the state.

The following example of imperative programming in MSDN, loops through the numbers 1 through 10, and finds the even numbers.

var numbersOneThroughTen = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//With imperative programming, we'd step through this, and decide what we want:
var evenNumbers = new List<int>();
foreach (var number in numbersOneThroughTen)
{    if (number % 2 == 0)
    {
        evenNumbers.Add(number);
    }
}
//The following code uses declarative programming to accomplish the same thing.
// Here, we're saying "Give us everything where it's even"
var evenNumbers = numbersOneThroughTen.Where(number => number % 2 == 0);

Both examples yield the same result, and one is neither better nor worse than the other. The first example requires more code, but the code is testable, and the imperative approach gives you full control over the implementation details. In the second example, the code is arguably more readable; however, LINQ does not give you control over what happens behind the scenes. You must trust that LINQ will provide the requested result.

Bakerman answered 1/7, 2013 at 11:59 Comment(2)
Can you add a description for object-oriented?Knelt
Good examples: tylermcginnis.com/imperative-vs-declarative-programmingSpier
C
110

Answers here and in other online posts mention the following:

  • With declarative programming, you write code that describes what you want, but not necessarily how to get it
  • You should prefer declarative programming over the imperative programming

What they have not told us is how to achieve it. For part of the program to be more declarative, other parts must provide the abstraction to hide the implementation details (which is the imperative code).

  • E.g., LINQ is more declarative than loops (for, while, etc.), e.g., you can use list.Where() to get a new filtered list. For this to work, Microsoft has done all the heavy lifting behind the LINQ abstraction.

In fact, one of the reason functional programming and functional libraries are more declarative is because they have abstracted away loops and list creations, hiding all the implementation details (most likely imperative code with loops) behind the scene.

In any program, you will always have both imperative and declarative code, and you should aim to hide all imperative code behind the domain-specific abstractions, so that other parts of the program can use them declaratively.

Finally, although functional programming and LINQ can make your program more declarative, you can always make it even more declarative by providing more abstractions. For example:

// JavaScript example

// Least declarative
const bestProducts = [];
for(let i = 0; i < products.length; i++) {
    let product = products[i];
    if (product.rating >= 5 && product.price < 100) {
        bestProducts.push(product);
    }
}


// More declarative
const bestProducts = products.filter(function(product) {
    return product.rating >= 5 && product.price < 100;
});

// Most declarative, implementation details are hidden in a function
const bestProducts = getBestProducts();

P.S. the extreme of declarative programming is to invent new domain specific languages (DSL):

  1. String Search: Regular Expression instead of custom imperative code
  2. React.js: JSX instead of direct DOM manipulation
  3. AWS CloudFormation: YAML instead of CLI
  4. Relational Database: SQL instead of older read–write APIs such as ISAM or VSAM.
Cream answered 18/9, 2016 at 19:33 Comment(5)
There are many good examples of declarative programmings: React, CloudFormation, TerraformCream
So "declarative" programming just means moving the code that does the job to a function?Mutter
@GuillaumeF. It is about creating the domain specific abstraction. E.g., - in banking: you should create functions such as debit, deposit, etc. instead of repeating imparative code account.balance += depositAmountCream
@Cream But you're still going to have both, right? At the end of your abstraction you are going to have account.balance += depositAmount. So is the declarative programming style just advocating for creating good APIs at the proper abstraction levels?Percolation
pretty much yes. And, of course that allows for better testing practices and resiliency, among other thingsSethrida
K
53

I'll add another example that rarely pops up in declarative/imperative programming discussion: the User Interface!

In C#, you can build an UI using various technologies.

On the imperative end, you could use DirectX or OpenGL to very imperatively draw your buttons, checkboxes, etc... line-by-line (or really, triangle by triangle). It is up to you to say how to draw the user interface.

At the declarative end, you have WPF. You basically write some XML (yeah, yeah, "XAML" technically) and the framework does the work for you. You say what the user interface looks like. It is up to the system to figure out how to do it.

Anyway, just another thing to think about. Just because one language is declarative or imperative does not mean that it doesn't have certain features of the other.

Also, one benefit of declarative programming is that purpose is usually more easily understood from reading the code whereas imperative gives you finer control over execution.

The gist of it all:

Declarative -> what you want done

Imperative -> how you want it done

Karlsruhe answered 23/11, 2009 at 18:41 Comment(0)
C
46

The difference has mostly to do with the overall level of abstraction. With declarative, at some point, you're so far away from the individual steps that the program has a lot of latitude regarding how to get your result.


You could look at every piece of instruction as falling somewhere on a continuum:

Degree of abstraction:

Declarative <<=====|==================>> Imperative

Declarative Real World Example:

  1. Librarian, please check me out a copy of Moby Dick. (Librarian, at their discretion chooses the best method for performing the request)

Imperative Real World Example:

  1. Go into Library
  2. Find Book Organization System (Card Catalog - Old school)
  3. Research how to use Card Catalogs (You forgot too, right)
  4. Figure out how shelves are labeled and organized.
  5. Figure out how books are organized on a shelf.
  6. Cross-reference book location from card catalog with organization system to find said book.
  7. Take book to check-out system.
  8. Check out book.
Congruence answered 14/6, 2017 at 20:55 Comment(6)
Isn't this more about abstraction than declarative/imperative? You are still instrtucting the librarian to bring the book.Technicolor
Updated answer to be more complete and include this aspect in the solution.Congruence
There is some truth in this, but it's not a complete definition. With declarative programming you're stating the end-goal, without regard for the starting point. With imperative programming, a defined start point is important. It's like the difference of giving an address vs giving directions. The address is useful no matter you are. Whereas directions are invalid if you start somewhere else.Zygo
@Zygo I wish "It's like the difference of [declaring] an address vs [commanding] directions. The address is useful no matter you are. Whereas directions are invalid if you start somewhere else," was the selected answer all by itself. ;^)Jeavons
@Jeavons That's a fantastic way of describing it.Zygo
This is really the only answer that makes sense. The usual distinction between "declarative" and "imperative" does not apply to programming, unless you're looking at a spectrum, the only real imperative programming is machine code.Decimeter
C
38

I liked an explanation from a Cambridge course + their examples:

  • Declarative - specify what to do, not how to do it
    • E.g.: HTML describes what should appear on a web page, not how it should be drawn on the screen
  • Imperative - specify both what and how
    • int x; - what (declarative)
    • x=x+1; - how
Curling answered 25/2, 2015 at 5:0 Comment(4)
"not how it should be drawn on the screen" ... So does that imply that CSS is Imperative then?Berl
No. It can also be considered declarative because you just say what you want - "make this cell border blue". Imagine that you want to draw the same border in an imperative approach (E.g.: JavaScript). Then you need to say "go to point (x1,y1), draw a blue line between this point and (x2,y1), draw a blue line from (x2,y1) to (x2,y2), draw a blue line from (x2,y2) to (x1,y2), draw a blue line from (x1,y2) to (x1,y1)".Curling
@ROMANIA_engineer, Where can I find such Cambridge course, please?Nagano
@testteam, search the following "cl.cam.ac.uk teaching ooprog" on Google. You can change the years from the URL.Curling
S
30

Imperative programming requires developers to define step by step how code should be executed. To give directions in an imperative fashion, you say, “Go to 1st Street, turn left onto Main, drive two blocks, turn right onto Maple, and stop at the third house on the left.” The declarative version might sound something like this: “Drive to Sue’s house.” One says how to do something; the other says what needs to be done.

The declarative style has two advantages over the imperative style:

  • It does not force the traveler to memorize a long set of instructions.
  • It allows the traveler to optimize the route when possible.

Calvert,C Kulkarni,D (2009). Essential LINQ. Addison Wesley. 48.

Superhighway answered 15/4, 2014 at 8:34 Comment(0)
C
12

Stealing from Philip Roberts here:

  • Imperative programming tells the machine how to do something (resulting in what you want to happen)
  • Declarative programming tells the machine what you would like to happen (and the computer figures out how to do it)

Two examples:

1. Doubling all numbers in an array

Imperatively:

var numbers = [1,2,3,4,5]
var doubled = []

for(var i = 0; i < numbers.length; i++) {
  var newNumber = numbers[i] * 2
  doubled.push(newNumber)
}
console.log(doubled) //=> [2,4,6,8,10]

Declaratively:

var numbers = [1,2,3,4,5]

var doubled = numbers.map(function(n) {
  return n * 2
})
console.log(doubled) //=> [2,4,6,8,10]

2. Summing all items in a list

Imperatively

var numbers = [1,2,3,4,5]
var total = 0

for(var i = 0; i < numbers.length; i++) {
  total += numbers[i]
}
console.log(total) //=> 15

Declaratively

var numbers = [1,2,3,4,5]

var total = numbers.reduce(function(sum, n) {
  return sum + n
});
console.log(total) //=> 15

Note how the imperative examples involve creating a new variable, mutating it, and returning that new value (i.e., how to make something happen), whereas the declarative examples execute on a given input and return the new value based on the initial input (i.e., what we want to happen).

Casa answered 29/1, 2015 at 13:43 Comment(1)
As with frighteningly many answers to this question, your example of 'declarative' programming is an example of functional programming. The semantics of 'map' are 'apply this function to the elements of the array in order'. You're not allowing the runtime any leeway in the order of execution.Thoughtless
S
11

Imperative programming is telling the computer explicitly what to do, and how to do it, like specifying order and such

C#:

for (int i = 0; i < 10; i++)
{
    System.Console.WriteLine("Hello World!");
}

Declarative is when you tell the computer what to do, but not really how to do it. Datalog / Prolog is the first language that comes to mind in this regard. Basically everything is declarative. You can't really guarantee order.

C# is a much more imperative programming language, but certain C# features are more declarative, like Linq

dynamic foo = from c in someCollection
           let x = someValue * 2
           where c.SomeProperty < x
           select new {c.SomeProperty, c.OtherProperty};

The same thing could be written imperatively:

dynamic foo = SomeCollection.Where
     (
          c => c.SomeProperty < (SomeValue * 2)
     )
     .Select
     (
          c => new {c.SomeProperty, c.OtherProperty}
     )

(example from wikipedia Linq)

Sanjiv answered 23/11, 2009 at 17:30 Comment(0)
W
9

In computer science, declarative programming is a programming paradigm that expresses the logic of a computation without describing its control flow.

From http://en.wikipedia.org/wiki/Declarative_programming

in a nutshell the declarative language is simpler because it lacks the complexity of control flow ( loops, if statements, etc. )

A good comparison is the ASP.Net 'code-behind' model. You have declarative '.ASPX' files and then the imperative 'ASPX.CS' code files. I often find that if I can do all I need in the declarative half of the script a lot more people can follow what's being done.

Wurst answered 23/11, 2009 at 17:30 Comment(0)
T
8

Imperative programming - you write the code that does the work

Declarative programming - someone else writes the code that does the work

Tetracaine answered 28/7, 2021 at 23:41 Comment(0)
V
6

Imperative programming
A programming language that requires programming discipline such as C/C++, Java, COBOL, FORTRAN, Perl and JavaScript. Programmers writing in such languages must develop a proper order of actions in order to solve the problem, based on a knowledge of data processing and programming.

Declarative programming
A computer language that does not require writing traditional programming logic; Users concentrate on defining the input and output rather than the program steps required in a procedural programming language such as C++ or Java.

Declarative programming examples are CSS, HTML, XML, XSLT, RegX.

Vibraphone answered 30/11, 2015 at 10:14 Comment(0)
M
4

There were already lots of code examples added, so I'll not add another one.
Instead, I'll try to explain the difference between the two approaches in a way that I think makes their essence clearer than most of the definitions floating around:

  • A declarative approach focuses on the purpose of a particular algorithm, which often hides the algorithm itself.

  • An imperative approach focuses on the algorithm for a particular purpose, which often hides the purpose itself.

Matheson answered 15/12, 2021 at 10:49 Comment(0)
O
4

I found it easier to distinguish between declarative and imperative based upon idempotent and commutative. Use the references to know about them.

Checkout this simplified version to know about idempotent.

Then I bring in the definition of "WHAT" & "HOW" to understand what "WHAT" & "HOW" actually mean. In declarative, you connect one data with another by defining a relationship between them. You don't mention how that relationship should be achieved rather "WHAT" that relationship is. Through a relationship you describe "WHAT" your output data looks like rather than "HOW" to achieve this output data.

Start drawing some diagrams in our head, draw some dots (data) and connect them with lines (relationship). Draw in all possible ways one to many, many to one & one to one. Give arrows to these lines, like this <-----------. All arrows should be facing left because all datas that a particular data is based upon must be calculated first and then move left to calculate that particular data.

If data a is based upon data b, data c and data d which in turn might be based upon on some other datas. Then b, c and d should be calculated first and only then a will be calculated. So a is on the left side of line and all others on the right. There will be 3 lines reaching a one from each of b, c and d.

This diagram has some properties:

  • NO data will violate the relationship it has with all other data
  • control flow or the order doesn't matter, of course b, c and d should be calculated before a but there is no preference between b, c and d i.e. it doesn't matter which one of these 3 is calculated first (commutative)
  • a is only based upon b, c and d and no one else. Hence, it doesn't matter how many times the relationship operation that calculates a using b, c and d is executed, same a should be achieved (idempotent). a is the end result of the relationship operation here. Basically, everyone who is affecting a should have a line pointing to a.

These relationships (lines) are like functions (functions of Mathematics and NOT programming). No doubt functional programming is famous among people of academia. Pure functions (of our programming, therefore not in bold) are like functions (of Maths, therefore in bold).

By now declarative might have started to sound like PURE and IMMUTABLE (which are generally used in Functional Programming) to you, if yes GOOD and if no GREAT. Because that's not the aim here, that's something that automatically emerged out of this pattern.

If your piece of code can be converted into this diagram then it's completely declarative otherwise, it lies somewhere else on the scale.

Declarative is close to Maths.

Now let's zoom in into these relationships (lines), to see what's going on inside the computer during program execution.

Imperative comes in. Here's where that ground-level work is done. In imperative, you mention step by step "HOW" it needs to be done and you know that this sequence of steps will create the requested relationship between one data (inputs b c d) and another data (output a). Here you create variables, mutate them, loop through array and all other things.

Imperative is close to Programming.

Instead of saying a program to be declarative or imperative, I prefer to see it on a scale where on the leftmost side I have completely declarative and on the rightmost side it's completely imperative. Remember, declarative is built on top of imperative, hence any declarative thing you see is actually imperative underneath. Generally, programs are a mixture of declarative and imperative.

Now, let's take these 2 examples:

Second example can be converted to the diagram like this:

      reduce_r       map_r       filter_r
a <--------- b <--------- c <--------- d

  • filter_r (relationship): c is only even numbers of d
  • map_r (relationship): b is all numbers multiplied by 10 of c
  • reduce_r (relationship): a is all numbers added of b

this should look like compound function of maths: reduce_r( map_r( filter_r( d ) ) )

In declarative, the job of developer is to break the ultimate goal (a) into subgoals (b, c) which will help to reach the ultimate goal.

of course under the hood of procedures map, reduce and filter is imperative code running.

Food for thought: if you are required to make an assumption on map function to go from left to right to make your code work as expected, you are actually doing imperative in the name of declarative.

References: purpleidea (James), www.dataops.live, wiki.c2.com

Ostrom answered 12/1, 2022 at 13:31 Comment(1)
Sometimes it also depends upon the way a person looks at something, someone might call it imperative and someone else might call the same thing declarative. Someone might say that reduce is just an abstracted version of "loop through the array from left to right and call reducer on items one by one" (imperative) and someone else might explain it the way I did above in my post without caring about the sequence in which numbers are added (declarative). A good reducer satisfies commutative and associative properties eg: addOstrom
E
4

Just a practical example, of why CSS being declarative and JavaScript being imperative.

Imagine we have this navbar, and the user is currently looking at "Explore" option so it is marked as currently selected.

enter image description here

<ul>
  <li class="selected">
    <p>Explore</p>
  </li>
  <li>
    <p>Suggestions</p>
  </li>
</ul>

We want the title of the currently selected option to be blue, how do we achieve this with CSS and JavaScript?

CSS

li.selected > p {
  color: blue;
}

Here li.selected > p declares the pattern of element to which we want the property color: blue; to be applied. The result is "Explore" is highlighted in blue but "Suggestions" is not. Notice, our code describes what we want to happen and not how. How does CSS selector engine find "Explore"? We don't know and usually don't care.

JavaScript

let liElements = document.getElementsByTagName("li")
for (let i = 0; i < liElements.length; i++) {
  if (liElements[i].className === "selected") {
    let children = liElements[i].childNodes
    for (let j = 0; j < children. length; j++) {
      let child = children[j]
      if (child.nodeType === Node.ELEMENT_NODE && child.tagName === "P") {
        child.setAttribute("style", "color: blue")
      }
    } 
  }
}

This code is much longer and harder to understand. Other than that, it applies blue color to a selected option but never unapply it when selected class is removed. The blue colors are only reset when the page is reloaded. Notice, that with this code we specify exactly what needs to be done and how, step by step.

Conclusion

Each programming paradigm brings its advantages to the table.

CSS (declarative)

  • concise
  • we, as programmers, don't control how the CSS core does what we need. This gives the CSS core developers an opportunity to change the CSS selector implementation at any time. Why would the CSS core need to be changed? Perhaps, the CSS developers found a faster way to apply properties.

JavaScript (imperative)

  • customization. We control all aspects of how our code accomplishes the goal.
  • good for solving wide variety of problems
Edraedrea answered 21/7, 2022 at 20:41 Comment(0)
C
3

From my understanding, both terms have roots in philosophy, there are declarative and imperative kinds of knowledge. Declarative knowledge are assertions of truth, statements of fact like math axioms. It tells you something. Imperative, or procedural knowledge, tells you step by step how to arrive at something. That's what the definition of an algorithm essentially is. If you would, compare a computer programming language with the English language. Declarative sentences state something. A boring example, but here's a declarative way of displaying whether two numbers are equal to each other, in Java:

public static void main(String[] args)
{
    System.out.print("4 = 4.");
}

Imperative sentences in English, on the other hand, give a command or make some sort of request. Imperative programming, then, is just a list of commands (do this, do that). Here's an imperative way of displaying whether two numbers are equal to each other or not while accepting user input, in Java:

private static Scanner input;    

public static void main(String[] args) 
{
    input = new Scanner(System.in);
    System.out.println();
    System.out.print("Enter an integer value for x: ");
    int x = input.nextInt();
    System.out.print("Enter an integer value for y: ");        
    int y = input.nextInt();

    System.out.println();
    System.out.printf("%d == %d? %s\n", x, y, x == y);
}

Essentially, declarative knowledge skips over certain elements to form a layer of abstraction over those elements. Declarative programming does the same.

Campanology answered 5/5, 2015 at 23:12 Comment(0)
C
3

declarative program is just a data for its some more-or-less "universal" imperative implementation/vm.

pluses: specifying just a data, in some hardcoded (and checked) format, is simpler and less error-prone than specifying variant of some imperative algorithm directly. some complex specifications just cant be written directly, only in some DSL form. best and freq used in DSLs data structures is sets and tables. because you not have dependencies between elements/rows. and when you havent dependencies you have freedom to modify and ease of support. (compare for example modules with classes - with modules you happy and with classes you have fragile base class problem) all goods of declarativeness and DSL follows immediately from benefits of that data structures (tables and sets). another plus - you can change implementation of declarative language vm, if DSL is more-or-less abstract (well designed). make parallel implementation, for example. or port it to other os etc. all good specifed modular isolating interfaces or protocols gives you such freedom and easyness of support.

minuses: you guess right. generic (and parameterized by DSL) imperative algorithm/vm implementation may be slower and/or memory hungry than specific one. in some cases. if that cases is rare - just forget about it, let it be slow. if it's frequient - you always can extend your DSL/vm for that case. somewhere slowing down all other cases, sure...

P.S. Frameworks is half-way between DSL and imperative. and as all halfway solutions ... they combines deficiences, not benefits. they not so safe AND not so fast :) look at jack-of-all-trades haskell - it's halfway between strong simple ML and flexible metaprog Prolog and... what a monster it is. you can look at Prolog as a Haskell with boolean-only functions/predicates. and how simple its flexibility is against Haskell...

Costin answered 6/1, 2016 at 4:52 Comment(0)
J
2

Just to add another example in terms of mobile app development. In iOS and Android, we have Interface Builders, where we can define UI of the apps.

The UI drawn using these Builders is declarative in nature, where we drag and drop the components. The actual drawing happens underneath and performed by the framework and system.

But we can also draw the whole components in code, and that is imperative in nature.

Also, some new languages like Angular JS are focussing on designing UIs declaratively and we may see a lot of other languages offering the same support. Like Java doesn't have any good declarative way to draw native desktop apps in Java swing or Java FX but in the near future, they just might.

Joleen answered 22/12, 2013 at 5:51 Comment(0)
B
2

I just wonder why no one has mentioned Attribute classes as a declarative programming tool in C#. The popular answer of this page has just talked about LINQ as a declarative programming tool.

According to Wikipedia

Common declarative languages include those of database query languages (e.g., SQL, XQuery), regular expressions, logic programming, functional programming, and configuration management systems.

So LINQ, as a functional syntax, is definitely a declarative method, but Attribute classes in C#, as a configuration tool, are declarative too. Here is a good starting point to read more about it: Quick Overview of C# Attribute Programming

Balikpapan answered 26/5, 2016 at 11:11 Comment(1)
This is a good point and a more obvious example I think.Things like linq can still seem imperative so it's confusing for people who don't know the difference but Attributes are hard to see any other way than declarative.You're literally slapping little "tags" onto members to declare what you want done to them but you're not saying the how in any sense.I can see how someone could say a linq query is still sort of saying the how because at some level you are describing a form of logic that just isn't as heavy, but with attributes you aren't describing any logic at all.You're just labeling thingsProclamation
P
0

You've asked for an example in C#, which is a highly "imperative" language. Imperative and declarative fall on two ends of a spectrum of "what" vs. "how", and they are often blended. On the declarative end, consider pure HTML or CSS (without scripts). An HTML doc like <body><p>Hello World</p></body> contains no imperative commands at all; in this case it really does just declare "what" the result should be. On the imperative end, consider a C statement like void main(){ printf("Hello World\n");}. This is purely "imperative," formed as a list of commands telling the computer "how" to do the job.

Consider an SQL statement like SELECT * FROM customers WHERE balance > 0;. This falls somewhere in the middle. It has a declarative aspect in the FROM and WHERE clauses, describing "what" the result should be. But it is clearly structured as an imperative statement starting off with a SELECT command.

If you ask the question in the context of a highly imperative programming language you're usually going to get an example of "functional" programming, where some basic imperative operations are wrapped up so they can be used in a more declarative style. The usual example is a "for-loop" function used to perform common operations on an array or object. You get something like let evenNums = myNums.where(number => number % 2 == 0); This is essentially an imperative statement instructing the computer to create a variable and assign a value to it, but it invokes a "where" function that gives it a declarative feel. It does include a truncated function call, but the mechanics of the for-loop are swapped out for the "where." It has to be placed closer to the imperative end of the scale than the SQL example, but in the context of an imperative language it's still relatively declarative. This is why it's hard to get a clear-cut answer.

Note that the "where" function and all the other built-in "functional" methods for handling arrays and objects are basically wrappers around a for-loop. They just have more declarative-style names and signatures that result in clearer code (usually). Whenever you write a function, and you're encapsulating a bunch of imperative statements, give your functions declarative-style names that describe "what" they return--you can be a declarative-programming god too.

Pyongyang answered 30/4, 2023 at 15:57 Comment(0)
A
-3

I think this concept is often over-complicated.

Declarative Programming = calling a function

Imperative Programming = defining a function

Really, that's what it is. In short and simple terms, declarative programming is calling some abstracted pre-defined function that someone else programmed.

Take a look at the top-rated answer:

// Declarative: You call Where()
var results = collection.Where(num => num % 2 != 0); 

// Imperative: You implement Where()
List<int> results = new List<int>(); 
    foreach(var num in collection) { 
        if (num % 2 != 0)
            results.Add(num);
}

Or another one:

var numbers = [1,2,3,4,5]
var doubled = []

// Imperative: You implement map()
for(var i = 0; i < numbers.length; i++) {
  var newNumber = numbers[i] * 2
  doubled.push(newNumber)
}
console.log(doubled) //=> [2,4,6,8,10]
var numbers = [1,2,3,4,5]

// Declarative: You call map()
var doubled = numbers.map(function(n) {
  return n * 2
})
console.log(doubled) //=> [2,4,6,8,10]
var numbers = [1,2,3,4,5]
var total = 0

// Imperative: You implement reduce()
for(var i = 0; i < numbers.length; i++) {
  total += numbers[i]
}
console.log(total) //=> 15
var numbers = [1,2,3,4,5]

// Declarative: You call reduce()
var total = numbers.reduce(function(sum, n) {
  return sum + n
});
console.log(total) //=> 15

If you want to get more deep, there is a spectrum:

  • The more pre-defined functions you use, the more "declarative" it is.
  • The less functions you use, the more "imperative" it is.

Take another example that was given:

// Least declarative: Mostly implemented
const bestProducts = [];
for(let i = 0; i < products.length; i++) {
    let product = products[i];
    if (product.rating >= 5 && product.price < 100) {
        bestProducts.push(product);
    }
}

// More declarative: Function called, less implementation
const bestProducts = products.filter(function(product) {
    return product.rating >= 5 && product.price < 100;
});

// Most declarative: Function called, no implementation
const bestProducts = getBestProducts();
Andizhan answered 31/10, 2023 at 4:27 Comment(2)
......... what? care to expand?Leifeste
It's a simpler way of saying all of the things others have been saying here. With declarative programming, you're really calling some abstracted pre-defined function. With imperative programming, you're building it from the ground up. Take a look at the top answer: ``` // declarative var results = collection.Where( num => num % 2 != 0); // imperative List<int> results = new List<int>(); foreach(var num in collection) { if (num % 2 != 0) results.Add(num); } ```Andizhan

© 2022 - 2024 — McMap. All rights reserved.