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

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.

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.

What is the relationship between Gallina and OCaml?

I learned that Coq is written in OCaml, but it has the specification language as Gallina. How are these two languages related besides they are all functional programming languages?
That's a bit of a loaded question.
Gallina could exist independently from OCaml, though, being a lambda calculus, it shares some construct and semantics with it, and, having been developed in the OCaml world, it also shares some concrete syntax. But OCaml could not have been suitable to take the place of Gallina.
Some similarities:
They share a lambda calculus-inspired, functional language.
They have similar algebraic data type declarations (though there are lots of differences in what is allowable and expressible).
Some (major) differences:
Gallina has dependent types, while OCaml has a type system that is close to a prenex-polymorphic System F with some subtyping... I'm not sure how to call it, but it is less expressive than dependent types in some ways, though it has some extra features absent from Gallina.
Gallina is total, meaning all functions must be syntactically well-behaved, either clearly terminating, or clearly making computational progress. OCaml is a more general purpose language where non-termination is fine.
Gallina is pure, while OCaml has side-effectful primitives.
Gallina is "functional only" if you will. OCaml has a notion of objects, some "imperative"-looking features (due to all the differences previously listed).
In fact, historically, ML (which OCaml is some variant of) was to LCF sort of what Ltac is to Gallina! :-D (oh boy, I might get some angry comments because of this note...)

Are there purely declarative, general purpose programming languages?

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.

What are the core concepts in functional programming?

In object-oriented programming, we might say the core concepts are:
encapsulation
inheritance,
polymorphism
What would that be in functional programming?
There's no community consensus on what are the essential concepts in functional programming. In
Why Functional Programming Matters (PDF), John Hughes argues that they are higher-order functions and lazy evaluation. In Wearing the Hair Shirt: A Retrospective on Haskell, Simon Peyton Jones says the real essential is not laziness but purity. Richard Bird would agree. But there's a whole crowd of Scheme and ML programmers who are perfectly happy to write programs with side effects.
As someone who has practiced and taught functional programming for twenty years, I can give you a few ideas that are widely believed to be at the core of functional programming:
Nested, first-class functions with proper lexical scoping are at the core. This means you can create an anonymous function at run time, whose free variables may be parameters or local variables of an enclosing function, and you get a value you can return, put into data structures, and so on. (This is the most important form of higher-order functions, but some higher-order functions (like qsort!) can be written in C, which is not a functional language.)
Means of composing functions with other functions to solve problems. Nobody does this better than John Hughes.
Many functional programmers believe purity (freedom from effects, including mutation, I/O, and exceptions) is at the core of functional programming. Many functional programmers do not.
Polymorphism, whether it is enforced by the compiler or not, is a core value of functional programmers. Confusingly, C++ programmers call this concept "generic programming." When polymorphism is enforced by the compiler it is generally a variant of Hindley-Milner, but the more powerful System F is also a powerful basis for functional languages. And with languages like Scheme, Erlang, and Lua, you can do functional programming without a static type system.
Finally, a large majority of functional programmers believe in the value of inductively defined data types, sometimes called "recursive types". In languages with static type systems these are generally known as "algebraic data types", but you will find inductively defined data types even in material written for beginning Scheme programmers. Inductively defined types usually ship with a language feature called pattern matching, which supports a very general form of case analysis. Often the compiler can tell you if you have forgotten a case. I wouldn't want to program without this language feature (a luxury once sampled becomes a necessity).
In computer science, functional programming is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data. It emphasizes the application of functions, in contrast to the imperative programming style, which emphasizes changes in state. Functional programming has its roots in the lambda calculus, a formal system developed in the 1930s to investigate function definition, function application, and recursion. Many functional programming languages can be viewed as embellishments to the lambda calculus. - Wikipedia
In a nutshell,
Lambda Calculus
Higher Order Functions
Immutability
No side-effects
Not directly an answer to your question, but I'd like to point out that "object-oriented" and functional programming aren't necessarily at odds. The "core concepts" you cite have more general counterparts which apply just as well to functional programming.
Encapsulation, more generally, is modularisation. All purely functional languages that I know of support modular programming. You might say that those languages implement encapsulation better than the typical "OO" variety, since side-effects break encapsulation, and pure functions have no side-effects.
Inheritance, more generally, is logical implication, which is what a function represents. The canonical subclass -> superclass relation is a kind of implicit function. In functional languages, this is expressed with type classes or implicits (I consider implicits to be the more general of these two).
Polymorphism in the "OO" school is achieved by means of subtyping (inheritance). There is a more general kind of polymorphism known as parametric polymorphism (a.k.a. generics), which you will find to be supported by pure-functional programming languages. Additionally, some support "higher kinds", or higher-order generics (a.k.a. type constructor polymorphism).
What I'm trying to say is that your "core concepts of OO" aren't specific to OO in any way. I, for one, would argue that there aren't any core concepts of OO, in fact.
Let me repeat the answer I gave at one discussion in the Bangalore Functional Programming group:
A functional program consists only of functions. Functions compute
values from their inputs. We can contrast this with imperative
programming, where as the program executes, values of mutable
locations change. In other words, in C or Java, a variable called X
refers to a location whose value change. But in functional
programming X is the name of a value (not a location). Any where that
X is in scope, it has the same value (i.e, it is referentially
transparent). In FP, functions are also values. They can be passed as
arguments to other functions. This is known as higher-order functional
programming. Higher-order functions let us model an amazing variety of
patterns. For instance, look at the map function in Lisp. It
represents a pattern where the programmer needs to do 'something' to
every element of a list. That 'something' is encoded as a function and
passed as an argument to map.
As we saw, the most notable feature of FP is it's side-effect
freeness. If a function does something more than computing a value
from it's input, then it is causing a side-effect. Such functions are
not allowed in pure FP. It is easy to test side-effect free functions.
There is no global state to set-up before running the test and there
is no global state to check after running the test. Each function can
be tested independently just by providing it's input and examining the
return value. This makes it easy to write automated tests. Another
advantage of side-effect freeness is that it gives you better control
on parallelism.
Many FP languages treat recursion and iteration correctly. They does this by
supporting something called tail-recursion. What tail-recursion is -
if a function calls itself, and it is the last thing it does, it
removes the current stack frame right away. In other words, if a
function calls itself tail-recursively a 1000 times, it does not grow
the stack a 1000 deep. This makes special looping constructs
unnecessary in these languages.
Lambda Calculus is the most boiled down version of an FP language.
Higher level FP languages like Haskell get compiled to Lambda
Calculus. It has only three syntactic constructs but still it is
expressive enough to represent any abstraction or algorithm.
My opinion is that FP should be viewed as a meta-paradigm. We can
write programs in any style, including OOP, using the simple
functional abstractions provided by the Lambda Calculus.
Thanks,
-- Vijay
Original discussion link: http://groups.google.co.in/group/bangalore-fp/browse_thread/thread/4c2cfa7985d7eab3
Abstraction, the process of making a function by parameterizing over some part of an expression.
Application, the process of evaluating a function by replacing its parameters with specific values.
At some level, that's all there is to it.
Though the question is older, thought of sharing my view as reference.
Core Concept in FP is "FUNCTION"
FP gives KISS(Keep It Simple Sxxxxx) programming paradigm (once you get the FP ideas, you will literally start hating the OO paradigm)
Here is my simple FP comparison with OO Design Patterns. Its my perspective of seeing FP and pls correct me if there is any discrepancy from actual.

How helpful is knowing lambda calculus? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
To all the people who know lambda calculus: What benefit has it bought you, regarding programming? Would you recommend that people learn it?
The benefit of lambda calculus is that it's an extremely simple model of computation that is equivalent to a Turing machine. But while a Turing machine is more like assembly language, lambda calculus is more a like a high-level language. And if you learn Church encodings that will help you learn the programming technique called continuation-passing style, which is quite useful for implementing backtracking search and other neat tricks.
The main use of lambda calculus in practice is that it is a great laboratory tool for studying new programming-language ideas. If you have an idea for a new language feature, you can add the new feature to the lambda calculus and you get something that is expressive enough to program while being simple enough to study very thoroughly. This use is really more for language designers and theorists than for programmers.
Lambda calculus is also just very cool in its own right: just like knowing assembly language, it will deepen your understanding of computation. It's especially fun to program a universal turing machine in the lambda calculus. But this is foundational mathematics, not practical programming.
If you want to program in any functional programming language, it's essential. I mean, how useful is it to know about Turing machines? Well, if you write C, the language paradigm is quite close to Turing machines -- you have an instruction pointer and a current instruction, and the machine takes some action in the current state, and then ambles along to the next instruction.
In a functional language, you simply can't think like that -- that's not the language paradigm. You have to think back to lambda calculus, and how terms are evaluated there. It will be much harder for you to be effective in a functional language if you don't know lambda calculus.
To be honest, learning lambda calculus before functional programming has made me realize that the two are as unrelated as C is to any imperative programming.
Lambda calculus is a functional programming language, an esoteric one, a Turing tarpit if you like; accidentally it's also the first.
The majority of functional programming languages at all do not require you to 'learn' lambda calculus, whatever that would mean, lambda calculus is insanely minimal, you can 'learn' its axioms in an under an hour. To know the results from it, like the fixedpoint theorem, the Church-Rosser Theorem et cetera is just irrelevant to functional programming.
Also, lambda-abstractions are often held to be 'functions', I disagree with that, they are algorithms, not functions, a minor difference, most 'functional languages' treat their functions more in the way classical mathematics does.
However, to for instance effectively use Haskell you do need to understand certain type systems, that's irrespective of lambda calculus, the System F type system can be applied to all 'functions' and requires no lambda abstractions at all. Commonly in maths we say f : R^2 -> R : f (x) = x^2. We could've said: f (x) = x^2 :: R -> R -> R. In fact, Haskell comes pretty close to this notation.
Lambda calculus is a theoretical formalism, Haskell's functions are really no more 'lambda abstractions' than f : f(x) = x^2 really, what makes lambda abstractions interesting is that it enables us to define what are normally seen as 'constants' as 'functions', no functional language does that because of the huge computational overhead. Haskell and alike is just a restricted form of System F's type system applied to functions as used in everyday classical maths. Functions in Haskell are certainly not the anonymous formally symbolic reduction-applicants as they are in lambda-calculus. Most functional programming languages are not symbolic reduction-based re-writing systems. Lisps are to some degree but that's a paradigm on its own and its 'lambda keyword' really doesn't satisfy calling it lambda calculus.
I think the use of lambda calculus with respect to programming in practice is that it is a quite minimal system that captures the essence of abstraction (or "anonymous functions" or closures, if you will). Other than that I don't think it is generally essential except when you need to implement abstraction yourself (as Tetha (114646) mentioned).
I also completely disagree with Denis Bueno (114701) who says that it is essential for functional programming. It is perfectly well possible to define, use or understand a functional language without any lambda calculus at all. In order to understand the evaluation of terms in functional languages (which, in my opinion, somewhat contradicts the use of a functional language) you will most likely be better of learning about term rewrite systems.
I agree with those that say it is theoretically possible to learn functional programming without learning the lambda calculus—but what's the advantage of not learning the lambda calculus? It's not as if it takes a big investment of time.
Most likely, it will help you understand functional programming better. But even if it doesn't, it's still a cool thing worth learning. The Y-combinator is a thing of beauty.
If you only want to be a technician and write programs to do things, then you don't really need to know lambda-calculus, finite-state machines, pushdown automata, regular expressions, context-free grammar, discrete mathematics, etc.
But if you have curiosity about the deeper mysteries underlying this stuff, you can start to wonder how these questions might be answered. The concepts are beautiful and will expand your imagination. I also think they, incidentally, make one a better practicioner.
What got me hooked was Minsky's book Computation: Finite and Infinite Machines.
The lambda calculus is a computational model, just like the turing machine. Thus, it is useful if you need to implement a certain evaluator for a language based on this model, however, in practice, you just need the basic idea (uh. place argument semantically correct in the body of a function?) and that's about it.
One posible way to learn lambda calculus is
http://en.wikipedia.org/wiki/Lambda_Calculus
Or, if you want more, here is my blog dedicated to lambda calculus and stuff like that
http://weblogs.manas.com.ar/lziliani/
As every abstraction of computations, with lambda calculus you can model stuff used in most programming languages, like subtyping. For more about this, one of the best books with practical uses of lambda calculus in this sense is
http://www.amazon.com/Types-Programming-Languages-Benjamin-Pierce/dp/0262162091/ref=sr_1_1?ie=UTF8&s=books&qid=1222088714&sr=8-1
I found that the Lambda calculus was useful for understand how functional programming worked on a deeper level. Especially how to implement functional languages.
It has made it easier for me to understand advanced concepts like type-systems and evaluations strategies (e.g. call by name versus call by value).
I don't think one needs to know anything about the Lambda calculus to use basic functional programming techniques. However understanding the lambda calculus makes it easier to learn advanced programming theory.
I'd also like to mention that if you're doing anything in the area of NLP, lambda calculus is at the foundation of a massive body of work in compositional semantics.
The benefits for me is a more compact synergistic programming. Stuff tends to flow horizontally more than vertically. Plus it is very useful for prototyping simple algorithms. Don't know if I am using it to its full potential but I find it very useful.

Resources