Alloy 4, Software Abstractions 2E, and the seq keyword - alloy

Not long ago I acquired the second edition of Software Abstractions, and when I needed to refresh my memory on how to spell the name of the elems function I thought "Oh, good, I can check the new edition instead of trying to read my illegible handwritten notes in the end-papers of the first edition."
But I can't find "seq" or "elems" or the names of any of the other helper functions in the index, nor do I see any mention of the seq keyword in the language reference in Appendix B.
One or more of the following seems likely to be the case; which?
I am missing something. (What? where?)
The seq keyword is not covered in Appendix B because it's not strictly speaking a keyword in the way that set and the other unary operators are. (Please expound!)
The support for sequences was added to Alloy 4 after the second edition went to press, and so the book needs to be augmented by reference to the discussion of new features in Alloy 4 in the Quick Guide and the Alloy 4 grammar on the Web site. (Ah, OK. Pages are slow, bits are fast.)
Other ...
I guess, to try to put a generally useful question here, that I'm asking: what exactly is the relation between the language implemented by the Alloy Analyzer 4.2 (or any 4.*) and the language defined in Software abstractions second edition?

The current implementation corresponds to this online documentation.
Sequences are really not part of the language; x: seq A can be seen just as a syntactic sugar for x: Int -> A, and all the utility functions (e.g., first, last, elems) are library-defined (in util/sequence). The actual implementation is a little more complicated (just so that we can let the user write something like x.elems and make the type checker happy at the same time), but conceptually that's what's going on.

Related

Is there a standardized way to transform functional code to imperative code?

I'm writing a small tool for generating php checks from javascript code, and I would like to know if anyone knows of a standard way of transforming functional code into imperative code?
I found this paper: Defunctionalization at Work it explains defunctionalization pretty well.
Lambdalifting and defunctionalization somewhat answered the question, but what about datastructures, we are still parsing lists as if they are all linkedlists. Would there be a way of transforming the linkedlists of functional languages into other high-level datastructures like c++ vectors or java arraylists?
Here are a few additions to the list of #Artyom:
you can convert tail recursion into loops and assignments
linear types can be used to introduce assignments, e.g. y = f x can be replaced with x := f x if x is linear and has the same type as y
at least two kinds of defunctionalization are possible: Reynolds-type defunctionalization when you replace a high-order application with a switch full of first-order applications, and inlining (however, recursive functions is not always possible to inline)
Perhaps you are interested in removing some language elements (such as higher-order functions), right?
For eliminating HOFs from a program, there are techniques such as defunctionalization. For removing closures, you can use lambda-lifting (aka closure conversion). Is this something you are interested in?
I think you need to provide a concrete example of code you have, and the target code you intend to produce, so that others may propose solutions.
Added:
Would there be a way of transforming the linkedlists of functional languages into other high-level datastructures like c++ vectors or java arraylists?
Yes. Linked lists are represented with pointers in C++ (a structure "node" with two fields: one for the "payload", another for the "next" pointer; empty list is then represented as a NULL pointer, but sometimes people prefer to use special "sentinel values"). Note that, if the code in the source language does not rely on the representation of singly linked lists (in the source language implementation), you can also implement the "cons"/"nil" operations using a vector in the target language (not sure if this suits your needs, though). The idea here is to give an alternative implementations for the familiar operations.
No, there is not.
The reason is that there is no such concrete and well defined thing like functional code or imperative code.
Such transformations exist only for concrete instances of your abstraction: for example, there are transformations from Haskell code to LLVM bytecode, F# code to CLI bytecode or Frege code to Java code.
(I doubt if there is one from Javascript to PHP.)
Depends on what you need. The usual answer is "there is no such tool", because the result will not be usable. However look at this from this standpoint:
The set of Assembler instructions in a computer defines an imperative machine. Hence the compiler needs to do such a translation. However I assume you do not want to have assembler code but something more readable.
Usually these kinds of heavy program transformations are done manually, if one is interested in the result, or automatically if the result will never be looked at by a human.

Mathematica: what is symbolic programming?

I am a big fan of Stephen Wolfram, but he is definitely one not shy of tooting his own horn. In many references, he extols Mathematica as a different symbolic programming paradigm. I am not a Mathematica user.
My questions are: what is this symbolic programming? And how does it compare to functional languages (such as Haskell)?
When I hear the phrase "symbolic programming", LISP, Prolog and (yes) Mathematica immediately leap to mind. I would characterize a symbolic programming environment as one in which the expressions used to represent program text also happen to be the primary data structure. As a result, it becomes very easy to build abstractions upon abstractions since data can easily be transformed into code and vice versa.
Mathematica exploits this capability heavily. Even more heavily than LISP and Prolog (IMHO).
As an example of symbolic programming, consider the following sequence of events. I have a CSV file that looks like this:
r,1,2
g,3,4
I read that file in:
Import["somefile.csv"]
--> {{r,1,2},{g,3,4}}
Is the result data or code? It is both. It is the data that results from reading the file, but it also happens to be the expression that will construct that data. As code goes, however, this expression is inert since the result of evaluating it is simply itself.
So now I apply a transformation to the result:
% /. {c_, x_, y_} :> {c, Disk[{x, y}]}
--> {{r,Disk[{1,2}]},{g,Disk[{3,4}]}}
Without dwelling on the details, all that has happened is that Disk[{...}] has been wrapped around the last two numbers from each input line. The result is still data/code, but still inert. Another transformation:
% /. {"r" -> Red, "g" -> Green}
--> {{Red,Disk[{1,2}]},{Green,Disk[{3,4}]}}
Yes, still inert. However, by a remarkable coincidence this last result just happens to be a list of valid directives in Mathematica's built-in domain-specific language for graphics. One last transformation, and things start to happen:
% /. x_ :> Graphics[x]
--> Graphics[{{Red,Disk[{1,2}]},{Green,Disk[{3,4}]}}]
Actually, you would not see that last result. In an epic display of syntactic sugar, Mathematica would show this picture of red and green circles:
But the fun doesn't stop there. Underneath all that syntactic sugar we still have a symbolic expression. I can apply another transformation rule:
% /. Red -> Black
Presto! The red circle became black.
It is this kind of "symbol pushing" that characterizes symbolic programming. A great majority of Mathematica programming is of this nature.
Functional vs. Symbolic
I won't address the differences between symbolic and functional programming in detail, but I will contribute a few remarks.
One could view symbolic programming as an answer to the question: "What would happen if I tried to model everything using only expression transformations?" Functional programming, by contrast, can been seen as an answer to: "What would happen if I tried to model everything using only functions?" Just like symbolic programming, functional programming makes it easy to quickly build up layers of abstractions. The example I gave here could be easily be reproduced in, say, Haskell using a functional reactive animation approach. Functional programming is all about function composition, higher level functions, combinators -- all the nifty things that you can do with functions.
Mathematica is clearly optimized for symbolic programming. It is possible to write code in functional style, but the functional features in Mathematica are really just a thin veneer over transformations (and a leaky abstraction at that, see the footnote below).
Haskell is clearly optimized for functional programming. It is possible to write code in symbolic style, but I would quibble that the syntactic representation of programs and data are quite distinct, making the experience suboptimal.
Concluding Remarks
In conclusion, I advocate that there is a distinction between functional programming (as epitomized by Haskell) and symbolic programming (as epitomized by Mathematica). I think that if one studies both, then one will learn substantially more than studying just one -- the ultimate test of distinctness.
Leaky Functional Abstraction in Mathematica?
Yup, leaky. Try this, for example:
f[x_] := g[Function[a, x]];
g[fn_] := Module[{h}, h[a_] := fn[a]; h[0]];
f[999]
Duly reported to, and acknowledged by, WRI. The response: avoid the use of Function[var, body] (Function[body] is okay).
You can think of Mathematica's symbolic programming as a search-and-replace system where you program by specifying search-and-replace rules.
For instance you could specify the following rule
area := Pi*radius^2;
Next time you use area, it'll be replaced with Pi*radius^2. Now, suppose you define new rule
radius:=5
Now, whenever you use radius, it'll get rewritten into 5. If you evaluate area it'll get rewritten into Pi*radius^2 which triggers rewriting rule for radius and you'll get Pi*5^2 as an intermediate result. This new form will trigger a built-in rewriting rule for ^ operation so the expression will get further rewritten into Pi*25. At this point rewriting stops because there are no applicable rules.
You can emulate functional programming by using your replacement rules as function. For instance, if you want to define a function that adds, you could do
add[a_,b_]:=a+b
Now add[x,y] gets rewritten into x+y. If you want add to only apply for numeric a,b, you could instead do
add[a_?NumericQ, b_?NumericQ] := a + b
Now, add[2,3] gets rewritten into 2+3 using your rule and then into 5 using built-in rule for +, whereas add[test1,test2] remains unchanged.
Here's an example of an interactive replacement rule
a := ChoiceDialog["Pick one", {1, 2, 3, 4}]
a+1
Here, a gets replaced with ChoiceDialog, which then gets replaced with the number the user chose on the dialog that popped up, which makes both quantities numeric and triggers replacement rule for +. Here, ChoiceDialog as a built-in replacement rule along the lines of "replace ChoiceDialog[some stuff] with the value of button the user clicked".
Rules can be defined using conditions which themselves need to go through rule-rewriting in order to produce True or False. For instance suppose you invented a new equation solving method, but you think it only works when the final result of your method is positive. You could do the following rule
solve[x + 5 == b_] := (result = b - 5; result /; result > 0)
Here, solve[x+5==20] gets replaced with 15, but solve[x + 5 == -20] is unchanged because there's no rule that applies. The condition that prevents this rule from applying is /;result>0. Evaluator essentially looks the potential output of rule application to decide whether to go ahead with it.
Mathematica's evaluator greedily rewrites every pattern with one of the rules that apply for that symbol. Sometimes you want to have finer control, and in such case you could define your own rules and apply them manually like this
myrules={area->Pi radius^2,radius->5}
area//.myrules
This will apply rules defined in myrules until result stops changing. This is pretty similar to the default evaluator, but now you could have several sets of rules and apply them selectively. A more advanced example shows how to make a Prolog-like evaluator that searches over sequences of rule applications.
One drawback of current Mathematica version comes up when you need to use Mathematica's default evaluator (to make use of Integrate, Solve, etc) and want to change default sequence of evaluation. That is possible but complicated, and I like to think that some future implementation of symbolic programming will have a more elegant way of controlling evaluation sequence
As others here already mentioned, Mathematica does a lot of term rewriting. Maybe Haskell isn't the best comparison though, but Pure is a nice functional term-rewriting language (that should feel familiar to people with a Haskell background). Maybe reading their Wiki page on term rewriting will clear up a few things for you:
http://code.google.com/p/pure-lang/wiki/Rewriting
Mathematica is using term rewriting heavily. The language provides special syntax for various forms of rewriting, special support for rules and strategies. The paradigm is not that "new" and of course it's not unique, but they're definitely on a bleeding edge of this "symbolic programming" thing, alongside with the other strong players such as Axiom.
As for comparison to Haskell, well, you could do rewriting there, with a bit of help from scrap your boilerplate library, but it's not nearly as easy as in a dynamically typed Mathematica.
Symbolic shouldn't be contrasted with functional, it should be contrasted with numerical programming. Consider as an example MatLab vs Mathematica. Suppose I want the characteristic polynomial of a matrix. If I wanted to do that in Mathematica, I could do get an identity matrix (I) and the matrix (A) itself into Mathematica, then do this:
Det[A-lambda*I]
And I would get the characteristic polynomial (never mind that there's probably a characteristic polynomial function), on the other hand, if I was in MatLab I couldn't do it with base MatLab because base MatLab (never mind that there's probably a characteristic polynomial function) is only good at calculating finite-precision numbers, not things where there are random lambdas (our symbol) in there. What you'd have to do is buy the add-on Symbolab, and then define lambda as its own line of code and then write this out (wherein it would convert your A matrix to a matrix of rational numbers rather than finite precision decimals), and while the performance difference would probably be unnoticeable for a small case like this, it would probably do it much slower than Mathematica in terms of relative speed.
So that's the difference, symbolic languages are interested in doing calculations with perfect accuracy (often using rational numbers as opposed to numerical) and numerical programming languages on the other hand are very good at the vast majority of calculations you would need to do and they tend to be faster at the numerical operations they're meant for (MatLab is nearly unmatched in this regard for higher level languages - excluding C++, etc) and a piss poor at symbolic operations.

Is there a language with native pass-by-reference/pass-by-name semantics, which could be used in modern production applications?

This is a reopened question.
I look for a language and supporting platform for it, where the language could have pass-by-reference or pass-by-name semantics by default. I know the history a little, that there were Algol, Fortran and there still is C++ which could make it possible; but, basically, what I look for is something more modern and where the mentioned value pass methodology is preferred and by default (implicitly assumed).
I ask this question, because, to my mind, some of the advantages of pass-by-ref/name seem kind of obvious. For example when it is used in a standalone agent, where copyiong of values is not necessary (to some extent) and performance wouldn't be downgraded much in that case. So, I could employ it in e.g. rich client app or some game-style or standalone service-kind application.
The main advantage to me is the clear separation between identity of a symbol, and its current value. I mean when there is no reduntant copying, you know that you're working with the exact symbol/path you have queried/received. And intristing boxing of values will not interfere with the actual logic of program.
I know that there is C# ref keyword, but it's something not so intristic, though acceptable. Equally, I realize that pass-by-reference semantics could be simulated in virtually any language (Java as an instant example) and so on.. not sure about pass by name :)
What would you recommend - create a something like DSL for such needs wherever it be appropriate; or use some languages that I already know? Maybe, there is something that I'm missing?
Thank you!
UPDATE: Currently, I think that Haskell would be appropriate. But I didn't investigate much, so I think I'll update this text later.
Scala provides very flexible parameter passing semantics including real call-by-name:
def whileLoop(cond: => Boolean)(body: => Unit) {
if (cond) {
body
whileLoop(cond)(body)
}
}
And it really works
var i = 10
whileLoop (i > 0) {
println(i)
i -= 1
}
Technical details:
Though all parameters are passed by value (and these are usually references) much like Java, the notation => Type will make Scala generate the required closures automatically in order to emulate call-by-name.
Note that there is lazy evaluation too.
lazy val future = evalFunc()
The interesting thing is that you have consistent strict call-by-value semantics but can punctually change these where you really need to - nearly without any syntactic overhead.
Haskell has call-by-need as its default (and indeed only) evaluation strategy.
Now, you asked for two things: call-by-name and modern. Well, Haskell is a pure language and in a pure language call-by-name and call-by-need are semantically the same thing, or more precisely they always have the same result, the only difference being that call-by-need is usually faster and at worst only a constant factor slower than call-by-name. And Haskell surely is a modern language: it is merely 23 years old and in many of its features it is actually 10 years ahead of many languages that were created just recently.
The other thing you asked about is call-by-reference. Again, in a pure language, call-by-value and call-by-reference are the same thing, except that the latter is faster. (Which is why, even though most functional languages are usually described as being call-by-value, they actually implement call-by-reference.)
Now, call-by-name (and by extension call-by-need) are not the same thing as call-by-value (and by extension call-by-reference), because call-by-name may return a result in cases where call-by-value doesn't terminate.
However, in all cases where call-by-value or call-by-reference terminates, in a pure language, call-by-value, call-by-reference, call-by-name and call-by-need are the same thing. And in cases where they are not the same thing, call-by-name and call-by-need are in some sense "better", because they give you an answer in cases where call-by-value and call-by-reference would basically have run into an infinite loop.
Ergo, Haskell is your answer. Although probably not the one you were looking for :-)
Pass-by name is rare nowadays. However, you can simulate it in most functional programming languages using a lambda-nill:
// Pass by value
(dosomething (random))
// Pass by name hack
(dosomething (lambda () (random)))
Other then that: ML and O'CaML has a distinction between pass-by-value (default), pass-by-ref (using ref variables) and of course using lambdas. However, I'm not sure either of them qualifies as a "modern" language.
I'm not quite following your reasoning for why C#'s ref and out modifiers aren't "intrinsic." Seems to me that it provides almost exactly what you're looking for: A modern language and environment that supports pass-by-value and pass-by-reference. (As Little Bobby Tables pointed out, pass-by-name is very rare these days, you're better off with a lambda/closure.)
AFAIK, modern Fortran is pass-by-reference (preserving compatibility with ye olde FORTRAN).
Modern Fortran has all the niceties you expect of a modular language, so you can build just fine systems in it. Nobody does, because "Fortran is passe" and everybody wants to code in C# "because its cool.".
In Java, all objects are passed by reference.

Programming Language with Inflection

Is there a programming language that uses inflections (suffixing a word to add a certain meaning) instead of operators to express instructions? Just wondering.
What I am talking about is using inflections to add a meaning to an identifier such as a variable or type name.
For example:
native type integer
var x : integer = 12
var location : integers = 12, 5, 42
say 0th locationte to_string (( -te replaces "." operator. prints 12 ))
I think Perligata (Perl in Latin) is what you're looking for. :) From the article
There is no reason why programming
languages could not also use
inflexions, rather than position, to
denote lexical roles.
Here's an example program (Sieve of Eratosthenes):
#! /usr/local/bin/perl -w
use Lingua::Romana::Perligata;
maximum inquementum tum biguttam egresso scribe.
meo maximo vestibulo perlegamentum da.
da duo tum maximum conscribementa meis listis.
dum listis decapitamentum damentum nexto
fac sic
nextum tum novumversum scribe egresso.
lista sic hoc recidementum nextum cis vannementa da listis.
cis.
This is partially facetious, but... assembly language? Things like conditional jump instructions are often variations on a root ("J" for jump or whatnot) with suffixes added to denote the associated condition ("JNZ" for jump-if-not-zero, et cetera).
The excellent (dare I say fascinating) game-design language Inform 7 is inflected like English. But it's so closely integrated with a host of other design decisions that it's hard to peel away as a separate feature.
Anyone who is interested in language designs that are unusual but successful should check out Inform 7.
Presumably any programming language that uses natural language explicitly or closely as a basis, e.g., Natural-Language Programming. There was some research done at MIT into using English to produce high-level skeletons of programs, which is more in the realm of natural-language processing; the tool they created is called Metafor.
As far as I know, no existing language has support for, say, modifying or extending keywords with inflection. Now you've got me interested, though, so I'm sure I'll come up with something soon!
Of the 40 or so languages I know, the only thing that comes to mind is some rare SQL implementations which include friendly aliases. For example to select a default database after connecting, the standard is USE <some database name> but one I used somewhere which also allowed USING <some database name>.
FORTRAN uses the first letter of the name to determine the type of an implicitly-declared variable.
COBOL has singular and plural versions of its "figurative constants", e.g. SPACE and SPACES.
Python3.7 standard module contextvars has Context Variables, which can be used for inflection..

What is declarative programming? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Closed 7 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
I keep hearing this term tossed around in several different contexts. What is it?
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.
The other answers already do a fantastic job explaining what declarative programming is, so I'm just going to provide some examples of why that might be useful.
Context Independence
Declarative Programs are context-independent. Because they only declare what the ultimate goal is, but not the intermediary steps to reach that goal, the same program can be used in different contexts. This is hard to do with imperative programs, because they often depend on the context (e.g. hidden state).
Take yacc as an example. It's a parser generator aka. compiler compiler, an external declarative DSL for describing the grammar of a language, so that a parser for that language can automatically be generated from the description. Because of its context independence, you can do many different things with such a grammar:
Generate a C parser for that grammar (the original use case for yacc)
Generate a C++ parser for that grammar
Generate a Java parser for that grammar (using Jay)
Generate a C# parser for that grammar (using GPPG)
Generate a Ruby parser for that grammar (using Racc)
Generate a tree visualization for that grammar (using GraphViz)
simply do some pretty-printing, fancy-formatting and syntax highlighting of the yacc source file itself and include it in your Reference Manual as a syntactic specification of your language
And many more …
Optimization
Because you don't prescribe the computer which steps to take and in what order, it can rearrange your program much more freely, maybe even execute some tasks in parallel. A good example is a query planner and query optimizer for a SQL database. Most SQL databases allow you to display the query that they are actually executing vs. the query that you asked them to execute. Often, those queries look nothing like each other. The query planner takes things into account that you wouldn't even have dreamed of: rotational latency of the disk platter, for example or the fact that some completely different application for a completely different user just executed a similar query and the table that you are joining with and that you worked so hard to avoid loading is already in memory anyway.
There is an interesting trade-off here: the machine has to work harder to figure out how to do something than it would in an imperative language, but when it does figure it out, it has much more freedom and much more information for the optimization stage.
Loosely:
Declarative programming tends towards:-
Sets of declarations, or declarative statements, each of which has meaning (often in the problem domain) and may be understood independently and in isolation.
Imperative programming tends towards:-
Sequences of commands, each of which perform some action; but which may or may not have meaning in the problem domain.
As a result, an imperative style helps the reader to understand the mechanics of what the system is actually doing, but may give little insight into the problem that it is intended to solve. On the other hand, a declarative style helps the reader to understand the problem domain and the approach that the system takes towards the solution of the problem, but is less informative on the matter of mechanics.
Real programs (even ones written in languages that favor the ends of the spectrum, such as ProLog or C) tend to have both styles present to various degrees at various points, to satisfy the varying complexities and communication needs of the piece. One style is not superior to the other; they just serve different purposes, and, as with many things in life, moderation is key.
Here's an example.
In CSS (used to style HTML pages), if you want an image element to be 100 pixels high and 100 pixels wide, you simply "declare" that that's what you want as follows:
#myImageId {
height: 100px;
width: 100px;
}
You can consider CSS a declarative "style sheet" language.
The browser engine that reads and interprets this CSS is free to make the image appear this tall and this wide however it wants. Different browser engines (e.g., the engine for IE, the engine for Chrome) will implement this task differently.
Their unique implementations are, of course, NOT written in a declarative language but in a procedural one like Assembly, C, C++, Java, JavaScript, or Python. That code is a bunch of steps to be carried out step by step (and might include function calls). It might do things like interpolate pixel values, and render on the screen.
I am sorry, but I must disagree with many of the other answers. I would like to stop this muddled misunderstanding of the definition of declarative programming.
Definition
Referential transparency (RT) of the sub-expressions is the only required attribute of a declarative programming expression, because it is the only attribute which is not shared with imperative programming.
Other cited attributes of declarative programming, derive from this RT. Please click the hyperlink above for the detailed explanation.
Spreadsheet example
Two answers mentioned spreadsheet programming. In the cases where the spreadsheet programming (a.k.a. formulas) does not access mutable global state, then it is declarative programming. This is because the mutable cell values are the monolithic input and output of the main() (the entire program). The new values are not written to the cells after each formula is executed, thus they are not mutable for the life of the declarative program (execution of all the formulas in the spreadsheet). Thus relative to each other, the formulas view these mutable cells as immutable. An RT function is allowed to access immutable global state (and also mutable local state).
Thus the ability to mutate the values in the cells when the program terminates (as an output from main()), does not make them mutable stored values in the context of the rules. The key distinction is the cell values are not updated after each spreadsheet formula is performed, thus the order of performing the formulas does not matter. The cell values are updated after all the declarative formulas have been performed.
Declarative programming is the picture, where imperative programming is instructions for painting that picture.
You're writing in a declarative style if you're "Telling it what it is", rather than describing the steps the computer should take to get to where you want it.
When you use XML to mark-up data, you're using declarative programming because you're saying "This is a person, that is a birthday, and over there is a street address".
Some examples of where declarative and imperative programming get combined for greater effect:
Windows Presentation Foundation uses declarative XML syntax to describe what a user interface looks like, and what the relationships (bindings) are between controls and underlying data structures.
Structured configuration files use declarative syntax (as simple as "key=value" pairs) to identify what a string or value of data means.
HTML marks up text with tags that describe what role each piece of text has in relation to the whole document.
Declarative Programming is programming with declarations, i.e. declarative sentences. Declarative sentences have a number of properties that distinguish them from imperative sentences. In particular, declarations are:
commutative (can be reordered)
associative (can be regrouped)
idempotent (can repeat without change in meaning)
monotonic (declarations don't subtract information)
A relevant point is that these are all structural properties and are orthogonal to subject matter. Declarative is not about "What vs. How". We can declare (represent and constrain) a "how" just as easily as we declare a "what". Declarative is about structure, not content. Declarative programming has a significant impact on how we abstract and refactor our code, and how we modularize it into subprograms, but not so much on the domain model.
Often, we can convert from imperative to declarative by adding context. E.g. from "Turn left. (... wait for it ...) Turn Right." to "Bob will turn left at intersection of Foo and Bar at 11:01. Bob will turn right at the intersection of Bar and Baz at 11:06." Note that in the latter case the sentences are idempotent and commutative, whereas in the former case rearranging or repeating the sentences would severely change the meaning of the program.
Regarding monotonic, declarations can add constraints which subtract possibilities. But constraints still add information (more precisely, constraints are information). If we need time-varying declarations, it is typical to model this with explicit temporal semantics - e.g. from "the ball is flat" to "the ball is flat at time T". If we have two contradictory declarations, we have an inconsistent declarative system, though this might be resolved by introducing soft constraints (priorities, probabilities, etc.) or leveraging a paraconsistent logic.
Describing to a computer what you want, not how to do something.
imagine an excel page. With columns populated with formulas to calculate you tax return.
All the logic is done declared in the cells, the order of the calculation is by determine by formula itself rather than procedurally.
That is sort of what declarative programming is all about. You declare the problem space and the solution rather than the flow of the program.
Prolog is the only declarative language I've use. It requires a different kind of thinking but it's good to learn if just to expose you to something other than the typical procedural programming language.
I have refined my understanding of declarative programming, since Dec 2011 when I provided an answer to this question. Here follows my current understanding.
The long version of my understanding (research) is detailed at this link, which you should read to gain a deep understanding of the summary I will provide below.
Imperative programming is where mutable state is stored and read, thus the ordering and/or duplication of program instructions can alter the behavior (semantics) of the program (and even cause a bug, i.e. unintended behavior).
In the most naive and extreme sense (which I asserted in my prior answer), declarative programming (DP) is avoiding all stored mutable state, thus the ordering and/or duplication of program instructions can NOT alter the behavior (semantics) of the program.
However, such an extreme definition would not be very useful in the real world, since nearly every program involves stored mutable state. The spreadsheet example conforms to this extreme definition of DP, because the entire program code is run to completion with one static copy of the input state, before the new states are stored. Then if any state is changed, this is repeated. But most real world programs can't be limited to such a monolithic model of state changes.
A more useful definition of DP is that the ordering and/or duplication of programming instructions do not alter any opaque semantics. In other words, there are not hidden random changes in semantics occurring-- any changes in program instruction order and/or duplication cause only intended and transparent changes to the program's behavior.
The next step would be to talk about which programming models or paradigms aid in DP, but that is not the question here.
It's a method of programming based around describing what something should do or be instead of describing how it should work.
In other words, you don't write algorithms made of expressions, you just layout how you want things to be. Two good examples are HTML and WPF.
This Wikipedia article is a good overview: http://en.wikipedia.org/wiki/Declarative_programming
Since I wrote my prior answer, I have formulated a new definition of the declarative property which is quoted below. I have also defined imperative programming as the dual property.
This definition is superior to the one I provided in my prior answer, because it is succinct and it is more general. But it may be more difficult to grok, because the implication of the incompleteness theorems applicable to programming and life in general are difficult for humans to wrap their mind around.
The quoted explanation of the definition discusses the role pure functional programming plays in declarative programming.
Declarative vs. Imperative
The declarative property is weird, obtuse, and difficult to capture in a technically precise definition that remains general and not ambiguous, because it is a naive notion that we can declare the meaning (a.k.a semantics) of the program without incurring unintended side effects. There is an inherent tension between expression of meaning and avoidance of unintended effects, and this tension actually derives from the incompleteness theorems of programming and our universe.
It is oversimplification, technically imprecise, and often ambiguous to define declarative as “what to do” and imperative as “how to do”. An ambiguous case is the “what” is the “how” in a program that outputs a program— a compiler.
Evidently the unbounded recursion that makes a language Turing complete, is also analogously in the semantics— not only in the syntactical structure of evaluation (a.k.a. operational semantics). This is logically an example analogous to Gödel's theorem— “any complete system of axioms is also inconsistent”. Ponder the contradictory weirdness of that quote! It is also an example that demonstrates how the expression of semantics does not have a provable bound, thus we can't prove2 that a program (and analogously its semantics) halt a.k.a. the Halting theorem.
The incompleteness theorems derive from the fundamental nature of our universe, which as stated in the Second Law of Thermodynamics is “the entropy (a.k.a. the # of independent possibilities) is trending to maximum forever”. The coding and design of a program is never finished— it's alive!— because it attempts to address a real world need, and the semantics of the real world are always changing and trending to more possibilities. Humans never stop discovering new things (including errors in programs ;-).
To precisely and technically capture this aforementioned desired notion within this weird universe that has no edge (ponder that! there is no “outside” of our universe), requires a terse but deceptively-not-simple definition which will sound incorrect until it is explained deeply.
Definition:
The declarative property is where there can exist only one possible set of statements that can express each specific modular semantic.
The imperative property3 is the dual, where semantics are inconsistent under composition and/or can be expressed with variations of sets of statements.
This definition of declarative is distinctively local in semantic scope, meaning that it requires that a modular semantic maintain its consistent meaning regardless where and how it's instantiated and employed in global scope. Thus each declarative modular semantic should be intrinsically orthogonal to all possible others— and not an impossible (due to incompleteness theorems) global algorithm or model for witnessing consistency, which is also the point of “More Is Not Always Better” by Robert Harper, Professor of Computer Science at Carnegie Mellon University, one of the designers of Standard ML.
Examples of these modular declarative semantics include category theory functors e.g. the Applicative, nominal typing, namespaces, named fields, and w.r.t. to operational level of semantics then pure functional programming.
Thus well designed declarative languages can more clearly express meaning, albeit with some loss of generality in what can be expressed, yet a gain in what can be expressed with intrinsic consistency.
An example of the aforementioned definition is the set of formulas in the cells of a spreadsheet program— which are not expected to give the same meaning when moved to different column and row cells, i.e. cell identifiers changed. The cell identifiers are part of and not superfluous to the intended meaning. So each spreadsheet result is unique w.r.t. to the cell identifiers in a set of formulas. The consistent modular semantic in this case is use of cell identifiers as the input and output of pure functions for cells formulas (see below).
Hyper Text Markup Language a.k.a. HTML— the language for static web pages— is an example of a highly (but not perfectly3) declarative language that (at least before HTML 5) had no capability to express dynamic behavior. HTML is perhaps the easiest language to learn. For dynamic behavior, an imperative scripting language such as JavaScript was usually combined with HTML. HTML without JavaScript fits the declarative definition because each nominal type (i.e. the tags) maintains its consistent meaning under composition within the rules of the syntax.
A competing definition for declarative is the commutative and idempotent properties of the semantic statements, i.e. that statements can be reordered and duplicated without changing the meaning. For example, statements assigning values to named fields can be reordered and duplicated without changed the meaning of the program, if those names are modular w.r.t. to any implied order. Names sometimes imply an order, e.g. cell identifiers include their column and row position— moving a total on spreadsheet changes its meaning. Otherwise, these properties implicitly require global consistency of semantics. It is generally impossible to design the semantics of statements so they remain consistent if randomly ordered or duplicated, because order and duplication are intrinsic to semantics. For example, the statements “Foo exists” (or construction) and “Foo does not exist” (and destruction). If one considers random inconsistency endemical of the intended semantics, then one accepts this definition as general enough for the declarative property. In essence this definition is vacuous as a generalized definition because it attempts to make consistency orthogonal to semantics, i.e. to defy the fact that the universe of semantics is dynamically unbounded and can't be captured in a global coherence paradigm.
Requiring the commutative and idempotent properties for the (structural evaluation order of the) lower-level operational semantics converts operational semantics to a declarative localized modular semantic, e.g. pure functional programming (including recursion instead of imperative loops). Then the operational order of the implementation details do not impact (i.e. spread globally into) the consistency of the higher-level semantics. For example, the order of evaluation of (and theoretically also the duplication of) the spreadsheet formulas doesn't matter because the outputs are not copied to the inputs until after all outputs have been computed, i.e. analogous to pure functions.
C, Java, C++, C#, PHP, and JavaScript aren't particularly declarative.
Copute's syntax and Python's syntax are more declaratively coupled to
intended results, i.e. consistent syntactical semantics that eliminate the extraneous so one can readily
comprehend code after they've forgotten it. Copute and Haskell enforce
determinism of the operational semantics and encourage “don't repeat
yourself” (DRY), because they only allow the pure functional paradigm.
2 Even where we can prove the semantics of a program, e.g. with the language Coq, this is limited to the semantics that are expressed in the typing, and typing can never capture all of the semantics of a program— not even for languages that are not Turing complete, e.g. with HTML+CSS it is possible to express inconsistent combinations which thus have undefined semantics.
3 Many explanations incorrectly claim that only imperative programming has syntactically ordered statements. I clarified this confusion between imperative and functional programming. For example, the order of HTML statements does not reduce the consistency of their meaning.
Edit: I posted the following comment to Robert Harper's blog:
in functional programming ... the range of variation of a variable is a type
Depending on how one distinguishes functional from imperative
programming, your ‘assignable’ in an imperative program also may have
a type placing a bound on its variability.
The only non-muddled definition I currently appreciate for functional
programming is a) functions as first-class objects and types, b)
preference for recursion over loops, and/or c) pure functions— i.e.
those functions which do not impact the desired semantics of the
program when memoized (thus perfectly pure functional
programming doesn't exist in a general purpose denotational semantics
due to impacts of operational semantics, e.g. memory
allocation).
The idempotent property of a pure function means the function call on
its variables can be substituted by its value, which is not generally
the case for the arguments of an imperative procedure. Pure functions
seem to be declarative w.r.t. to the uncomposed state transitions
between the input and result types.
But the composition of pure functions does not maintain any such
consistency, because it is possible to model a side-effect (global
state) imperative process in a pure functional programming language,
e.g. Haskell's IOMonad and moreover it is entirely impossible to
prevent doing such in any Turing complete pure functional programming
language.
As I wrote in 2012 which seems to the similar consensus of
comments in your recent blog, that declarative programming is an
attempt to capture the notion that the intended semantics are never
opaque. Examples of opaque semantics are dependence on order,
dependence on erasure of higher-level semantics at the operational
semantics layer (e.g. casts are not conversions and reified generics
limit higher-level semantics), and dependence on variable values
which can not be checked (proved correct) by the programming language.
Thus I have concluded that only non-Turing complete languages can be
declarative.
Thus one unambiguous and distinct attribute of a declarative language
could be that its output can be proven to obey some enumerable set of
generative rules. For example, for any specific HTML program (ignoring
differences in the ways interpreters diverge) that is not scripted
(i.e. is not Turing complete) then its output variability can be
enumerable. Or more succinctly an HTML program is a pure function of
its variability. Ditto a spreadsheet program is a pure function of its
input variables.
So it seems to me that declarative languages are the antithesis of
unbounded recursion, i.e. per Gödel's second incompleteness
theorem self-referential theorems can't be proven.
Lesie Lamport wrote a fairytale about how Euclid might have
worked around Gödel's incompleteness theorems applied to math proofs
in the programming language context by to congruence between types and
logic (Curry-Howard correspondence, etc).
Declarative programming is "the act of programming in languages that conform to the mental model of the developer rather than the operational model of the machine".
The difference between declarative and imperative programming is well
illustrated by the problem of parsing structured data.
An imperative program would use mutually recursive functions to consume input
and generate data. A declarative program would express a grammar that defines
the structure of the data so that it can then be parsed.
The difference between these two approaches is that the declarative program
creates a new language that is more closely mapped to the mental model of the
problem than is its host language.
It may sound odd, but I'd add Excel (or any spreadsheet really) to the list of declarative systems. A good example of this is given here.
I'd explain it as DP is a way to express
A goal expression, the conditions for - what we are searching for. Is there one, maybe or many?
Some known facts
Rules that extend the know facts
...and where there is a deduct engine usually working with a unification algorithm to find the goals.
As far as I can tell, it started being used to describe programming systems like Prolog, because prolog is (supposedly) about declaring things in an abstract way.
It increasingly means very little, as it has the definition given by the users above. It should be clear that there is a gulf between the declarative programming of Haskell, as against the declarative programming of HTML.
A couple other examples of declarative programming:
ASP.Net markup for databinding. It just says "fill this grid with this source", for example, and leaves it to the system for how that happens.
Linq expressions
Declarative programming is nice because it can help simplify your mental model* of code, and because it might eventually be more scalable.
For example, let's say you have a function that does something to each element in an array or list. Traditional code would look like this:
foreach (object item in MyList)
{
DoSomething(item);
}
No big deal there. But what if you use the more-declarative syntax and instead define DoSomething() as an Action? Then you can say it this way:
MyList.ForEach(DoSometing);
This is, of course, more concise. But I'm sure you have more concerns than just saving two lines of code here and there. Performance, for example. The old way, processing had to be done in sequence. What if the .ForEach() method had a way for you to signal that it could handle the processing in parallel, automatically? Now all of a sudden you've made your code multi-threaded in a very safe way and only changed one line of code. And, in fact, there's a an extension for .Net that lets you do just that.
If you follow that link, it takes you to a blog post by a friend of mine. The whole post is a little long, but you can scroll down to the heading titled "The Problem" _and pick it up there no problem.*
It depends on how you submit the answer to the text. Overall you can look at the programme at a certain view but it depends what angle you look at the problem. I will get you started with the programme:
Dim Bus, Car, Time, Height As Integr
Again it depends on what the problem is an overall. You might have to shorten it due to the programme. Hope this helps and need the feedback if it does not.
Thank You.

Resources