I would like to start, here, a low-key but potentially useful collection of Mathematica "best practices" and "programming patterns". The emphasis would be on pragmatics, obviously. Please chime in as the spirit moves you.
In previous posts I've expressed frustration at the lack of collections of such things. In many ways my uses of Mathematica are still naive, but I've found the following useful, especially at addressing what I see as a challenge associated with functional programming. To make a long story short I am coming to love the functional programming paradigm for software development but find it not always easy to overcome the resulting readability challenge. Since I don't have a magic bullet with which to overcome this challenge here are three very small ideas that have helped me.
Use the prefix operator - @ - where-ever possible to call functions - as in f@x, instead of f[x] - so as to eliminate the use of square brackets. When a functional programming line has concatenated, or nested, many levels of functions this simple expedient can improve readability to a surprising degree. Further, using f[#,<argumentList>]&@x, in place of f[x,<argumentList>], keeps the arguments close to the function with which they are associated. When functions are concatenated, or nested, many layers deep, the visual connection between a function and its arguments can be difficult to establish. Again, a very small thing, but one that helps me understand code I come back to later.
Use programming patterns: Yes, this is obvious, but, in my opinion, little articulated with Mathematica. For example, a simple one I now use is Thread[Join[<a bunch of lists>]. I stumbled onto this and now use it all the time to combine the results of separately derived lists, often for displaying intermediate results. (One question here is whether there is a single command that does the same thing - without using Transpose.)
Avoid intermingling procedural and functional code: The most difficult debugging challenges I've faced recently have been associated with code that is a mixture of procedural and functional commands. I don't have a theoretical explanation, but for me the observation is clear. One interpretation is that such code reflects laziness on my part - I don't have the mental energy or insight to create a purely functional solution - so I satisfice by, for instance, putting a procedural wrapper around some functional code. The last such debugging challenge was a ";" where there should have been a "::". The latter was introduced accidentally during editing; the resulting code executed but of course didn't do the right thing. I rarely have to resort to divide-and-conquer debugging in Mathematica, but I did in this case, and it was tedious.
I look forward to submissions from this community - simple, or sophisticated.
I know what you mean. When I looked at code in Michael Trott's GuideBooks I'm often amazed at what he does in so little code.
No one with experience disagrees with this.
The deeper and much more difficult question is the general software engineering challenge - how do you do decide what to do NEXT, and how do you decide how to balance local vs. global simplicity. To your point, it's good to have something that runs, as early as possible, and for all there right reasons. But when I watch skilled Mathematica programmers they almost all proceed bottom-up and inside out; they start out quite simply and then - using the functional paradigm - string thing together up and down stream from this. Often the result is incomprehensible, UNLESS one saw it being put together.
I think it's better to, especially when first developing a calculation, to write a larger number of simpler functions, rather than a small number of complicated functions, especially for debugging purposes. This goes along with the idea of using functional programming whenever possible.
Excellent, thank you!
I've used Stack Exchange for some details, such as dealing with type conversions between Excel and Mathematica, but missed the general stuff completely.
I look forward to digesting it.
This might be helpful, though it isn't hosted here.