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

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.

Related

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.

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...

Continuations in Clojure

I read somewhere where rich hickey said:
"I think continuations might be neat
in theory, but not in practice"
I am not familiar with clojure.
1. Does clojure have continuations?
2. If no, don't you need continuations? I have seen a lot of good examples especially from this guy. What is the alternative?
3. If yes, is there a documentation?
When talking about continuations, you’ll have to distinguish between two different kinds of them:
First-class continuations – Continuation-support that is deeply integrated in the language (Scheme or Ruby). Clojure does not support first-class continuations.
Continuation-passing-style (CPS) – CPS is just a style of coding and any language supporting anonymous functions will allow this style (which applies to Clojure too).
Examples:
-- Standard function
double :: Int -> Int
double x = 2 * x
-- CPS-function – We pass the continuation explicitly
doubleCPS :: Int -> (Int -> res) -> res
doubleCPS x cont = cont (2 * x)
; Call
print (double 2)
; Call CPS: Continue execution with specified anonymous function
double 2 (\res -> print res)
Read continuation on Wikipedia.
I don’t think that continuations are necessary for a good language, but especially first-class continuations and CPS in functional languages like Haskell can be quite useful (intelligent backtracking example).
I've written a Clojure port of cl-cont which adds continuations to Common Lisp.
https://github.com/swannodette/delimc
Abstract Continuations
Continuations are an abstract notion that are used to describe control flow semantics. In this sense, they both exist and don't exist (remember, they're abstract) in any language that offers control operators (as any Turing complete language must), in the same way that numbers both exist (as abstract entities) and don't exist (as tangible entities).
Continuations describe control effects such as function call/return, exception handling, and even gotos. A well founded language will, among other things, be designed with abstractions that are built on continuations (e.g., exceptions). (That is to say, a well-founded language will consist of control operators that were designed with continuations in mind. It is, of course, perfectly reasonable for a language to expose continuations as the only control abstraction, allowing users to build their own abstractions on top.)
First Class Continuations
If the notion of a continuation is reified as a first-class object in a language, then we have a tool upon which all kinds of control effects can be built. For example, if a language has first-class continuations, but not exceptions, we can construct exceptions on top of continuations.
Problems with First-Class Continuations
While first-class continuations are a powerful and useful tool in many cases, there are also some drawbacks to exposing them in a language:
Different abstractions built on top of continuations may result in unexpected / unintuitive behavior when composed. For example, a finally block might be skipped if I use a continuation to abort a computation.
If the current continuation may be requested at any time, then the language run-time must be structured so that it is possible to produce some data-structure representation of the current continuation at any time. This places some degree of burden on the run-time for a feature which, for better or worse, is often considered "exotic". If the language is hosted (such as Clojure is hosted on the JVM), then that representation must be able to fit within the framework provided by the hosting platform. There may also be other features a language would like to maintain (e.g., C interop) which restrict the solution space. Issues such as these increase the potential of an "impedence mismatch", and can severely complicate development of a performant solution.
Adding First-Class Continuations to a Language
Through metaprogramming, it is possible to add support for first-class continuations to a language. Generally, this approach involves transforming code to continuation-passing style (CPS), in which the current continuation is passed around as an explicit argument to each function.
For example, David Nolen's delimc library implements delimited continuations of portions of a Clojure program through a series of macro transforms. In a similar vein, I have authored pulley.cps, which is a macro compiler that transforms code into CPS, along with a run-time library to support more core Clojure features (such as exception handling) as well as interop with native Clojure code.
One issue with this approach is how you handle the boundary between native (Clojure) code and transformed (CPS) code. Specifically, since you can't capture the continuation of native code, you need to either disallow (or somehow restrict) interop with the base language or place a burden on the user of ensuring the context will allow any continuation they wish to capture to actually be captured.
pulley.cps tends towards the latter, although some attempts have been made to allow the user to manage this. For instance, it is possible to disallow CPS code to call into native code. In addition, a mechanism is provided to supply CPS versions of existing native functions.
In a language with a sufficiently strong type system (such as Haskell), it is possible to use the type system to encapsulate computations which might use control operations (i.e., continuations) from functionally pure code.
Summary
We now have the information necessary to directly answer your three questions:
Clojure does not support first-class continuations due to practical considerations.
All languages are built on continuations in the theoretical sense, but few languages expose continuations as first-class objects. However, it is possible to add continuations to any language via, e.g., transformation into CPS.
Check out the documentation for delimc and/or pulley.cps.
Is continuation a necessary feature in a language?
No. Plenty of languages don't have continuations.
If no, dont you need continuations? I have seen a lot of good examples especially from this guy. What is the alternative?
A call stack
A common use of continuations is in the implementation of control structures for: returning from a function, breaking from a loop, exception handling etc. Most languages (like Java, C++ etc) provide these features as part of the core language. Some languages don't (e.g: Scheme). Instead, these languages expose continuatiions as first class objects and let the programmer define new control structures. Thus Scheme should be looked upon as a programming language toolkit, not a complete language in itself.
In Clojure, we almost never need to use continuations directly, because almost all the control structures are provided by the language/VM combination. Still, first class continuations can be a powerful tool in the hands of the competent programmer. Especially in Scheme, continuations are better than the equivalent counterparts in other languages (like the setjmp/longjmp pair in C). This article has more details on this.
BTW, it will be interesting to know how Rich Hickey justifies his opinion about continuations. Any links for that?
Clojure (or rather clojure.contrib.monads) has a continuation monad; here's an article that describes its usage and motivation.
Well... Clojure's -> implements what you are after... But with a macro instead

Functional programming and non-functional programming

In my second year of University we were "taught" Haskell, I know almost nothing about it and even less about functional programming.
What is functional programming, why and/xor where would I want to use it instead of non-functional programming and am I correct in thinking that C is a non-functional programming language?
One key feature in a functional language is the concept of first-class functions. The idea is that you can pass functions as parameters to other functions and return them as values.
Functional programming involves writing code that does not change state. The primary reason for doing so is so that successive calls to a function will yield the same result. You can write functional code in any language that supports first-class functions, but there are some languages, like Haskell, which do not allow you to change state. In fact, you're not supposed to make any side effects (like printing out text) at all - which sounds like it could be completely useless.
Haskell instead employs a different approach to IO: monads. These are objects that contain the desired IO operation to be executed by your interpreter's toplevel. At any other level they are simply objects in the system.
What advantages does functional programming provide? Functional programming allows coding with fewer potentials for bugs because each component is completely isolated. Also, using recursion and first-class functions allows for simple proofs of correctness which typically mirror the structure of the code.
What is functional programming
There are two different definitions of "functional programming" in common use today:
The older definition (originating from Lisp) is that functional programming is about programming using first-class functions, i.e. where functions are treated like any other value so you can pass functions as arguments to other functions and function can return functions among their return values. This culminates in the use of higher-order functions such as map and reduce (you may have heard of mapReduce as a single operation used heavily by Google and, unsurprisingly, it is a close relative!). The .NET types System.Func and System.Action make higher-order functions available in C#. Although currying is impractical in C#, functions that accept other functions as arguments are common, e.g. the Parallel.For function.
The younger definition (popularized by Haskell) is that functional programming is also about minimizing and controlling side effects including mutation, i.e. writing programs that solve problems by composing expressions. This is more commonly called "purely functional programming". This is made possible by wildly different approaches to data structures called "purely functional data structures". One problem is that translating traditional imperative algorithms to use purely functional data structures typically makes performance 10x worse. Haskell is the only surviving purely functional programming language but the concepts have crept into mainstream programming with libraries like Linq on .NET.
where would I want to use it instead of non-functional programming
Everywhere. Lambdas in C# have now demonstrated major benefits. C++11 has lambdas. There's no excuse not to use higher-order functions now. If you can use a language like F# you'll also benefit from type inference, automatic generalization, currying and partial application (as well as lots of other language features!).
am I correct in thinking that C is a non-functional programming language?
Yes. C is a procedural language. However, you can get some of the benefit of functional programming by using function pointers and void * in C.
May be worth checking out this article on F# "101" on CoDe Mag recently posted.
Also, Dustin Campbell has a great blog where he has posted many articles on his adventures on getting up to speed with F#..
I hope you find these useful :)
EDIT:
Also, just to add, my understanding of functional programming is that everything is a function, or parameters to a function, rather than instances/stateful objects.. But I could be wrong F# is something I am dying to get in to but just dont have the time! :)
John the Statistician's example code does not show functional programming, because when you're doing functional programming, the key is that the code does NO ASSIGNMENTS ( record = thingConstructor(t) is an assignment), and it has NO SIDE EFFECTS (localMap.put(record) is a statement with a side effect). As a result of these two constraints, everything that a function does is fully captured by its arguments and its return value. Rewriting the Statistician's code the way it would have to look, if you wanted to emulate a functional language using C++:
RT getOrCreate(const T thing,
const Function<RT<T>> thingConstructor,
const Map<T,RT<T>> localMap) {
return localMap.contains(t) ?
localMap.get(t) :
localMap.put(t,thingConstructor(t));
}
As a result of the no side-effects rule, every statement is part of the return value (hence return comes first), and every statement is an expression. In languages that enforce functional programming, the return keyword is implied, and the if statement behaves like C++'s ?: operator.
Also, everything is immutable, so localMap.put has to create a new copy of localMap and return it, instead of modifying the original localMap, the way a normal C++ or Java program would. Depending on the structure of localMap, the copy could re-use pointers into the original, reducing the amount of data that has to be copied.
Some of the advantages of functional programming include the fact that functional programs are shorter, and it is easier to modify a functional program (because there are no hidden global effects to take into account), and it is easier to get the program right in the first place.
However, functional programs tend to run slowly (because of all the copying they have to do), and they don't tend to interact well with other programs, operating system processes, or operating systems, which deal in memory addresses, little-endian blocks of bytes, and other machine-specific, non-functional bits. The degree of noninteroperability tends to be inversely correlated with the degree of functional purity, and the strictness of the type system.
The more popular functional languages have really, really strict type systems. In OCAML, you can't even mix integer and floating-point math, or use the same operators (+ is for adding integers, +. is for adding floats). This can be either an advantage or a disadvantage, depending on how highly you value the ability of a type checker to catch certain kinds of bugs.
Functional languages also tend to have really big runtime environments. Haskell is an exception (GHC executables are almost as small as C programs, both at compile-time and runtime), but SML, Common Lisp, and Scheme programs always require tons of memory.
Yes you are correct in thinking that C is a non-functional language. C is a procedural language.
I prefer to use functional programming to save myself repeated work, by making a more abstract version and then using that instead. Let me give an example. In Java, I often find myself creating maps to record structures, and thus writing getOrCreate structures.
SomeKindOfRecord<T> getOrCreate(T thing) {
if(localMap.contains(thing)) { return localMap.get(thing); }
SomeKindOfRecord<T> record = new SomeKindOfRecord<T>(thing);
localMap = localMap.put(thing, record);
return record;
}
This happens very often. Now, in a functional language I could write
RT<T> getOrCreate(T thing,
Function<RT<T>> thingConstructor,
Map<T,RT<T>> localMap) {
if(localMap.contains(thing)) { return localMap.get(thing); }
RT<T> record = thingConstructor(thing);
localMap = localMap.put(thing,record);
return record;
}
and I would never have to write a new one of these again, I could inherit it. But I could do one better than inheriting, I could say in the constructor of this thing
getOrCreate = myLib.getOrCreate(*,
SomeKindOfRecord<T>.constructor(<T>),
localMap);
(where * is a kind of "leave this parameter open" notation, which is a sort of currying)
and then the local getOrCreate is exactly the same as it would have been if I wrote out the whole thing, in one line, with no inheritance dependencies.
If you are looking for a good text on F#
Expert F# is co-written by Don Syme. Creator of F#. He worked on generics in .NET specifically so he could create F#.
F# is modeled after OCaml so any OCaml text would help you learn F# as well.
I find What Is Functional Programming? to be useful
Functional programming is about writing pure functions, about removing
hidden inputs and outputs as far as we can, so that as much of our
code as possible just describes a relationship between inputs and
outputs.
Prefer explicit when param
public Program getProgramAt(TVGuide guide, int channel, Date when) {
Schedule schedule = guide.getSchedule(channel);
Program program = schedule.programAt(when);
return program;
}
over
public Program getCurrentProgram(TVGuide guide, int channel) {
Schedule schedule = guide.getSchedule(channel);
Program current = schedule.programAt(new Date());
return current;
}
A functional language is actively hostile to side-effects. Side-effects are complexity and complexity is bugs and bugs are the devil. A functional language will help you be hostile to side-effects too.

Resources