This question of making Nim more functional seems to come up from time to time, so I thought it might be useful to summarize "the state of Nim as to being a functional language", at least as I see it...
**History** Nim's background story would seem to in no way include any back trace to what have been called "functional languages" of the past such as Lisp/Scheme/etc. The reason for Nim's existance would seem to be to build a better C/C++, which it does quite well to the point where I avoid using any "imperative" language other than Nim other than to learn enough about them so as to compare features and abilities. As a better C/C++, it shares some common goals with quite a few other newish languages such as Zig, the V language, and so on all the way up to Rust, but having learned something about all of these, I reject them in favor of Nim because none of them offer the features I want and they either reject automatic memory management altogether or use a very complex system of memory management that makes them onerous to work with (Rust, I'm looking at you, and you can't even break cycles automatically). **The Tendencies of Modern Languages to be "Safe"** Modern **imperative** languages have adopted some functional programming precepts in order to enable writing safer code, so most new languages have some way of expressing that a variable should not be mutated (Nim's `let`; other language's `const`, etc.), some control or indication of what functions are or are not side effect free (Nim's `strict func`), support for anonymous functions (lambda's), support for closure functions (which may be anonymous - which Nim has), some form of support for Algebraic Date Types (Nim's variadic objects) and the means to pattern match based on these types (which Nim can do in a limited way). In order to be more "safe" Nim has in the works a version of Haskell's Type Classes and Rust's `Trait`'s called `Concept`'s and a version of Rust's control of mutation called `View`'s that are intended to be easier to use, but they are "opt-in" features and will have to be for the foreseeable future ax they are experimental and no libraries use them **Functional Things that Imperative Languages Lack** However, some features that functional programmers would expect to be able to use such as full type inference and currying/partial application of function arguments (very difficult to implement in current Nim due to function overloading), the ability to eliminate imperative loops by using tail call recursive functions (difficult but not impossible in the current Nim as Nim mostly compiles directly to C or C++ which do not guarantee tail call safe code, so Nim would have to emit code that forces C/C++ to be tail call safe). Also, as long as a language such as Nim accepts mutable (`var`) function arguments and can return `var`/`lent` values, it is not side effect free and it is no use pretending that it is. Another thing that many imperative languages lack, especially those that restrict control of variable bindings in the interest of "safety" is recursive references to variable definitions, even when such recursive definitions can be shown to be safe; in Nim and many other imperative languages, we can only do this (when necessitated by the algorithm) by forward defining a mutable variable and then assigning it with the recursively derived final definition but that breaks being "purely" functional. I have read some proposal from some years ago to make Nim more functional (can't find it now), but it degraded into just using a package of templates and macros that would prevent the use of `var` arguments, provide better versions of pattern matching (of which there are template/macro packages that do this), and so on, and this proposal died on the vine and hasn't gone anywhere, or at least that I am aware. **Assumptions about Functional Programming that are Incorrect** There are two things that are commonly assumed about functional languages that aren't necessarily true, as follows: 1. That all functional languages need to have Garbage Collection (GC); this is no doubt because most if not all functional languages currently use (GC) from Lisp all the way to Haskell, including everything between, although some of those languages have had GC forced on them due to the platform on which they run (Clojure/Scala/F#/etc.). There is no reason that a functional language could not use automatic reference counting as in Nim's Arc and include cyclic reference breaking as in Nim's Orc (or something like it). 2. That functional languages are slow. It's true that functional implementations are sometimes slower than more imperative implementations but that is more the tendency of functional programmers to overuse list processing rather than using recursive function "loops" for time critical code, and to the tendency for functional programmers to not consider the time implications of constant allocation/deallocation of and wrapping/unwrapping of functional "containers", which overhead can often be avoided and/or eliminated by a fully optimizing functional language compiler but not always. An example of this being done is my Haskell contribute to [the Software Drag Race](https://github.com/PlummersSoftwareLLC/Primes/blob/drag-race/README.md), where the only reason that my Haskell contribution is slower than my Nim contribution is that the Haskell LLVM code back end doesn't emit code that is compatible with "auto-vectorization" to SIMD operations where the C code that Nim emits is compatible with such optimizations. **Attitudes Against Functional Programming in Nim** The general attitude seems to be as @Araq's "if we want functional programming, we know where to find Haskell", along with the above two incorrect assumptions about functional languages in general, and the common acceptance that if one wants to write purely functionally in Nim, one can do it by discipline and by using template/macro packages that would help enforce those disciplines. However, I don't know that is correct in that, in order to be efficient, functional paradigms need to be optimized with some compiler support. **Final Observations** It is my feeling that a lot of the recent work in imperative languages regarding "safety" as in Rust's lifetimes and mutation control/Nim's views, wouldn't be necessary or would be so much simpler if the languages were purely functional in the first place, as when everything appears to be immutable, we don't have to control mutation other that for some carefully sequenced mutation wrapper code that can all be elided away when compiled (for instance, `IO`/`ST` monad control of mutation). It is true that all system code can't be written in a purely functional language, as even the Haskell compiler source includes quite a bit of C code for the "primitive" operations, but it is my feeling that many of the types of errors that plague Nim currentlly could have been avoided if the "outer" code had been more functional. It is still true that Haskell has its fair share of issues in the code base, but part of this is that Haskell is mostly an experimental academic language for investigating extremely advanced functional concepts; I don't propose that a new functional layer be like that at all as to its complexity (I have spent about 10 years off and on learning Haskell and still regard myself at only an intermediate level) but would rather use a purely functional language like Elm as a model with about three or four extensions for things it can't currently do, but with C/C++ output as in Nim's. In Elm, there is no talk of "Functor's", "Applicative's", and "Monad's" although it uses all of those, just not named that way. For instance, in Elm a monad is a container that supports a very specific definition of the "andThen" (which is actaully a "bind") function with examples such as the `Task` type which is actually something like Haskell's `IO` monad except that it also has some elements of the `Either` monad in that it can indicate success/failure. Functional langauges don't have to be complicated in that Elm is so simple that it can be learned in a few days to a week by an experienced programmer, and is used to teach school children of as little as age about ten. Elm only has about 20 keywords, a few more than that operators, and all of those can be learned gradually due to its nature. It lacks some desirable features such as templates/macros that could be of use for advanced purposes, but there is likely a clean way way to implement those; in addition it also should have some form of Type Classes/Families/Traits for more extensive type use as the current system has some deficiencies that will restrict its progress as a language. The above is the kind of purely functional language I would like to see as a front end to Nim used as a build chain to generate C/C++... There must be others out there that feel as I do? There would appear to be two approaches to be able to use Nim as a code generator but enable writing more functional code, as follows: 1. To have a package that provides some tools as a form of DSL templates/macros that cause Nim to do what is necessary to convert that DSL to code as was already proposed and not continued; I feel it would be quite difficult to accomplish all of the goals within the Nim framework, especially doing things like type inference, etc, but perhaps others more proficient at templates/macros than eye could give a better opinion. 2. Build a new language that uses Nim as a back end, using the functional code from a language such as Elm to emit Nim code that would be converted to c/C++ by Nim. The reason for using Nim as an intermediate step is to avoid having to solve many of the problems that Nim has already solved in providing closure functions, a great non-GC memory management system, nested functions, etc., etc...