31

In other words, what makes a language pure?

For example, Smalltalk is considered to be a purely object-oriented language. Haskell and Lisp are arguably known to be purely functional languages.

When we say pure, does that mean they're not capable of other programming paradigms (which is far from the truth) or does it mean they were designed to be used in that "purely" X paradigm?

pat34515
  • 1,959
  • 12
  • 13
  • While it's an interesting question, I think it would be better if moved to programmers.se – Ptharien's Flame Jul 23 '12 at 07:18
  • possible duplicate of [Pure Functional Language: Haskell](http://stackoverflow.com/questions/4382223/pure-functional-language-haskell) – Chris Jul 23 '12 at 07:19
  • 19
    Lisp is not a purely functional language. – augustss Jul 23 '12 at 07:36
  • 10
    While it is very theoretical, this question has a clear and definite answer that isn't subjective; "pure" has different definitions, but they *are* definitions, albeit in various contexts. The question could arguably be off-topic, but it **is** constructive. (Voting to reopen) – dflemstr Jul 23 '12 at 09:37

2 Answers2

57

The word pure has different meanings in different contexts.

Functional Programming

When people talk about Haskell being a pure language, they mean that it has referential transparency. That is, you can replace any expression with its value without changing the meaning of the program. For example, in Haskell:

square :: Int -> Int
square x = x * x

main = print (square 4)

the expression square 4 can be replaced with its value (16) without changing the meaning of the program. On the other, hand, in this Java code:

public int square(int x) {
    System.out.println("Done!");
    return (x*x);
}

public static void main(String [] args) {
   System.out.println(square(4));
}

you can't replace square(4) with its value (16) because it would change the meaning of the program - it would no longer print Done! to stdout. In Haskell it is impossible for functions to have side effects like printing to stdout or changing memory locations, so referential transparency is enforced.

Note that with this meaning of pure, Lisp is not a pure functional language, as its functions can have side effects (if you want to get picky, Haskell isn't a pure functional language because of the existence of unsafePerformIO, but everyone knows that you are consigned to one of the nastier circles of hell if you ever use that function).

Of course, it is always possible to adopt a pure style in an impure language, and many programmers will do this in order to make reasoning about their programs easier. It's just that referential transparency isn't enforced by the compiler, as it is in a pure language.

Examples of purely functional languages include Haskell, Clean and Miranda. Examples of impure functional languages include OCaml, F# and Scheme.

Object Oriented Programming

When people talk about Smalltalk or Ruby being a pure object-oriented language, they mean that there is no distinction between objects and primitive values. In Smalltalk and Ruby, values like integers, booleans and characters are also objects, in the sense that they can receive messages (Smalltalk) or have methods (Ruby). For example, you can do

1.to_s

in Ruby, i.e. call the method of the integer 1 that converts it to a string. Compare this with an 'impure' OO language like Java, in which there are objects (which are instances of classes, and can have methods, etc) and primitive values (e.g. int, double, bool, which can't have methods).

When an OO language is pure, people often say that "everything is an object", which isn't strictly true (for example, an if statement isn't an object) but is is true to say that "every value is an object".

Examples of pure object oriented languages include Ruby and Smalltalk. Examples of impure object oriented languages include Java and C++.

Chris Taylor
  • 46,912
  • 15
  • 110
  • 154
  • Just out of curiosity, what makes C# an impure object-oriented language? As far as I know, it does have a unified type system (everything is an `object`), so `0.ToString()` is a valid expression. – Jules Jul 24 '12 at 13:44
  • 3
    I was under the impression that value types in C# could not have (non static) methods, but after a little research that appears to be false. Thanks for the correction! – Chris Taylor Jul 24 '12 at 14:47
  • 1
    That description makes Haskell sound useless. You say "In Haskell it is impossible for functions to have side effects like printing to stdout or changing memory locations". This is only true in the sense that that doing so is part of the return value (the IO monad), and so isn't technically a side effect. But you make it sound like you can't print to stdout in Haskell, which is not true, you can. – Tim Aug 10 '12 at 16:29
  • 3
    *This is only true in the sense that that doing so is part of the return value (the IO monad), and so isn't technically a side effect.* -- it's not 'true in the sense of X', it's just 'true'. Functions *don't* have side effects. Maybe it's sometimes helpful to think of a function that returns an IO action as a function with side effects, but it's not. It's a pure function that returns an IO action. You *can* print to stdout, but you don't do it by calling a function, you do it by executing an IO action. – Chris Taylor Aug 10 '12 at 20:28
  • _When people talk about Haskell being a pure language, they mean that it has referential transparency_ - not quite; see e.g. https://stackoverflow.com/q/4865616 . – atravers Oct 03 '21 at 03:31
7

The word "pure" in functional language is arguably "Stateless", the output does not depend on states.

For imperative languages, you assign x := 0, but you can reassign the value of variable x later. The value of x depends on the current state.

But for pure functional languages, if f(x) = 1, then the result will always be 1.

Ronson
  • 479
  • 2
  • 4