4

Assignment should avoided in functional programming, but in clojure we often use let.

Is let just a way of being practical or is assignment not the same as using let? Should we not avoid assignment in functional programming?

David
  • 2,926
  • 1
  • 27
  • 61
  • 1
    "Assignment should avoided in functional programming" citation needed. Haskell, OCaml, Clojure, Erlang... every functional language I've programmed in or ever even toyed with had a mechanism for binding a name to a value. All the non-functional ones too for that matter. – Jared Smith Jul 05 '22 at 20:50
  • 3
    While maybe not strictly speaking a duplicate, [this question](https://stackoverflow.com/q/27830405/3757232) and its accepted answer might shed a little light for you. Because `let` bindings in Clojure are not mutable variables. – Jared Smith Jul 05 '22 at 20:57
  • 1
    This question is excellent, and IMO perfectly clear. It's a basic confusion common among beginners in functional programming. I had the same confusion when I started. Please allow people to answer. – Ben Kovitz Jul 09 '22 at 05:20

2 Answers2

9

Mutable state is generally against the core concepts of functional programming.

However, let merely binds a name to a value. If that value is immutable, there's no reason for it to be inconsistent with functional programming ideals.

Chris
  • 26,361
  • 5
  • 21
  • 42
  • there's value mutation (like changing an element in an array), and there's binding mutation (i.e. resetting a variable). Does Clojure have both? -- In Scheme, any variable in scope can be mutated with `set!`. – Will Ness Jul 09 '22 at 08:05
4

One cannot say that assignment in general is against the idea of functional programming (FP).

A def expression is an assignment as well as a let expression. Giving names to things and procedures/functions is a mean of abstraction - and programming means to a big part applying abstraction on recurring problems.

Imperative style misuses assignments for mutation and thus creating/maintaining/mapping of (global) states. Mutation is not possible without assignment. So FP aims against such kind of mutations not assignments per se.

Actually FP is not even aiming against mutation per se. Even in functional languages mutation is in some situations required for performance reasons.

There is harmless mutation - mutation of variables which are anyway never ever again referred to for the rest of the program - e.g. because they appear only within a certain scope (e.g. within the scope of a let expression or a function definition). I tend to call them 'benign' mutations. And there is harmful mutation - mutation of variables to which later is referred to - mutation of variables which go on living outside the scope they were created in - thus constituting some kind of an unlimited state. I call them 'malign' mutations.

Actually it is also wrong to say FP avoids state alltogether.

Closures are actually constituting states in FP. Through closures functions can refer to hidden variables which keep a "memory"/state between different function calls. But they are applied in a very controlled manner.

Probably this is why defining FP is so difficult. Very quickly one has oversimplified something thereby causing more confusion than clarifying things.

Gwang-Jin Kim
  • 9,303
  • 17
  • 30