``How much land does a man need?'' asked Lev Tolstoi, and the answer turned out to be: surprisingly little. ``How many programming languages does a software designer need?'' The answer seems to be: surprisingly many. See below.
Of course, well-designed languages are a key to good software design, but while many well designed languages are available (see below), the problem of ill-designed software persists. Why is this so?
A refreshing concept for software design is being puth forth at Praxis High Integrity Systems (IEEE Spectrum Software Report ``The Exterminators'', September 2005), but it is nothing new. Years ago, that was the way software was developed. Programmers actually designed their programs - remember flowcharts ? - and wrote ``pseudocode'' before ever beginning to write code. Why has that changed?For the last 20 years, the goal has been to make programming easier and easier by supplying ever more powerful tools - compilers, Visio, programming packages, workbenches, and so on - and by creating higher-level and more abstract languages. Theoretically, these tools should have made the output better, and, used correctly, they would have. Instead, the innovations made programming and coding so easy that literally anyone can write code. Not well-structured code or bug-free code - just code.
Joseph DeCarolis in a letter to IEEE Spectrum, January 2006.
Recall the old joke of the computer programmer who died in the shower? He was just following the instructions on the shampoo bottle: ``Lather, rinse, repeat.'' Following a sequence of instructions to the letter is the essence of imperative programming.
The definition on the shampoo bottle of the functional programmer runs like this:
wash = lather : rinse : washThis is effectively a definition by co-recursion (like definition by recursion, but without a base case) of an infinite stream.
The key feature in specifying abstract data types is to present a precise description of that data type without referring to any concrete representation of the objects of that datatype and without referring to any implementation details on the operations on the datatype.
This abstract point of view is provided by many-sorted algebras. Many sorted algebras are specifications of abstract datatypes.
First order predicate logic can be turned into a computation engine by adding SDL resolution, unification and fixpoint computation. The result is datalog.
To extend this into a full fledged programming paradigm, backtracking and cut (an operator for pruning search trees) were added. The result is Prolog.
SWI-Prolog offers a comprehensive Free Software Prolog environment, licensed under the Lesser GNU Public License. Together with its graphics toolkit XPCE, its development started in 1987 and has been driven by the needs for real-world applications. These days SWI-Prolog is widely used in research and education as well as for commercial applications.
Gödel is a declarative, general-purpose programming language in the family of logic programming languages. It is a strongly typed language, the type system being based on many-sorted logic with parametric polymorphism. It has a module system. Gödel supports infinite precision integers, infinite precision rationals, and also floating-point numbers. It can solve constraints over finite domains of integers and also linear rational constraints. It supports processing of finite sets. It also has a flexible computation rule and a pruning operator which generalises the commit of the concurrent logic programming languages. Considerable emphasis is placed on Gödel's meta- logical facilities which provide significant support for meta-programs that do analysis, transformation, compilation, verification, debugging, and so on.
Inductive Logic Programming (ILP) is a research area formed at the intersection of Machine Learning and Logic Programming. ILP systems develop predicate descriptions from examples and background knowledge. The examples, background knowledge and final descriptions are all described as logic programs. A unifying theory of Inductive Logic Programming is being built up around lattice-based concepts such as refinement, least general generalisation, inverse resolution and most specific corrections. In addition to a well established tradition of learning-in-the-limit results, some results within Valiant's PAC-learning framework have been demonstrated for ILP systems. U-learnabilty, a new model of learnability, has also been developed.
The birth of CLP is a milestone in the history of programming languages. CLP combines two declarative programming paradigms: logic programming and constraint solving. The declarative nature has proven appealing in numerous applications including computer-aided design and verification, database, data mining, software engineering, optimization, configuration, graphical user interface, and language processing. It greatly enhances the productivity of software development and software maintainability. In addition, because of the availability of efficient constraint-solving, memory management, and compilation techniques, CLP programs can be more efficient than their counterparts written in procedural languages.
B-Prolog is a Prolog system with extensions for programming concurrency, constraints, and interactive graphics. The system is based on a significantly refined WAM, called ATOAM, that facilitates software emulation. In addition to an ATOAM emulator with a garbage collector written in C, the system consists of a compiler and an interpreter written in Prolog, and a rich library of built-in predicates written in C and Prolog. B-Prolog follows the standard of Prolog but also enjoys several features that are not available in traditional Prolog systems.
Excellent source of information on logic programming: http://vl.fmnet.info/logic-prog/
Pure lambda calculus was developed in the 1930s and 40s by logician Alonzo Church, as a foundational project intended to put mathematics on a firm basis of `effective procedures'. In the system of pure lambda calculus, everything is a function, functions can be applied to other functions to obtain values by a process of application, and new functions can be constructed from existing functions by a process of lambda abstraction. Unfortunately, the system of pure lambda calculus admits the formulation of Russell's paradox.
Representing sets by their characteristic functions (essentially procedures for separating the members from a set from the non-members), we can define
\ x . not (x x)Now apply r to itself:
r r = (\ x . not (x x)) (\ x . not (x x))
= not ((\ x . not (x x))(\ x . not (x x)))
= not (r r)
So if (r r) is true then it is false and vice versa.
This means that pure lambda calculus is not a suitable foundation
for mathematics. However, as Church and Turing realized, it is
a suitable foundation for computation.
Lisp uses a variant of lambda notation for defining functions. Only its purely functional subset is really equivalent to lambda-calculus.
Scheme is a statically scoped and properly tail-recursive dialect of the Lisp programming language invented by Guy Lewis Steele Jr. and Gerald Jay Sussman. It was designed to have an exceptionally clear and simple semantics and few different ways to form expressions. A wide variety of programming paradigms, including imperative, functional, and message passing styles, find convenient expression in Scheme.
ML is often referred to as an impure functional language, because it permits side-effects, and therefore imperative programming, unlike purely functional programming languages such as Haskell.
Features of ML include call-by-value evaluation strategy, first class functions, automatic memory management through garbage collection, parametric polymorphism, static typing, type inference, algebraic data types, pattern matching, and exception handling.
Unlike Haskell, ML uses eager evaluation, which means that all subexpressions are always evaluated. One result of this is that you cannot use infinite lists per se. However, lazy evaluation and hence infinite lists can be simulated, through use of anonymous functions.
Today there are several languages in the ML family; the two major dialects are Standard ML and Caml, but others exist, including F# - an open research project that targets the Microsoft .NET platform. Ideas from ML have influenced numerous other languages, such as Haskell, Cyclone, and Nemerle.
ML's strengths are mostly applied in language design and manipulation (compilers, analyzers, theorem provers), but it is a general-purpose language also used in bioinformatics, financial systems, and applications including a genealogical database, a peer-to-peer client/server program, etc.
In the mid-1980s, there was no ßtandard" non-strict, purely-functional programming language. A language-design committee was set up in 1987, and the Haskell language is the result.
A Functional Programming Language like Clean is based on the concept of mathematical functions. Clean is a pure functional language, there is not such a thing as an assignment. This has a big advantage: a function cannot have a side-effect. A Clean function is referential transparent: the result of a function only depends on the value of the function arguments and on nothing else.
This has important consequences:
For making real world applications one needs of course to be able to update a database, perform I/O, update an array destructively, pass a message to another program. And, the application should run efficiently enough. Although Clean does not have assignments, objects can be updated destructively. Clean is the only functional language in the world which has a special type system, uniqueness typing. This type system is developed in Nijmegen. It enables to update function arguments destructively retaining the purity of the language.
Frequently asked questions about functional programming: http://www.cs.nott.ac.uk/~gmh/faq.html.
Many proposals have been made for the integration of functional programming and logic programming:
ALF is a language which combines functional and logic programming techniques. The foundation of ALF is Horn clause logic with equality which consists of predicates and Horn clauses for logic programming, and functions and equations for functional programming. Since ALF is a genuine integration of both programming paradigms, any functional expression can be used in a goal literal and arbitrary predicates can occur in conditions of equations. The operational semantics of ALF is based on the resolution rule to solve literals and narrowing to evaluate functional expressions. In order to reduce the number of possible narrowing steps, a leftmost-innermost basic narrowing strategy is used which can be efficiently implemented. Furthermore, terms are simplified by rewriting before a narrowing step is applied and also equations are rejected if the two sides have different constructors at the top. Rewriting and rejection can result in a large reduction of the search tree. Therefore this operational semantics is more efficient than Prolog's resolution strategy.
Die Sprache BABEL ist eine funktional-logische Sprache, die 1988 von Mario Rodriguez-Artalejo (Universidad Complutense de Madrid) und Juan Jose Moreno-Navarro (Universidad Politecnica de Madrid) entwickelt wurde. In BABEL wird eine uniforme Integration des funktionalen und des logischen Programmierstils erreicht. Die Kernidee besteht darin, den Auswertungsmechanismus funktionaler Sprachen zu verallgemeinern, indem zur Parameterübergabe die aus den Logik-Sprachen bekannte Unifikation verwendet wird.
Curry is a universal programming language aiming to amalgamate the most important declarative programming paradigms, namely functional programming and logic programming. Moreover, it also covers the most important operational principles developed in the area of integrated functional logic languages: "residuation" and "narrowing".
Mercury is a new logic/functional programming language, which combines the clarity and expressiveness of declarative programming with advanced static analysis and error detection features. Its highly optimized execution algorithm delivers efficiency far in excess of existing logic programming systems, and close to conventional programming systems. Mercury addresses the problems of large-scale program development, allowing modularity, separate compilation, and numerous optimization/time trade-offs.
Mozart is based on the Oz language, which supports declarative programming, object-oriented programming, constraint programming, and concurrency as part of a coherent whole. For distribution, Mozart provides a true network transparent implementation with support for network awareness, openness, and fault tolerance. Security is upcoming. Mozart is an ideal platform for both general-purpose distributed applications as well as for hard problems requiring sophisticated optimization and inferencing abilities. We have developed many applications including sophisticated collaborative tools, multi-agent systems, and digital assistants, as well as applications in natural language understanding and knowledge representation, in scheduling and time-tabling, and in placement and configuration.
NUE-Prolog is implemented as a preprocessor for NU-Prolog. The source language is NU-Prolog augmented with evaluable function definitions. The output is standard NU-Prolog including some goals to add information for the runtime system.
RELFUN is a logic-programming language with call-by-value (eager) expressions of non-deterministic, non-ground functions. Clauses are `hornish', succeeding with true(s), or `footed', returning any value(s). They define operations (relations and functions) permitting (apply-reducible) higher-order syntax with arbitrary terms (constants, structures, and variables) as operators. The language explicitly distinguishes structures [passive] and expressions (active). All structures and expressions, not only lists or tuples, can have varying arities. RELFUN generalizes PROLOG's is-primitive to .=, unifying a structure with the value(s) of an arbitrary expression; expressions may become flattened via further .=-calls. Finite domains and exclusions as well as sorts are first-class citizens built into the unification. Extensions include single-cut clauses and relational-functional primitives such as a value-returning tupof.
TOY is a constraint functional logic system, designed to support the main declarative programming styles and their combination. It has been designed and developed mainly by the Declarative Programming Group at the Universidad Complutense de Madrid and in collaboration and inputs from the Universidad de Málaga, following previous experiences with the design of declarative languages.
Programming languages are just tools. Multi-paradigm languages are the equivalent of multi-purpose tools like Swiss army knifes: