Chat Notebook
Insert Chat Cell
Chat Settings

MIT Future Tech Lab - Introduction to Functional Programming in WL

Phileas Dazeley-Gaist

Teasers: Example Functional Style Programs

Here are a few example WL programs, written in a functional style.
By the end of this presentation you’ll have new intuitions about how these programs achieve what they do, and how they manage to be so concise.
Put some text in 8 nested rotated frames:
Out[]=
Plot the bifurcation diagram of the logistic map:
Out[]=
1
2
3
4
0.2
0.4
0.6
0.8
1.0
Sierpiński gasket using text:
Out[]=
o,
o
o
o
,
o
o
o
o
o
o
o
o
o
,
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
,
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
,
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o

Get OpenAI’s Whisper to transcribe a recording:
Out[]=
In this, probably its true aspect, the airport is not a prelude to travel, not a place of transition. It is a stop, a blockage, a constipation. The airport is where you can't go anywhere else. A non-place in which time does not pass and there is no hope of any meaningful existence. A terminus. The end. The airport offers nothing to any human being except access to the interval between planes.
Make a list of connections between a selection of European capital cities and Rome:
Out[]=

Vienna

Rome
,
Paris

Rome
,
San Marino

Rome
,
Ljubljana

Rome
,
Bern

Rome
,
Vatican City

Rome
,
Prague

Rome
,
Berlin

Rome
,
Budapest

Rome
,
Vaduz

Rome
,
Bratislava

Rome
,
Andorra la Vella

Rome
,
Brussels

Rome
,
Luxemburg

Rome
,
Monaco

Rome
,
Madrid

Rome
,
Zagreb

Rome

Illustrate the saying: “All roads lead to Rome” with a map of driving directions from a selection of European Capitals to Rome:
Out[]=
Construct a 4-hop graph of word synonyms starting from the root node “bug”:
Out[]=

Introduction to WL

Before we discuss functional constructs, here are a few keys you’ll need to understand how to read Wolfram Language code:

Symbolic Expressions

1
.
Wolfram Language is a symbolic programming language. Everything in Wolfram Language (other than real numbers and integers) is a symbolic expression.
2
.
All symbolic expressions have the same fundamental structure: head[arguments].
For example:
The head of an expression is analogous to the notion of “type”, though in a more human sense. It’s not quite the same as type far as the compiler is concerned.
For example:
Because WL is built up from symbolic expressions, an undefined variable is just a symbol with no other definitions.
For example:
So what happens when we try to compute with an undefined variable?

Variable Assignment and Function Definitions

Set (=)

Variable assignment using Set:

SetDelayed (:=)

Delayed variable assignment using SetDelayed:

ClearAll

Make the Wolfram Kernel forget a definition using ClearAll:

Function definitions

SetDelayed is often used to define functions using pattern matching.
Define a function:
Clear the function definition:

Pure (Anonymous) Functions

Pure functions are also known as anonymous functions or lambda expressions.
Make a pure function for adding 1:
If a pure function is given as the head of an expression, the function is applied to the arguments:
Here is a function of several arguments:
Another way to write the above function is:
(The examples in this subsubsection are from The Wolfram Language: Fast Introduction for Programmers)

Further Reading/Learning Resources

◼
  • The Wolfram Language: Fast Introduction for Programmers
  • ◼
  • Elementary Introduction to Wolfram Language: Wolfram U MOOC
  • Introduction to Functional Programming

    Wolfram Language is a multi-paradigm programming language. It supports procedural programming and OOP, but is designed to encourage programmers to code in a functional style.
    Functional programming in WL typically results in more performant code.

    What is Functional Programming?

    1
    .
    Ideal Functional programming:
    ◼
  • Writing programs using only mathematical functions: (a function is a map between sets). A function called twice with the same arguments should return the same result.
  • ◼
  • No concept of state. No variable assignments ever, and no reading values from the environment.
  • ◼
  • BIG CAVEAT: It turns out that in a purely functional language (without the notion of state) you can’t really do anything.
  • 2
    .
    Functional programming as a programming style:
    ◼
  • No real-world programming language is purely functional: It would be better to think of functional languages as languages that strive to be as functional as possible.
  • ◼
  • Functional programming languages encourage programmers to code in a functional style:
  • ◼
  • Writing programs with functions, higher order functions (functions that take other functions as arguments), and compositions of functions.
  • ◼
  • Being as clear as possible about the side effects, failure cases and misbehaviours a function may have.
  • ◼
  • Using functional constructs and design patterns when possible.
  • Guiding Principles of Functional Programming

    ◼
  • Make functions the building blocks of your programs.
  • ◼
  • If a process is being reused throughout a program, it should be its own function.
  • ◼
  • If a process is large enough that it would be cumbersome to rewrite, and there is a chance you might like to reuse it later, it should be a function.
  • ◼
  • In WL, you are encouraged to implement function polymorphism using overloading (let me know if you’d like to see an example).
  • ◼
  • Minimise the number of variables you define, and limit side-effects by avoiding altering variables beyond the scope of any given function.
  • ◼
  • Side effects are behind all sorts of common and some more obscure and creative bugs in procedural and OOP programs.
  • ◼
  • If possible, a function called twice with the same arguments should return the same result (in practice, we break this rule all the time).
  • Reading Functional Code

    Read code from the inside out:
    ◼
  • Since programs are functions definitions + function compositions, whenever you use a higher order function, the arguments of the function have to be evaluated before the function can be evaluated.
  • ◼
  • In practice, this means that when you have many function compositions (e.g. f[g[h[x]]]) , the code can best be made sense of by reading from the deepest point outwards.
  • Bonus note: You can write function calls using brackets, prefix, or postfix notation, depending on your preferred style:

    Perks of Functional Programming

    ◼
  • Functional programming is often more declarative than procedural and OOP programming styles.
  • ◼
  • Functional style programs make it easier to debug, as issues are often easier to trace to misbehaving functions.
  • ◼
  • In functional programming (when your function is a true function in the mathematical sense), you can always safely run two functions in parallel because there are no side effects. There are no ways for the functions to interfere with each other.
  • ◼
  • In practice, you should program using a mix of paradigms depending on the nature of the task at hand. Functional and OO and procedural code really all have their own advantages, and can be combined.
  • Further Reading/Learning Resources

    ◼
  • Influential classic paper: Why Functional Programming Matters (Hughes, 1990)
  • ◼
  • Video Lecture: Why Functional Programming Matters • John Hughes • 2017
  • ◼
  • Erik Meijer: Functional Programming
  • ◼
  • Alan G. Isaac: Introduction to Functional Programming
  • Functional Constructs in Wolfram Language

    The following are some really common functional operations.
    These may be a lot to take in at once, so don’t feel pressured to remember these precisely.

    Function

    Array and Table

    Thread

    Maps (Map, MapApply, MapThread)

    Map

    Apply a function to an expression at level 1:
    Apply a function to an expression at level 2:
    Apply a function to an expression at levels 1 through 2:

    Comap

    Apply a list of functions to an input:

    Apply

    MapApply

    MapThread

    Map a function over corresponding arguments from two lists:

    Nests (Nest, NestList, NestTree, NestGraph)

    Nest

    NestList

    NestTree

    NestGraph

    Generate a k-hop network of related WL functions rooted at Nest:

    Folds (convenient for avoiding state)

    Pattern Matching

    Match any single expression:
    Match any single expression with the head Integer:
    Match any even number:
    Match any number that is even and evenly divisible by 3:
    Define a list elements:
    List cases of Graph elements in the list:
    These are some very simple examples, but the pattern matching rabbit hole goes deep.

    Query, Dataset, and Tabular

    Use Query to process data:
    Represent hierarchical or tabular data in WL:
    Use Query implicitly to apply functions at different levels of the datasets.
    As of Wolfram Language 14.2 (released in January), we also have a new construct called Tabular which is designed to make traditional data science pipeline operations (wrangling, reshaping, or summarising tabular data) easy:

    If anyone asks about monads

    A monadic pattern is a design pattern in functional programming that allows for operation chaining while managing context and control flow. It takes advantage of the properties of an object found in category theory: the monad.
    (In practice monads in functional programming are a little different from the ones found in category theory.)
    “Simply put, monads provide a generalized interface to sequential computation. Hence monads are a way to impose or enforce a certain regular behavior in building computations.” (Anton Antonov - Mathematica StackExchange)

    In Functional Programming, What’s a Monad, Really?

    First, let’s define the two functions needed to make a monad:
    Example:
    Example:
    Okay, now let’s define some functions f and g that satisfy the bind condition:
    For something to be a monad, in addition to implementing unit and bind, it has to follow some rules:

    Monadic Code in WL

    Demonstrate that the monad laws are satisfied:
    Example of some monadic functional code:

    Further Reading/Learning Resources

    ◼
  • A monad is a design pattern in which
  • My favourite ones:
    ◼
  • What The Heck Is A Monad
  • ◼
  • Wikipedia: Monad (functional programming)
  • ◼
  • An Intuitive Introduction to Monads in Under 10 Minutes
  • ◼
  • Brian Beckman: Don't fear the Monad
  • Some more:
    ◼
  • StackExhange: How and why to use monadic programming in Mathematica?
  • ◼
  • A quote from this: “Simply put, monads provide a generalized interface to sequential computation. Hence monads are a way to impose or enforce a certain regular behavior in building computations.”
  • ◼
  • The Absolute Best Intro to Monads For Software Engineers
  • ◼
  • What the heck are monads?!
  • ◼
  • Monads. A 5-minute introduction.
  • ◼
  • StackExchange: Does every Symbol in Mathematica induce a monad?
  • ◼
  • Anton Antonov - Monad code generation and extension