@Giulio, I don't know how I missed this when you originally posted it. Thanks for this post.
One thing I observe here is the heavy reliance on internal and undocumented functionality. I mentioned before how this is basically unavoidable for package development (think e.g. Internal`WithLocalSettings
).
There's GeneralUtilities, System`Private`Arguments
, several Internal`
context functions for verifying types, etc.
Since these are not documented, they are hard to discover. If I do discover them, I cannot be sure about how to use them. If I do use them, and they break, I can't get support, and my bug report might be rejected (so why even bother sending it?)
Of course, I still do use some of these because they are essential to package development. But the situation demonstrates well how WRI basically ignores (potential) package developers. There are very few quality packages that do not come fro WRI directly, and this is surely the main reason.
Another thing I observe is that you construct several layers around the basic function. How will this affect performance? This function may later be used to implement other functions, which are then used to implement yet other functions, and all this checking overhead adds up. Paying attention to the error checking overhead is a critical aspect of package development.
I notice that you use VectorQ[..., Internal`RealValuedNumericQ]
. What you did not mention that this is basically the only right way to check if the input is a real vector because it won't unnecessarily check every element of packed arrays, and thus will perform very well.
In[371]:= arr = RandomReal[1, 1000000];
In[372]:= VectorQ[arr, Internal`RealValuedNumericQ] // RepeatedTiming
Out[372]= {2.4*10^-7, True}
In[373]:= MatchQ[arr, {___?Internal`RealValuedNumericQ}] // RepeatedTiming
Out[373]= {0.15, True}
I'm not aware of this being documented anywhere in spite of how important it isanother example of how support for package developers is lacking.
Because these things are not documented, they are also more likely to be buggy (since they're not used by as many people). Example: in M10.3 and before (if I recall correctly) VectorQ[{}, Developer`MachineIntegerQ]
returns False
.
The point I am trying to make is this:
If Mathematica is to stay relevant, there must be a vibrant package ecosystem
Support for package development and package developers is currently next to non-existent. We are forced to use internal unsupported functions whose use is either reverse engineered by the community or "leaked" by developers (like you did here). As a consequence, there are few Mathematica packages and many are not of high quality.
Functions that are not important for interactive use but critical for package development should be documented. There should be guides and tutorials on how to solve the basic problems that come up during package development. If there are standard solutions for the most common tasks, and both internal functions and third-party developers use these solutions, then we will see fewer bugs and better performance (both in Mathematica and in third-party packages).
Finally, quality packages should be highlighted and promoted by WRI themselves, both as an example of a healthy package ecosystem and as an example for future package developers to follow. I am not saying this because I develop packages, but because I believe it is critical for the health of Mathematica, a system in which I invested heavily.