Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I come from an object oriented background where I've learned that classes are or at least can be used to make a layer of abstraction that allows for easy recycling of code which can then either be used to make objects or be used in inheritance.

Like for example I can have an animal class and then from that inherit cats and dogs and such that all inherit many of the same traits, and from those sub-classes I can then make objects that can specify a breed of animal or even the name of it.
Or I can use classes to specify multiple instances of the same code that handles or contains slightly different things; like nodes in a search-tree or multiple different database connections and what not.

I'm recently moving into functional programming, so I was starting to wonder:
How do purely functional languages handle things like that? That is, languages without any concept of classes and objects.

share|improve this question
1  
Why do you think that functional doesn't mean classes? The some of the frist classes came from LISP - CLOS Look at clojure namespaces and types or modules and haskell. –  MichaelT Jun 9 '13 at 18:58
    
I referred to the functional languages that DON'T have classes, I'm very well aware of the few that DO –  Electric Coffee Jun 9 '13 at 19:12
    
Which ones are the ones without classes? –  MichaelT Jun 9 '13 at 19:14
1  
Caml as an example, its sister language OCaml adds objects, but Caml itself doesn't have them. –  Electric Coffee Jun 9 '13 at 19:19
11  
The term "purely functional" refers to functional languages that maintain referential transparency and is unrelated to whether or not the language has any object oriented features. –  sepp2k Jun 9 '13 at 22:42

4 Answers 4

Many functional languages have a module system. (Many object-oriented languages do too, by the way.) But even in the absence of one, you can use functions as modules.

JavaScript is a good example. In JavaScript, functions are used both to implement modules and even object-oriented encapsulation. In Scheme, which was the major inspiration for JavaScript, there are only functions. Functions are used to implement almost everything: objects, modules (called units in Racket), even data structures.

OTOH, Haskell and the ML family have an explicit module system.

Object Orientation is about data abstraction. That's it. Modularity, Inheritance, Polymorphism, even mutable state are orthogonal concerns.

share|improve this answer
7  
Can you explain how those things work in a bit more detail in relation to oop? Rather than simply stating that the concepts exist... –  Electric Coffee Jun 9 '13 at 19:14

Although "functional programming" does not convey far reaching implications for issues of modularity, particular languages address programming-in-the-large in different ways. Code reuse and abstraction interact in that the less you expose the harder it is to reuse the code. Putting abstraction aside, I'll address two issues of reusability.

Statically typed OOP languages traditionally used nominal subtyping, which means that a code designed for class/module/interface A can only deal with class/module/interface B when B explicitly mentions A. Languages in functional programming family mainly use structural subtyping, which means that code designed for A can handle B whenever B has all the methods and/or fields of A. B could have been created by a different team before there was need for a more general class/interface A. For example in OCaml, structural subtyping applies to the module system, the OOP-like object system, and its quite unique polymorphic variant types.

The most prominent difference between OOP and FP wrt. modularity is that the default "unit" in OOP bundles together as an object various operations on the same case of values, while the default "unit" in FP bundles together as a function the same operation for various cases of values. In FP it is still very easy to bundle operations together, for example as modules. (BTW, neither Haskell nor F# have a full-fledged ML-family module system.) The Expression Problem is the task of incrementally adding both new operations working on all values (e.g. attaching a new method to existing objects), and new cases of values which all operations should support (e.g. adding a new class with the same interface). As discussed in the first Ralf Laemmel lecture below (which has extensive examples in C#), adding new operations is problematic in OOP languages.

The combination of OOP and FP in Scala might make it one of the most powerful languages wrt. modularity. But OCaml is still my favorite language and in my personal, subjective opinion it doesn't fall short of Scala. The two Ralf Laemmel lectures below discuss the solution to the expression problem in Haskell. I think this solution, although perfectly working, makes it difficult to use the resulting data with parametric polymorphism. Solving the expression problem with polymorphic variants in OCaml, explained in Jaques Garrigue article linked below, does not have this shortcoming. I also link to textbook chapters that compare the uses of non-OOP and OOP modularity in OCaml.

Below are Haskell- and OCaml-specific links expanding on the Expression Problem:

share|improve this answer
2  
would you mind explaining more on what these resources do and why do you recommend these as answering the question asked? "Link-only answers" are not quite welcome at Stack Exchange –  gnat Jun 10 '13 at 14:39
2  
I have just provided an actual answer rather than just links, as an edit. –  lukstafi Jun 10 '13 at 19:28

It looks like you're asking two questions: "How can you achieve modularity in functional languages?" which has been dealt with in other answers and "how can you create abstractions in functional languages?" which I'll answer.

In OO languages, you tend to concentrate on the noun, "an animal", "the mailserver", "his garden fork", etc. Functional languages, by contrast, emphasise the verb, "to walk", "to fetch mail", "to prod", etc.

It's no surprise, then, that abstractions in functional languages tend be over verbs or operations rather than over things. One example that I always reach for when I'm trying to explain this is parsing. In functional languages, a good way to write parsers is by specifying a grammar and then interpreting it. The interpreter creates an abstraction over the process of parsing.

Another concrete example of this is a project I was working on not long ago. I was writing a database in Haskell. I had one 'embedded language' for specifying operations at the lowest level; for example, it allowed me to write and read things from the storage medium. I had another, separate, 'embedded language' for specifying operations at the highest level. Then I had, what is essentially an interpreter, for converting operations from the higher level to the lower level.

This is a remarkably general form of abstraction, but it is not the only one available in functional languages.

share|improve this answer

One of popular solutions, is to break code into modules, here is how it's done in JavaScript:

    media.podcast = (function(name) {
    var fileExtension = 'mp3';        

     function determineFileExtension() {
         console.log('File extension is of type ' + fileExtension);
     }

     return {
         download: function(episode) {
            console.log('Downloading ' + episode + ' of ' + name);
            determineFileExtension();
        }
    }    
}('Astronomy podcast'));

The full article explaining this pattern in JavaScript, apart from that there is number of other ways to define a module, such as RequireJS, CommonJS, Google Closure. Another example is Erlang, where you have both modules and behaviours that enforce API and pattern, playing similar role as Interfaces in OOP.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.