In the alum chat for Mirdin, someone posted the following question, "Would it be better to start teaching beginners functional or imperative programming first?"
Pretending for a second that FP and IP are the only choices (they're not), an answer depends on where your beginner comes from.
A meta-pedagogical (teaching about teaching) answer acknowledges that learning starts in a place the learner feels grounded and connects them from there to new knowledge. For example, subitizing is an innate ability. A developmentally normal child can instantly know how many objects are presented, for values up to about 5.
Image: How many dots are there? You just subitized.
From there, you can teach a 5-year-old arithmetic, for example to add, by having them subitize groups of objects alongside numerals and the math symbol +
. This connects their innate notion of quantity to the abstract notion of numbers.
The MIT book and course SICP is a masterpiece in programming pedagogy, and it falls heavily on the FP side. Watch Professor Sussman absolutely rip apart side effects in lecture 5A. But not everybody "gets" this approach easily. Even Hal acknowledges in this Corecursive interview that the FP approach didn't work for everyone:
In the very beginning days, we would teach a sort of short courses for MIT faculty and some of the electrical engineers would just get stuck. "You haven’t showed us how the transistors work". ...People think different ways. Some people have to be grounded on where they’re comfortable and for some people, well, it really is transistors.
Contrast that to somebody who knows what a function is, in the math sense. The machinery of a transistor, of gates, sources, drains, and TTL will be an irritating detail, like multiplying matrices by hand.
So in the dichotomy between introducing FP and IP first, the answer might depend on where the learner is coming from. I learned IP and OOP first because that's what material was available. I was first exposed to FP in college in the form of Scheme. It was disorienting. I couldn't count all the parentheses, let alone grok tail recursion. I wish it could have been presented to me grounded in terms of what I was already comfortable with, for example high school algebra.
I say, introduce multiple programming paradigms early, and ground it in what the learner knows. A fundamental programming skill is to think at multiple levels of abstraction. The Haskell programmer needs to be aware that even monads at some point are just bits in a memory hierarchy, just as it's important for an assembly programmer to know that while register allocation is critical to performance, registers are not really what the program is about.
To close, let's ground this discussion in something we all know. To design a cathedral, the architect needs to know what bricks will be used. To build a cathedral, the bricklayer needs to envision the noble end to which each brick is set down.