Is Erlang really a functional language? [closed] - functional-programming

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.

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.

Is functional programming a type of declarative programming?

I am aware that declarative programming just passes the input and expects the output without stating the procedure how it is done. In functional programming, is a programming paradigm, which takes an input and returns an output. When I checked the Higher order functional programming, we pass a function to map/reduce, which does not reveal the procedure how it is done. So is higher order functional programming and declarative programming the same thing??
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
design a language that allows a programmer to describe what he wants without going into details on how to do it;
implement a compiler that will generate - based on such programs - an efficient implementation; and
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.
Not entirely, functional programming emphasises more on what to compute rather than how to compute. However, there are patterns available in functional programming that are pretty much control flow patterns you would commonly associate with declarative programming, take for example the following control flow:
let continue = ref true in
while !continue do
...
if cond then continue := false
else
...
done
Looks familiar huh? Here you can see some declarative constructs but this time round we are in more control.

Which is the easiest functional programming language for someone who has background in imperative languages? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I would like to learn a functional language in order to broaden my horizon. I have knowledge of Python and C/C++ and I want a language to be easy to learn from someone who comes from the imperative domain of languages. I don't care if the language is powerful enough. I just want a language in order to learn the basic of functional programming and then I will try for a more difficult (and powerful language).
Thanks
I recommend pure-lang for these pedagogical ends. It's also plenty powerful. If you want something more popular / with more community support, then I'd recommend Scheme or OCaml, depending on whether you'd rather deal with unfamiliar syntax (go with Scheme) or deal with unfamiliar typing (go with OCaml) first. SML and F# are only slightly different from OCaml. Others have or will mention Clojure, Scala, and Haskell.
Clojure is a variant of Scheme, with its own idiosyncracies (e.g. no tail-call optimization), so using it would be a way of starting with Scheme. I'd expect you'd have an easier time with a less idiosyncratic Scheme implementation though. Racket is what's often used for teaching. Scala looks to be fundamentally similar to OCaml, but this is based on only casual familiarity.
Unlike Haskell, the other languages mentioned all have two advantages: (1) evaluation-order is eager by default, though you can get lazy evaluation by specifically requesting it. In Haskell's the reverse. (2) Mutation is available, though much of the libraries and code you'll see doesn't use it. I actually think it's pedagogically better to learn functional programming while at the same time having an eye on how it interacts with side-effects, and working your way to monadic-style composition somewhat down the road. So I think this is an advantage. Some will tell you that it's better to be thrown into Haskell's more-quarantined handling of mutaton first, though.
Robert Harper at CMU has some nice blog posts on teaching functional programming. As I understand, he also prefers languages like OCaml for teaching.
Among the three classes of languages I recommended (Pure, Scheme and friends, OCaml and friends), the first two have dynamic typing. The first and third have explicit reference cells (as though in Python, you restricted yourself to never reassiging a variable but you could still change what's stored at a list index). Scheme has implicit reference cells: variables themselves look mutable, as in C and Python, and the reference cell handling is done under the covers. In languages like that, you often have some form of explicit reference cell available too (as in the example I just gave in Python, or using mutable pairs/lists in Racket...in other Schemes, including the Scheme standard, those are the default pairs/lists).
One virtue Haskell does have is some textbooks are appearing for it. (I mean this sincerely, not snarkily.) What books/resources to use is another controversial issue with many wars/closed questions. SICP as others have recommended has many fans and also some critics. There seem to me to be many good choices. I won't venture further into those debates.
At first, read Structure and Implementation of Computer Programs. I recommend Lisp (for, example, it's dialect Scheme) as first functional programming language.
Another option is Clojure, which I'm given to understand is more "purely" functional than Scheme/Racket (don't ask me about the details here) and possibly similar enough to let you use it in conjunction with SICP (Structure and Interpretation of Computer Programs, a highly recommended book also suggested by another answer).
I would like to learn a functional language in order to broaden my horizon. I have knowledge of Python and C/C++ and I want a language to be easy to learn from someone who comes from the imperative domain of languages. I don't care if the language is powerful enough. I just want a language in order to learn the basic of functional programming and then I will try for a more difficult (and powerful language).
Great question!
I had done BASIC, Pascal, assembler, C and C++ before I started doing functional programming in the late 1990s. Then I started using two functional languages at about the same time, Mathematica and OCaml, and was using them exclusively within a few years. In particular, OCaml let me write imperative code which looked like the code I had been writing before. I found that valuable as a learner because it let me compare the different approaches which made the advantages of ML obvious.
However, as others have mentioned, the core benefit of Mathematica and OCaml is pattern matching and that is not technically related to functional programming. I have subsequently looked at many other functional languages but I have no desire to go back to a language that lacks pattern matching.
This question is probably off-topic because it is going to result in endless language wars, but here's a general bit of advice:
There are a class of functional programming languages which are sometimes called "mostly functional", in that they permit some imperative features where you want them. Examples include Standard ML, OCaml, F#, and Scala. You might consider one of these if you want to be able to get a grip on the functional idiomatic style while still being able to achieve things in reasonably familiar ways.
I've used Standard ML extensively in the past, but if you're looking for something that has a bit less of a learning curve, I'd personally recommend Scala, which is my second-favourite programming language. The reasons for this include the prevalence of libraries, a healthy-sized community, and the availability of nice books and tutorials to help you getting started (particularly if you have ever had any dealings with Java).
One element that was not discussed is the availability of special pattern-matching syntax for algebraic datatypes, as in Haskell, all flavors of ML, and probably several of the other languages mentioned. Pattern-matching syntax tends to help the programmer see their functions as mathematical functions. Haskell's syntax is sufficiently complex, and its implementations have sufficiently poor parse error messages, that syntax is a decent reason not to choose Haskell. Scheme is probably easier to learn than most other options (and Scheme probably has the king of all macro systems), but the lack of pattern matching syntax would steer me away from it for an intro to functional programming.

Do functional languages cope well with complexity?

I am curious how functional languages compare (in general) to more "traditional" languages such as C# and Java for large programs. Does program flow become difficult to follow more quickly than if a non-functional language is used? Are there other issues or things to consider when writing a large software project using a functional language?
Thanks!
Functional programming aims to reduce the complexity of large systems, by isolating each operation from others. When you program without side-effects, you know that you can look at each function individually - yes, understanding that one function may well involve understanding other functions too, but at least you know it won't interfere with some other piece of system state elsewhere.
Of course this is assuming completely pure functional programming - which certainly isn't always the case. You can use more traditional languages in a functional way too, avoiding side-effects where possible. But the principle is an important one: avoiding side-effects leads to more maintainable, understandable and testable code.
Does program flow become difficult to follow more quickly than if a >non-functional language is used?
"Program flow" is probably the wrong concept to analyze a large functional program. Control flow can become baroque because there are higher-order functions, but these are generally easy to understand because there is rarely any shared mutable state to worry about, so you can just think about arguments and results. Certainly my experience is that I find it much easier to follow an aggressively functional program than an aggressively object-oriented program where parts of the implementation are smeared out over many classes. And I find it easier to follow a program written with higher-order functions than with dynamic dispatch. I also observe that my students, who are more representative of programmers as a whole, have difficulties with both inheritance and dynamic dispatch. They do not have comparable difficulties with higher-order functions.
Are there other issues or things to consider when writing a large
software project using a functional language?
The critical thing is a good module system. Here is some commentary.
The most powerful module system I know of the unit system of PLT Scheme designed by Matthew Flatt and Matthias Felleisen. This very powerful system unfortunately lacks static types, which I find a great aid to programming.
The next most powerful system is the Standard ML module system. Unfortunately Standard ML, while very expressive, also permits a great many questionable constructs, so it is easy for an amateur to make a real mess. Also, many programmers find it difficult to use Standard ML modules effectively.
The Objective Caml module system is very similar, but there are some differences which tend to mitigate the worst excesses of Standard ML. The languages are actually very similar, but the styles and idioms of Objective Caml make it significantly less likely that beginners will write insane programs.
The least powerful/expressive module system for a functional langauge is the Haskell module system. This system has a grave defect that there are no explicit interfaces, so most of the cognitive benefit of having modules is lost. Another sad outcome is that while the Haskell module system gives users a hierarchical name space, use of this name space (import qualified, in case you're an insider) is often deprecated, and many Haskell programmers write code as if everything were in one big, flat namespace. This practice amounts to abandoning another of the big benefits of modules.
If I had to write a big system in a functional language and had to be sure that other people understood it, I'd probably pick Standard ML, and I'd establish very stringent programming conventions for use of the module system. (E.g., explicit signatures everywhere, opague ascription with :>, and no use of open anywhere, ever.) For me the simplicity of the Standard ML core language (as compared with OCaml) and the more functional nature of the Standard ML Basis Library (as compared with OCaml) are more valuable than the superior aspects of the OCaml module system.
I've worked on just one really big Haskell program, and while I found (and continue to find) working in Haskell very enjoyable, I really missed not having explicit signatures.
Do functional languages cope well with complexity?
Some do. I've found ML modules and module types (both the Standard ML and Objective Caml) flavors invaluable tools for managing complexity, understanding complexity, and placing unbreachable firewalls between different parts of large programs. I have had less good experiences with Haskell
Final note: these aren't really new issues. Decomposing systems into modules with separate interfaces checked by the compiler has been an issue in Ada, C, C++, CLU, Modula-3, and I'm sure many other languages. The main benefit of a system like Standard ML or Caml is the that you get explicit signatures and modular type checking (something that the C++ community is currently struggling with around templates and concepts). I suspect that these issues are timeless and are going to be important for any large system, no matter the language of implementation.
I'd say the opposite. It is easier to reason about programs written in functional languages due to the lack of side-effects.
Usually it is not a matter of "functional" vs "procedural"; it is rather a matter of lazy evaluation.
Lazy evaluation is when you can handle values without actually computing them yet; rather, the value is attached to an expression which should yield the value if it is needed. The main example of a language with lazy evaluation is Haskell. Lazy evaluation allows the definition and processing of conceptually infinite data structures, so this is quite cool, but it also makes it somewhat more difficult for a human programmer to closely follow, in his mind, the sequence of things which will really happen on his computer.
For mostly historical reasons, most languages with lazy evaluation are "functional". I mean that these language have good syntaxic support for constructions which are typically functional.
Without lazy evaluation, functional and procedural languages allow the expression of the same algorithms, with the same complexity and similar "readability". Functional languages tend to value "pure functions", i.e. functions which have no side-effect. Order of evaluation for pure function is irrelevant: in that sense, pure functions help the programmer in knowing what happens by simply flagging parts for which knowing what happens in what order is not important. But that is an indirect benefit and pure functions also appear in procedural languages.
From what I can say, here are the key advantages of functional languages to cope with complexity :
Functional programming hates side-effects.
You can really black-box the different layers
and you won't be afraid of parallel processing
(actor model like in Erlang is really easier to use
than locks and threads).
Culturally, functional programmer
are used to design a DSL to express
and solve a problem. Identifying the fundamental
primitives of a problem is a radically
different approach than rushing to the brand
new trendy framework.
Historically, this field has been led by very smart people :
garbage collection, object oriented, metaprogramming...
All those concepts were first implemented on functional platform.
There is plenty of literature.
But the downside of those languages is that they lack support and experience in the industry. Having portability, performance and interoperability may be a real challenge where on other platform like Java, all of this seems obvious. That said, a language based on the JVM like Scala could be a really nice fit to benefit from both sides.
Does program flow become difficult to
follow more quickly than if a
non-functional language is used?
This may be the case, in that functional style encourages the programmer to prefer thinking in terms of abstract, logical transformations, mapping inputs to outputs. Thinking in terms of "program flow" presumes a sequential, stateful mode of operation--and while a functional program may have sequential state "under the hood", it usually isn't structured around that.
The difference in perspective can be easily seen by comparing imperative vs. functional approaches to "process a collection of data". The former tends to use structured iteration, like a for or while loop, telling the program "do this sequence of tasks, then move to the next one and repeat, until done". The latter tends to use abstracted recursion, like a fold or map function, telling the program "here's a function to combine/transform elements--now use it". It isn't necessary to follow the recursive program flow through a function like map; because it's a stateless abstraction, it's sufficient to think in terms of what it means, not what it's doing.
It's perhaps somewhat telling that the functional approach has been slowly creeping into non-functional languages--consider foreach loops, Python's list comprehensions...

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