I was actively avoiding the obviously imperative functions, though. Not sure why. That is, I could have simply said that the existence of all of the functions that end in exclamation points shows the language is imperative.
(define x 3)
(display x)
(set! x (add1 x))
(display x)
is about as imperative as they come, by my definition. And not a begin in site. (let* ((a 1) (b a))
(+ a b))
is an abbreviation for (let ((a 1))
(let ((b a))
(+ a b))))
which, in turn, is a syntactic sugar for ((lambda (a)
((lambda (b)
(+ a b)) a)) 1)
There is no "assignment", only lexicaly scooped bindings, which are "stateless" and "declarative".Looping constructs in Racket are just syntactic sugar - layered macros, based on what they call "contracts", I suppose.
In CL looping constructs are micro-DSLs.
Simply put, functional is not necessarily the opposite of imperative.
I took to googling to see if someone had made my point better already. The best I found quickly is this[1]. It is a good read. As it points out that we are most likely both stuck on different numbers in the "opposite of imperative" definition world.
I will say that throwing out mutability with the bathwater is perhaps the single most frustrating thing with most functional advocacy.
[1] https://existentialtype.wordpress.com/2013/07/18/what-if-any...