I was struggling with Mathematica in grad school (it's bread and butter for theoretical physicists, since it is particularly good at symbolic math, and good enough for ancillary numerics, plotting, etc). My previous programming experience included C/C++, Python (numpy/scipy), Matlab/Scilab/Octave, and somehow, getting Mathematica to do things seemed like pulling teeth.
Incidentally, around the same time, I was exploring lambda calculus and "Learn You a Haskell" [1] for fun. Suddenly, at some point, several things about the declarative paradigm just clicked, and within a space of a few days, I went from struggling against Mathematica and hating the experience, to appreciating it's elegance and enjoying getting things done with it! For functional programming in Mathematica, see [2, 3] and the fact that it gives you access to the expression tree in a structured manner means that some really cool stuff becomes really easy!
Later, I learned that Mathematica's computation model is based on pattern matching and term rewriting. I don't know enough computing theory to disambiguate functional/rewriting/declarative, but I find it very satisfying to write code in roughly that style -- it feels clean and understandable. See Yann Esposito's write-up [4] for a fantastic illustration of this.
In that illustration, Yann takes a simple problem with an obvious procedural solution, and proceeds to rewrite it step-by-step in ten versions, each time making it slightly more modular. The modularity and flexibility of the later versions is breathtaking in its simplicity!
Incidentally, around the same time, I was exploring lambda calculus and "Learn You a Haskell" [1] for fun. Suddenly, at some point, several things about the declarative paradigm just clicked, and within a space of a few days, I went from struggling against Mathematica and hating the experience, to appreciating it's elegance and enjoying getting things done with it! For functional programming in Mathematica, see [2, 3] and the fact that it gives you access to the expression tree in a structured manner means that some really cool stuff becomes really easy!
Later, I learned that Mathematica's computation model is based on pattern matching and term rewriting. I don't know enough computing theory to disambiguate functional/rewriting/declarative, but I find it very satisfying to write code in roughly that style -- it feels clean and understandable. See Yann Esposito's write-up [4] for a fantastic illustration of this.
[1]: http://learnyouahaskell.com/
[2]: https://reference.wolfram.com/language/guide/FunctionalProgr...
[3]: https://mathematica.stackexchange.com/questions/163992/what-...
[4]: See Section 3.1 (you don't actually have to know any Haskell to get value from this example): http://yannesposito.com/Scratch/en/blog/Haskell-the-Hard-Way...
In that illustration, Yann takes a simple problem with an obvious procedural solution, and proceeds to rewrite it step-by-step in ten versions, each time making it slightly more modular. The modularity and flexibility of the later versions is breathtaking in its simplicity!