Skip to main content
purity and immutability are not goals of themselves, but follow from referential transparency.
Source Link
amon
  • 135.9k
  • 27
  • 295
  • 386

Functional programming encompasses a number of techniques, depending on who you ask:

  • higher-order functions,
  • closures,
  • prefer immutabilityreferential transparency, and
  • makemaking state explicit / prefer pure functions.

The value of using pure functions is that these functions can be composed, without side effects leading to unexpected behaviour. Their behaviour is characterized solely by their inputs and outputs. As such, they are easier to reason about. Ideally, state should not be an implicit global context, but an explicit parameter/return value of a function.

So far, the theory. In practice, the vast majority of functional languages including the Lisp and ML families is also imperative: State may be implicit in the control flow, and statements may have side effects. It is not necessary to always make the state explicit. Other aspects of functional programming still apply.

The odd one is Haskell. Because Haskell uses lazy evaluation, expressions are not evaluated in any particular order. If expressions have side effects, the order of these effects is unspecified. Therefore, Haskell introduces the IO monad and the State monad to encode dependencies between effects on a type-system level. These monads allow a computation to be forced even when the result is thrown away or when the operation has no clear result.

In languages without lazy evaluation, the need for state or IO monads is greatly reduced. In fact, most languages do not have a sufficiently expressive type system to encode these monads. It is therefore wrong to see Haskell-specific techniques as the only way to be truly functional. Mixing functional and imperative techniques is perfectly fine.

Functional programming encompasses a number of techniques, depending on who you ask:

  • higher-order functions
  • closures
  • prefer immutability
  • make state explicit / prefer pure functions

The value of using pure functions is that these functions can be composed, without side effects leading to unexpected behaviour. As such, they are easier to reason about. Ideally, state should not be an implicit global context, but an explicit parameter/return value of a function.

So far, the theory. In practice, the vast majority of functional languages including the Lisp and ML families is also imperative: State may be implicit in the control flow, and statements may have side effects. It is not necessary to always make the state explicit. Other aspects of functional programming still apply.

The odd one is Haskell. Because Haskell uses lazy evaluation, expressions are not evaluated in any particular order. If expressions have side effects, the order of these effects is unspecified. Therefore, Haskell introduces the IO monad and the State monad to encode dependencies between effects on a type-system level. These monads allow a computation to be forced even when the result is thrown away or when the operation has no clear result.

In languages without lazy evaluation, the need for state or IO monads is greatly reduced. In fact, most languages do not have a sufficiently expressive type system to encode these monads. It is therefore wrong to see Haskell-specific techniques as the only way to be truly functional. Mixing functional and imperative techniques is perfectly fine.

Functional programming encompasses a number of techniques, depending on who you ask:

  • higher-order functions,
  • closures,
  • referential transparency, and
  • making state explicit.

The value of using pure functions is that these functions can be composed, without side effects leading to unexpected behaviour. Their behaviour is characterized solely by their inputs and outputs. As such, they are easier to reason about. Ideally, state should not be an implicit global context, but an explicit parameter/return value of a function.

So far, the theory. In practice, the vast majority of functional languages including the Lisp and ML families is also imperative: State may be implicit in the control flow, and statements may have side effects. It is not necessary to always make the state explicit. Other aspects of functional programming still apply.

The odd one is Haskell. Because Haskell uses lazy evaluation, expressions are not evaluated in any particular order. If expressions have side effects, the order of these effects is unspecified. Therefore, Haskell introduces the IO monad and the State monad to encode dependencies between effects on a type-system level. These monads allow a computation to be forced even when the result is thrown away or when the operation has no clear result.

In languages without lazy evaluation, the need for state or IO monads is greatly reduced. In fact, most languages do not have a sufficiently expressive type system to encode these monads. It is therefore wrong to see Haskell-specific techniques as the only way to be truly functional. Mixing functional and imperative techniques is perfectly fine.

Source Link
amon
  • 135.9k
  • 27
  • 295
  • 386

Functional programming encompasses a number of techniques, depending on who you ask:

  • higher-order functions
  • closures
  • prefer immutability
  • make state explicit / prefer pure functions

The value of using pure functions is that these functions can be composed, without side effects leading to unexpected behaviour. As such, they are easier to reason about. Ideally, state should not be an implicit global context, but an explicit parameter/return value of a function.

So far, the theory. In practice, the vast majority of functional languages including the Lisp and ML families is also imperative: State may be implicit in the control flow, and statements may have side effects. It is not necessary to always make the state explicit. Other aspects of functional programming still apply.

The odd one is Haskell. Because Haskell uses lazy evaluation, expressions are not evaluated in any particular order. If expressions have side effects, the order of these effects is unspecified. Therefore, Haskell introduces the IO monad and the State monad to encode dependencies between effects on a type-system level. These monads allow a computation to be forced even when the result is thrown away or when the operation has no clear result.

In languages without lazy evaluation, the need for state or IO monads is greatly reduced. In fact, most languages do not have a sufficiently expressive type system to encode these monads. It is therefore wrong to see Haskell-specific techniques as the only way to be truly functional. Mixing functional and imperative techniques is perfectly fine.