Are there purely declarative, general purpose programming languages? - functional-programming

I've been researching declarative languages, and it seems like declarative is just an umbrella term for both logic and functional languages. Or am I wrong? Are there any general-purpose declarative programming languages that can't be classified as either functional or logic(al), and simply "declarative"?

A declarative language requires you to code for what you want to happen rather than in an imperative language where you code how the computation should be done.
In general this means that a declarative language does not allow for side-effects, whereas imperative languages almost require coding with side-effects.
In order for general-purpose languages to be, well, general-purpose they require the ability to code side-effects. It thus make them hard to be declarative.
Languages like F# have a strong basis in functional programming, but have any constructs to allow for OO programming and side-effects. This makes F# a general purpose language but does so by allowing imperative style coding to be mixed in with declarative coding.
Although not entirely impossible, I would suspect that there are no "purely declarative" general purpose programming languages just simply by definition.

Related

Is it true that functional languages are intrinsically hard to make interface with non functional languages

I was told this to be the case by someone but never quite understood why and didn't believe it. Doing a check of https://en.wikipedia.org/wiki/Foreign_function_interface it seems to be the case. Is this true? And if so why?
No. A functional programming language is simply one which encourages the treatment of functions as values in their own right. This is orthogonal to whether it integrates well with other languages. Indeed, Clojure, Scala, and F# are designed to interoperate with Java, Java (again), and C# respectively.
It might take some work to adapt the API to the idioms of the target language. But this issue isn't unique to functional languages—most C interfaces won't look great as-is in Python either! And this work is optional: the Haskell network package is but a thin wrapper around Berkeley sockets, yet people are more than happy to use it.
I think 100% pure functional language can by its definition not interface at all with the outside world
That's a common misconception.
A pure functional language does not ban side effects; it annotates them—whether it be through an IO monad (Haskell), linear types (Mercury), or algebraic effects (Idris). In such a language, calling a foreign function would feel no different to any other I/O operation.
Moreover, if the programmer knows that the foreign function is pure (e.g. an LAPACK routine) then they can overrule the compiler and declare it as such. In Haskell, this can be done by omitting IO from the function's signature.

SOLID for functional programming

Coming from an OOP language, I am familiar with the SOLID principles of object oriented design. It seems like some of these would fit into a functional programming model, while other parts make no sense in a world lacking state. Is there a similar set of principles for refactoring functional code?
As far as I know (I'm no expert), SOLID principles do not tell anything about state. They should be applicable as well in a functional programming languages. They're more advice about how to achieve modularity.
Some of them are rather obvious or at least well-known. Single-responsibility is the UNIX principle "do one thing and do it well", which is even more popular in functional languages where "composition" is widely used, similarly. The Interface Segregation Principle is very natural as well (have your interfaces modular and keep orthogonal concepts separated). Finally, Dependency Inversion is just a name for "abstraction" and is omnipresent in functional programming.
The "OL" principles, Open/Closed and LSP, are more oriented towards languages based upon inheritance as a core software engineering concept. Functional languages values/modules do not have open recursion by default, so "implementation inheritance" is only used in very specific cases. Composition is preferred. I'm not sure how you should interpret the Open/Closed principle in that setting. You may consider it is about encapsulation, which functional programs also use a lot, using abstract types and such.
Finally, the Liskov Substitution Principle may seem to be about inheritance. Functional languages do not always use subtyping, but when they do it is indeed assumed that "derived types" should preserve the specification of "base types". Functional programmers are of course careful to specify and respect the interface and properties of their programs, modules etc., and may use algebraic reasoning (this is equivalent to this so I can substitute...) based on those specifications when programming, refactoring, etc. However, once you get rid of the "inheritance by default" idea, you have much less problems of interface violations, so LSP is not emphasized as a vital safeguard as it is in OOP.
This video presents the SOLID principles, and how to apply them in Clojure.
It shows how these principles hold in the Functional world as much as in OOP, because we still need to solve the same underlying problems. And overall, it made me think Functional Programming is better suited for SOLID design.
Actually, SOLID Could be a good idea to have a better principle for Functional Programming:
SRP: Only do one thing was taken from imperative programming in the first place. Having small, focused functions is good.
OCP: Allowing you to change behaviors without modifying code is good. Functional Programming uses higher-order functions more than inheritance, but the principle holds.
LSP: Abiding by some interface contract is just as good in functional programming as in object-oriented. If a sort function takes a comparator, then you would expect the '0 is equals, less than provides negative results, greater than positive results' behavior.
ISP: Most functional languages still have structs. Specifying the smallest set of data required by a function is still good practice. Requiring the least specific interface to the data (why use Lists of ints when Enumerations of T work just as well?) is still good practice.
DIP: Specifying parameters to a function (or a higher-order function to retrieve them) rather than hard coding the function to go get some value is just as good in functional programming as in object-oriented.
And even when doing object-oriented programming, many of these principles apply to the design of methods in the objects too.
"Richard Warburton, a member of the London JCP Committee, in his presentation describes the SOLID principles as one example of well-established object oriented programming design principles, identified by Robert C. Martin in the early 2000s, and looks at each of the five principles trying to find a functional equivalent or at least something related on the function side.
Richards experience is that although many developers don’t know how to use their existing design skills in functional design, functional programming can often help in implementing the SOLID principles and also that a functional mindset can actually help in achieving one important aspect of object-orientation, encapsulation."
Further information:
Object Oriented Design Principles and Functional Programming - https://www.infoq.com/news/2014/03/oo-functional-programming/
Equivalent of SOLID principles for functional programming -
https://softwareengineering.stackexchange.com/questions/165356/equivalent-of-solid-principles-for-functional-programming

Is Erlang really a functional language? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I hear all the time that Erlang is a functional language, yet it is easy to call databases or non side-effect free code from a function, and commands are easily ordered by using "," commas between them just like Ruby or another language, so where is the "functional" part of Erlang?
The central idea is that each process is a functional program over an input stream of messages. The result from the functional program is an output stream of messages to others. From this perspective, Erlang is a rather clean functional language; there are no destructive updates to data structures (like setcar in Lisp and most Schemes).
With few exceptions, all built-in functions such as operations on ETS tables also follow this model: apart from efficiency issues, those BIFs could actually have been implemented with pure Erlang processes and message passing.
So yes, the Erlang language is functional, but a collection of interacting Erlang processes is a different thing. Each process is an ongoing computation, and as such it has a current state, which can change in relation to the other processes. Even a database is just another process in this respect.
In my mind, this is one of the most important things about Erlang: outside the process, there could be a storm raging, but inside, things are calm, letting you focus on what that process should do - and only that.
There's a meme that functional languages must have immutable values and be side-effect free, but I say that any language with first-class functions is a functional programming language.
It is useful and powerful to have strong controls over value mutability and side effects, but I believe these are peripheral to functional programming. Nice to have, but not essential. Even in languages that do have these properties, there is always a way to escape the purity of the paradigm.1
There is a grayscale continuum between truly pure FP languages that you can't actually use for anything practical and languages that are really quite impure but still have some of the FP nature to them:
Book FP: Introductory books on FP languages frequently show only a subset of the language, with all examples done within the language's REPL, so that you never get to see the purely functional paradigm get broken. A good example of this is Scheme as presented in The Little Schemer.
You can come away from reading such a book with the false impression that FP languages can't actually do anything useful.
Haskell: The creators of Haskell went to uncommon lengths to wall off impurity via the famous I/O monad. Everything on one side of the wall is purely functional, so that the compiler can reason confidently about the code.
But the important thing is, despite the existence of this wall, you have to use the I/O monad to get anything useful done in Haskell.2 In that sense, Haskell isn't as "pure" as some would like you to believe. The I/O monad allows you to build any sort of "impure" software you like in Haskell: database clients, highly stateful GUIs, etc.
Erlang: Has immutable values and first-class functions, but lacks a strong wall between the core language and the impure bits.
Erlang ships with Mnesia, a disk-backed in-memory DBMS, which is about as impure as software gets. It's scarcely different in practice from a global variable store. Erlang also has great support for communicating with external programs via ports, sockets, etc.
Erlang doesn't impose any kind of purity policy on you, the programmer, at the language level. It just gives you the tools and lets you decide how to use them.
OCaml and F#: These closely-related multiparadigm languages include both purely functional elements as well as imperative and object-oriented characteristics.
The imperative programming bits allow you to do things like write a traditional for loop with a mutable counter variable, whereas a pure FP program would probably try to recurse over a list instead to accomplish the same result.
The OO parts are pretty much useless without the mutable keyword, which turns a value definition into a variable, so that the compiler won't complain if you change the variable's value. Mutable variables in OCaml and F# have some limitations, but you can escape even those limitations with the ref keyword.
If you're using F# with .NET, you're going to be mutating values all the time, because most of .NET is mutable, in one way or another. Any .NET object with a settable property is mutable, for example, and all the GUI stuff inherently has side-effects. The only immutable part of .NET that immediately comes to mind is System.String.
Despite all this, no one would argue that OCaml and F# are not functional programming languages.
JavaScript, R, Lua, Perl...: There are many languages even less pure than OCaml which can still be considered functional in some sense. Such languages have first-class functions, but values are mutable by default.
Foototes:
Any truly pure FP language is a toy language or someone's research project.
That is, unless your idea of "useful" is to keep everything in the ghci REPL. You can use Haskell like a glorified calculator, if you like, so it's pure FP.
Yes, it's a functional language. It's not a pure functional language like Haskell, but then again, neither is LISP (and nobody really argues that LISP isn't functional).
The message-passing/process handling of Erlang is an implementation of the Actor model. You could argue that Erlang is an Actor language, with a functional language used for the individual Actors.
The functional part is that you tend to pass around functions. Most langauges can be used both as a functional language, and as an imperative language, even C (it's quite possible to make a program consisting of only function pointers and constants).
I guess the distinguishing factor is usually the lack of mutable variables in functional languages.

"Functional programming" has a clear meaning, but does "functional language"?

I understand very clearly the difference between functional and imperative programming techniques. But there's a widespread tendency to talk of "functional languages", and this really confuses me.
Of course some languages like Haskell are more hospitable to functional programming than other languages like C. But even the former does I/O (it just keeps it in a ghetto). And you can write functional programs in C (it's just absurdly harder). So maybe it's just a matter of degree.
Still, even as a matter of degree, what does it mean when someone calls Scheme a "functional language"? Most Scheme code I see is imperative. Is it just that Scheme makes it easy to write in a functional style if you want to? So too do Lua and Python. Are they "functional languages" too?
I'm (really) not trying to be a language cop. If this is just a loose way of talking, that's fine. I'm just trying to figure out whether it does have some definite meaning (even if it's a matter-of-degree meaning) that I'm not seeing.
Among people who study programming languages for a living, "functional programming language" is a pretty weakly bound term. There is a strong consensus that:
Any language that calls itself functional must support first-class, nested functions with lexical scoping rules.
A significant minority also reserve the term "functional language" for languages which are:
Pure (or side-effect-free, referentially transparent, see also)
as in languages like Agda, Clean, Coq, and Haskell.
Beyond that, what's considered a functional programming language is often a matter of intent, that is, whether is designers want it to be called "functional".
Perl and Smalltalk are examples of languages that support first-class functions but whose designers don't call them functional. Objective Caml is an example of a language that is called functional even though it has a full object system with inheritance and everything.
Languages that are called "functional" will tend to have features like the following (taken from Defining point of functional programming):
Anonymous functions (lambda expressions)
Recursion (more prominent as a result of purity)
Programming with expressions rather than statements (again, from purity)
Closures
Currying / partial application
Lazy evaluation
Algebraic data types and pattern matching
Parametric polymorphism (a.k.a. generics)
The more a particular programming language has syntax and constructs tailored to making the various programming features listed above easy/painless to express & implement, the more likely someone will label it a "functional language".
I would say that a functional language is any language that allows functional programming without undue pain.
I like #Randolpho's answer. With regards to features, I might cite the list here:
Defining point of functional programming
namely
Purity (a.k.a. immutability, eschewing side-effects, referential transparency)
Higher-order functions (e.g. pass a function as a parameter, return it as a result, define anonymous function on the fly as a lambda expression)
Laziness (a.k.a. non-strict evaluation, most useful/usable when coupled with purity)
Algebraic data types and pattern matching
Closures
Currying / partial application
Parametric polymorphism (a.k.a. generics)
Recursion (more prominent as a result of purity)
Programming with expressions rather than statements (again, from purity)
The more a particular programming language has syntax and constructs tailored to making the various FP features listed above easy/painless to express & implement, the more likely someone will label it a "functional language".
Jane Street's Brian Hurt wrote a very good article on this a while back. The basic definition he arrived at is that a functional programming language is a language that models the lambda calculus. Think about what languages are widely agreed to be functional and you'll see that this is a very practical definition.
Lisp was a primitive attempt to model the lambda calculus, so it fits this definition — though since most implementations don't stick very closely to the ideas of lambda calculus, they're generally considered to be mixed-paradigm or at best weakly functional.
This is also why a lot of people bristle at languages like Python being called functional. Python's general philosophy is unrelated to lambda calculus — it doesn't encourage this way of thinking at all — so it's not a functional language. It's a Turing machine with first-class functions. You can do functional-style programming in Python, yes, but the language does not have its roots in the same math that functional languages do. (Incidentally, Guido van Rossum himself agrees with this description of the language.)
A language (and platform) that promotes Functional Programming as a means of fully leveraging the capabilities of the said platform.
A language that makes it a lot harder to create functions with side effects than without side effects. The same counts for mutable/immutable data structures.
I think the same question can be asked about "OOP languages". After all, you can write object oriented programs in C (and it's not uncommon to do so). But C doesn't have any built-in language constructs to enable OOP. You have to do OOP "by hand" without much help from the compiler. That's why it's usually not considered an OOP language. I think this distinction can be applied to "functional languages", too: For example, it's not uncommon to write functional code in C++ (think about STL functions like std::count_if or std::transform). But C++ (for now) lacks built-in language features that enable functional programming, like lambdas. (Let's ignore boost::lambda for the sake of the argument.)
So, to answer your question, I'd say although it's possible to write function programs in each of these languages:
C is not a functional language (no built-in functional language constructs)
Scheme, Python and friends have functional constructs, so they're functional languages. But they also have imperative and OOP constructs, so they're usually referred to as "multi-paradigm" languages.
You can do functional style programming in any language. I try as much as possible.
Python, Linq all promote functional style programming.
A pure functional language like Haskell requires you to do all your computations using mathematical functions, functions that do not modify anything, they just return values.
In addition, functional languages typically allow you to write higher order functions, functions that take functions as arguments and/or return types.
Haskell for one have different types for functions with side-effects and those without.
That's a pretty good discriminating property for being a 100% functional language, at least IMHO.
I wrote a (pretty long) analysis once on why the term 'functional programming language' is meaningless which also tries to explain why for instance 'functions' in Haskell are completely different from 'functions' in Lisp or Python: http://blog.nihilarchitect.net/archives/289/on-functional-programming/
Things like 'map' or 'filter' are for a large part also implementable in C for instance.

Clojure: Doesn't the ability to use Java objects with state defy the whole idea of functional P?

I thought the whole idea was to have only computation with NO state and NO side effects. Now if a Clojure app(or even worse, a reusable Clojure library ) can use and create any Java object, how can I be sure I don't get side effects or state ?
FP is a paradigm, a concept, but not necessarily a dogma. Clojure trusts the programmer to make thoughtful decisions about where he'll depart from FP. In exchange, Clojure offers the staggering cornucopia of code that is available in the form of Java libraries. This makes it relatively easy and painless to write a GUI app in Clojure, say, or a Web server or any of the things covered by Java library code.
Note that the Java "hole" is not the only escape hatch Clojure offers from FP: References and atoms hold state and Clojure offers functions to change it under controlled conditions. I think this pragmatic approach makes Clojure useful and will help make it popular.
You cannot be sure, apart from consulting documentation or using a java decompiler(?). This ability certainly defies the idea of pure functional programming, but the real world is not a particularly pure place and purely functional languages can't get much traction against it. Witness all the contortionism with monads in Haskell. Besides, mutable state is very powerful computationally — many algorithms become much faster and much more economical of memory when implemented with mutable state.
Clojure is not a pure functional programming language. What you said would stand in Haskell, but not in Clojure. Clojure encourages functional programming, but it doesn't force it. Clojure is built to help you program in a functional style, but also to allow you to actually get stuff done. Clojure makes sure that when you use state, you have to be explicit about it. If you want to be sure that you're programming purely functional, you have to make sure yourself. Clojure isn't pure, so it doesn't promise purity.
Because Clojure is meant for the real world it makes compromises, and therefore it isn't a pure functional language.
Haskell was made as a proof that it was even possible to make a pure functional programming language that could work in the real world, so if pureness is what you desire, your journey should take you there.
Referential transparency (which is a consequence of the lack of side effect) isn't the only motivation for functional programming. The concept of lazy evaluation is thought to be one of the central features of the functional style since it allows you to modularly construct programs.
In other words functional programming is at least as much about generic programming as it is about providing static safety guarantees. I'm pretty sure you already knew this, but I thought it might be appropriate to articulate the idea.
Allowing side effects is a bit of a trade-off which you need to justify for yourself. Many applications do need to deal with quite a lot of stateful computation, some languages are just more strict about dealing with this than others.
Functional programming has been around for years and years in varying degrees of "purity" sort of waiting for a killer app. Clojure explicitly embraces a specific application of functional programming, that is it focuses on single address space parallel programming and it's FP paradigm really shines in this area. Much of the java world is single threaded and hence does not need this tool.
So yes you are absolutely correct Clojure breaks the functional paradigm when it calls to java, because it doesn't really need FP for these parts and because the rest of the world provides so very much good code that also does not need Functional Programming.

Resources