Besides a Declarative Language, Is SQL a Functional Language

What is the difference between functional programming and declarative programming?

A non-functional declarative language is PROLOG. Programming in PROLOG is stating a number of facts, and then ask questions, which the system tries to verify or deny.

Example:

human(socrates).       // "Socrates is a human."
mortal(X) :- human(X). // "If X is a human, then X is mortal" or
// "All humans are mortal."

? mortal(socrates) // Is Socrates mortal?
Yes.
? mortal(X) // Who is mortal?
socrates
? mortal(pythagoras).
No. // since system doesn't know about any human except Socrates

Another well known language that is declarative, but not functional, is SQL.

Note that there are not only no functions as first class values. In the PROLOG example, there are no functions at all! To be sure, both SQL and PROLOG have some built-in functions, but have no way to let you write your own functions. One could think that the rule

mortal(X) :- human(X).

is a function, but it isn't, it is an inference rule. Hence, declarative, non-functional languages.

For the second part of your question: it is certainly possible to write imperative code in functional programming languages. Simon Peyton Jones once stated that he thinks that Haskell is the finest imperative programming language in the world. (And this was only a half joke.)

Example:

 main = do
print "Enter a number"
line <- getLine
print (succ (read line :: Int))

Is functional programming a type of declarative programming?

Short answer: No.

Wikipedia defines declarative programming as:

In computer science, declarative programming is a programming
paradigm - a style of building the structure and elements of computer
programs - that expresses the logic of a computation without describing
its control flow
.

Or to state it a bit boldly: "Say what you want, not how you want it.".

This is thus in contrast with imperative programming languages where a program is seen as a set of instructions that are done one after another. The fact that map, etc. do not reveal the procedure does not make it declarative: one can use a lot of C libraries that are proprietary and do not allow you to inspect the source code. That however, does not mean that these are declarative.

The definition of functional programming on the other hand is:

In computer science, functional programming is a programming paradigm
- a style of building the structure and elements of computer programs - that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data. It is a declarative
programming paradigm
, which means programming is done with expressions
or declarations instead of statements.

Based on these definitions one could say that functional programming is a subset of declarative programming. In a practical sense however if we follow the strict definitions, no programming language nowadays is purely, and un-ambigously declarative or functional. One can however say that Haskell is more declarative than Java.

Declarative programming is usually considered to be "safer" since people tend to have trouble managing side-effects. A lot of programming errors are the result of not taking all side effects into account. On the other hand it is hard to

  1. design a language that allows a programmer to describe what he wants without going into details on how to do it;
  2. implement a compiler that will generate - based on such programs - an efficient implementation; and
  3. some problems have inherent side effects. For instance if you work with a database, a network connection or a file system, then reading/writing to a file for instance is supposed to have side effects. One can of course decide not to make this part of the programming language (for instance many constraint programming languages do not allow these type of actions, and are a "sub language" in a larger system).

There have been several attempts to design such language. The most popular are - in my opinion - logic programming, functional programming, and constraint programming. Each has its merits and problems. We can also observe this declarative approach in for instance databases (like SQL) and text/XML processing (with XSLT, XPath, regular expressions,...) where one does not specify how a query is resolved, but simply specifies through for instance the regular expression what one is looking for.

Whether a programming language is however declarative, is a bit of a fuzzy discussion. Although programming languages, modeling languages and libraries like Haskell, Prolog, Gecode,... have definitely made programming more declarative, these are probably not declarative in the most strict sense. In the most strict sense, one should think that regardless how you write the logic, the compiler will always come up with the same result (although it might take a bit longer).

Say for instance we want to check whether a list is empty in Haskell. We can write this like:

is_empty1 :: [a] -> Bool
is_empty1 [] = True
is_empty1 (_:_) = False

We can however write it like this as well:

is_empty2 :: [a] -> Bool
is_empty2 l = length l == 0

Both should give the same result for the same queries. If we however give it an infinite list, is_empty1 (repeat 0) will return False whereas is_empty2 (repeat 0) will loop forever. So that means that we somehow still wrote some "control flow" into the program: we have defined - to some extent - how Haskell should evaluate this. Although lazy programming will result in the fact that a programmer does not really specify what should be evaluated first, there are still specifications how Haskell will evaluate this.

According to some people, this is the difference between programming and specifying. One of my professors once stated that according to him, the difference is that when you program something, you have somehow control about how something is evaluated, whereas when you specify something, you have no control. But again, this is only one of the many definitions.

Functional Programming Vs Declarative Programming Vs Imperative Programming

Your example of declarative programming above is not an actual program, so it's not a good example.

The main difference is between imperative and declarative. Functional is a particular kind of declarative.

C, C++, Java, Javascript, BASIC, Python, Ruby, and most other programming languages are imperative. As a rule, if it has explicit loops (for, while, repeat) that change variables with explicit assignment operations at each loop, then it's imperative.

SQL and XSLT are two well-known examples of declarative programming. Markup languages such as HTML and CSS are declarative too, although they are usually not powerful enough to describe arbitrary algorithms.

Here is an example computation (summing the income by gender, from a suitable data source) first written in an imperative language (Javascript) and then in a declarative language (SQL).

Imperative programming

var income_m = 0, income_f = 0;
for (var i = 0; i < income_list.length; i++) {
if (income_list[i].gender == 'M')
income_m += income_list[i].income;
else
income_f += income_list[i].income;
}

Notice:

  • explicit initialization of variables that will contain the running totals;
  • explicit loop over the data, modifying the control variable (i) and the running totals at each iteration;
  • conditionals (ifs) are only used to choose the code path at each iteration.

Declarative programming

select gender, sum(income)
from income_list
group by gender;

Notice:

  • memory cells to contain running totals are implied by the output you declare you want;
  • any loop the CPU will need to perform (eg. over the income_list table) is implied by the output you declare you want and by the structure of the source data;
  • conditionals (eg. case in SQL) are used in a functional way to specify the output value you want based on the input values, not to choose a code path.

Functional programming

As I mentioned above, SQL's case is a great example of the functional way of programming, which is a restricted subset of Declarative programming in which the desired computation is specified by composing functions.

Functions are things that accept inputs and return outputs (eg. case, sum()…)

Composition means chaining two or more together by specifying how the output of one is fed as the input to the next (typically by writing one inside the other.) Finally the whole composition, which is still itself a big function, is applied to the available inputs to get the desired output.

In this snippet I am declaring the output I want by composing the functions sum() and case. This is called functional programming:

select 
sum(case when some_flag = 'X' then some_column
else some_other_column end)
from
...

If the composition of two or more functions and their application to the input data are the only constructs available in a given language, that language is said to be purely functional. In those languages you will notice the complete absence of loops, variable assignment and other typically imperative statements.


Edit: I recommend watching some of Anjana Vakil's talks on functional programming in Javascript, to get a better idea of what it's about.

What is the difference between declarative and procedural programming paradigms?

Imperative

There are several sub-paradigms of the imperative programming paradigm, such as the procedural or the object-oriented programming paradigms.

In the imperative programming paradigm, you describe the algorithm step-by-step, at various degrees of abstraction.

Examples of programming languages which support the procedural paradigm:

  • C (and most other legacy languages)
  • PHP, mostly
  • In some sense, all major languages

Object-Oriented

It typically refers to languages that exhibit a hierarchy of types that inherit both methods and state from base types to derived types, but also includes the unusual prototype-based JavaScript.

Examples of programming languages which support the OO paradigm:

  • Java

Declarative

There are several sub-paradigms of the declarative programming paradigm, such as the functional or the logic programming paradigms.

In the declarative programming paradigm, you describe a result or a goal, and you get it via a "black box". The opposite of imperative.

Examples of programming languages which support the declarative programming paradigm:

  • yacc
  • Treetop
  • SQL
  • Regular Expressions
  • lex
  • XSLT
  • markup, troff, CSS, VHDL

Functional

Functional programming emphasizes the application of functions without side effects and without mutable state. The declarative systems above exhibit certain aspects of functional programming.

Examples of programming languages which support the declarative functional paradigm:

  • Haskell
  • OCaml
  • Scheme
  • Erlang
  • F#
  • Scala

What is declarative programming?

Declarative programming is when you write your code in such a way that it describes what you want to do, and not how you want to do it. It is left up to the compiler to figure out the how.

Examples of declarative programming languages are SQL and Prolog.

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

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.

Please help me understand SQL vs C like programming?

They are approaching the world from different points of view. C is about performing actions. SQL is about storing data, and manipulating data. The only "actions" it is good at are pulling and changing data.

Think of all your data like a Venn diagram- SQL lets you "look" at any part of that diagram you want.

If you want to actually do something to that data, then in C, you might say "Go to every user and perform this action on them", as in

//if a customer is late, send them a reminder
for(int i=0;i<USER_COUNT-1;++i){
if(LATE_ON_PAYMENTS=CustomerType(Customers[i])){
SendReminder(Customers[i]);
} //if cust is late on their payments
} //for ea customer

In SQL, you would be able to ASK for the list of users, as in:

SELECT *
FROM CUSTOMERS
WHERE LATE_FLAG = 'Y';

Or you could change data regarding those customers, as in:

UPDATE CUSTOMERS
SET TRUST_LEVEL = TRUST_LEVEL - 1 --trust a little less when they are late
WHERE LATE_FLAG = 'Y';

Note that this UPDATE could affect any number of rows, but there is no loop... you are simply saying "look up these records, and change them in this way".

But if you wanted to send them a reminder, well that's just too bad... you've got to use C or a stored procedure to do that.

You really get the best of both worlds when you combine a traditional language with SQL. If you can replace the earlier example in C with this (disclaimer: I know this is bogus code, it's just an example):

//if a customer is late, send them a reminder

//get all the late customers
sqlCommand = 'SELECT CUSTOMER_ID FROM CUSTOMERS WHERE LATE_FLAG = ''Y''';
dataSet = GetDataSet(sqlCommand);

//now loop through the late customers i just retrieved
for(int i=0;i<dataSet.RecordCount - 1;++i){
SendReminder(dataSet[i].Field('CUSTOMER_ID'));
} //for ea customer

Now the code is more readable, and everyone is pointed at the same data source at runtime.
You also avoid the potentially messy code in C that would have been involved in building your list of customers - now it is just a dataset.

Just as SQL sucks at doing imperative actions, C sucks at manipulating data sets. Used together, they can easily get data, manipulate it, and perform actions on it.



Related Topics



Leave a reply



Submit