The VikiD Truth

Knowledge base / Computing

Read This! | Algorithms | AssemblyLanguage | BASH | C-Programmming | Computer Security | Databases | Emacs | Exploitation | Functional Programming | Firewalls | Git | Javascipt | Julia | Social Engineering | Picolisp | Pharo Smalltalk | Linux | Python | Operating Systems | Machine Learning | Metasploit | Open Data Science | Networking | Machine Learning |Scheme | Unity | vim | Web Development

Functional Programming

Functional Programming

Here is the truth functional programming keeps repeating until it sinks in: if you stop changing things, most of your bugs disappear. You write functions that take values and return new values, and you build programs by composing them.

What it is, in plain words

Functional programming (FP) is a style – and in its pure form, a paradigm – that treats computation as the evaluation of mathematical functions. Its habits:

Languages that push you hard in this direction: Haskell, PureScript, Elm, OCaml, F#. Languages that make FP pleasant and practical: Scheme, Racket, Common Lisp, PicoLisp, Clojure, Erlang/Elixir, Rust, Kotlin, and modern JavaScript / Python.

Why it matters

Mutable state + concurrency = pain. Mutable state + large teams = pain. FP doesn’t eliminate state – a useful program must interact with the world – but it pushes state to the edges and keeps the core of the program predictable and testable. Even if you never write Haskell, the habit of asking “can this be a pure function?” improves every language you touch.

An everyday analogy: recipes versus a shared whiteboard

An imperative program is a crew sharing one whiteboard: anyone can erase and rewrite a number, and you spend meetings asking who changed it. A functional program is a kitchen of recipes: each recipe takes ingredients and produces a dish; recipes don’t overwrite each other. If the cake is wrong, you look at one recipe, not at every hand that held the chalk.

flowchart LR
  A[data] --> F1[pure f] --> B[new data]
  B --> F2[pure g] --> C[new data]
  C --> E[effect: save / print / send]

A hands-on example

The same idea in three languages. Sum of squares of the even numbers up to n:

Haskell (pure, lazy):

sumOfEvenSquares :: Int -> Int
sumOfEvenSquares n =
  sum [x * x | x <- [1..n], even x]

PicoLisp (the joy of small Lisp):

(de sum-of-even-squares (N)
   (sum '((X) (* X X))
      (filter '((X) (=0 (% X 2))) (range 1 N)) ) )

(sum-of-even-squares 10)   # -> 220

JavaScript:

const sumOfEvenSquares = n =>
  Array.from({ length: n }, (_, i) => i + 1)
    .filter(x => x % 2 === 0)
    .map(x => x * x)
    .reduce((a, b) => a + b, 0);

Python:

def sum_of_even_squares(n: int) -> int:
    return sum(x * x for x in range(1, n + 1) if x % 2 == 0)

Notice what’s absent: no mutable accumulator you manage yourself, no index variables, no chance of an off-by-one in a loop. (sum/reduce hides the accumulator in a well-tested place.)

Core vocabulary

FP is a spectrum

You don’t have to go full Haskell. Useful waypoints:

  1. Write pure functions where you can; push I/O to the edges.
  2. Prefer immutable data (const, persistent collections).
  3. Reach for map/filter/reduce before for.
  4. Model absence and failure with Option/Maybe and Result/Either, not nulls and thrown exceptions.
  5. Learn a real FP language for a month – it permanently changes how you write the others.

Common misconceptions

Connections

Last edited · 2 revisions

Tags: #Computing