Is using undocumented functionality a Bad Idea™?
The two main arguments against using undocumented functions are:
- Your code might not work as expected in future versions;
- Your code might not work as you intended in the current version, because you only have a partial understanding of a function or option that is undocumented.
In the case of Mathematica, though, there is no guarantee that even documented functions will remain unchanged in future versions.
- Even a basic function like
Random
, which was introduced in version 1, was deprecated in version 6 in favour ofRandomReal
andRandomInteger
(and of course,RandomVariate
in version 8). Sometimes the old functions still work, but in other cases the Compatibility Checker detects that code changes are necessary. (See this list of changes in version 6 - the very last line mentions the Compatibility Checker.) This is despite Wolfram's claims and best efforts to maintain forward compatibility of old code. - A search of the documentation provides a large list of symbols that have been obsoleted in recent versions.
- There is even a tutorial describing all the incompatible changes between versions. It only goes up to version 7, so it seems there might be some undocumented changes even here.
The two main arguments for using undocumented functions are:
- Oftentimes they presage the permanent inclusion of that functionality in a future version. For example,
ScalingFunctions
is only documented for charting functions likeBarChart
, but it has been shown to work also forListPlot
andPlot
(but notDateListPlot
). I predict that they will get around to completing (and documenting) this functionality in a future version. (EDIT: In fact, that's exactly what happened in 10.4, even though the online version of the documentation doesn't make it clear that this is new.) - The functionality might be documented, but not completely documented. For example, some option values (say
PlotRegion
) are documented as applying to "graphics functions", without specifying which ones. So the functionality is there, and might well remain stable for several versions.
Mathematica is a complex system with an enormous array of possibilities for the use and abuse of its rich functionality. Even with the massive documentation that exists, there are bound to be some undocumented or incompletely documented functions. Undocumented functions (and options) need to used with some care, but given the usefulness of some of the functionality they offer, it might well be worth the risk.
Problems with undocumented functions
I think that this is one of the things that everyone has to decide on their own. The biggest problem for using undocumented functions is that nobody is responsible for maintaining them, and therefore, it becomes explicitly your responsibility to maintain their use in the piece of software you are building with it. And from this perspective, it is no different from any other piece of code you grab and use, for which:
- no one is responsible
- no source code is available.
It is this combination which makes it unattractive to use, since I would think at least one of the above should hold: either you use unmaintained code, but it is open-source, or you can use commercial code, but it is maintained. So, to put it another way, if I develop some functionality, then, from developer's point of view, I find the general idea of using undocumented functions unattractive, because I have no control over these functions whatsoever.
I certainly don't think that we should promote the widespread use of undocumented functionality on this site. Neither do I think that we should totally exclude such uses from our answers. But the "default" should be "No", I think - speaking of common practices and conventional wisdom. The arguments were partly given by @Szabolcs in comments, I will just list them for consistency:
- No documentation means that you really don't know how the function works. This means in particular that you
- Don't know corner cases
- Can't distinguish between a bug and intended behavior
- The function may change in future versions, which may range from implementation changes to the function being totally removed.
In some cases, you can be more or less sure that some undocumented function will not be removed or become incompatible, because you somehow know that too much of internal functionality depends on that (for example, I have such feeling for Internal`InheritedBlock
). In such cases, I would be less hesitant to use these functions.
Specific situations
That said, I think it's OK if one decides to use undocumented functions in his/her work, as long as one takes full responsibility for that. The factors I would personally consider are:
- Who will use your functionality
- Who will maintain your code
- How critical is the code using that undocumented function
Using undocumented functions is a calculated risk. You trade speed of development (and often execution) for possible maintenance problems. The use of undocumented functions will increase maintenance costs because
- there are higher chances of regression bugs coming from versions incompatibility
- It is harder to read and understand the code (particularly for someone else), because of the lack of documentation
- It is harder to debug code
There are, of course, well-known techniques, such as writing unit tests, and make extensive comments in your code. These may to a large extent alleviate these problems.
Summary
So, in summary, I would distinguish between the "general advice" and specific situations. My "general advice" would be "don't use it". But, particularly if one is an experienced user, I don't think this rule should never be broken. What matters is to take responsibility for your code, particularly including future maintenance. So, what I would do in case I decide to use undocumented function is to leave extensive comments describing the functionality I count on, plus some tests to test that it works correctly in some representative use cases.
While the existing answers answer your question of whether/when it is a bad idea to use undocumented functionality, you didn't yet get an answer about your question why that functionality is undocumented. Of course, the ultimate answer to this question could only come from Wolfram (because they were making that decision), however here are several common reasons for leaving functionality undocumented (note that this is a general list, not one specific to Mathematica or Wolfram; I'm no Wolfram employee, nor do I personally know one):
- The functionality was used internally to implement some documented feature, but not considered worthwhile enough to make it documented. Note that making it documented means more than just writing documentation for it (most likely there does exist internal documentation for each undocumented function at Wolfram). It means extensive testing of the function, especially in corner cases. Possibly it even means actually writing additional code for corner cases where for internal functions you'd just throw a "not yet implemented" error (or even just put a warning about wrong results for that case in the internal docs) because your internal usage doesn't need that corner case anyway.
- The functionality is intended to go public in the future, but is not yet finished. However it is already included for the benefit of own code, which doesn't need the missing parts.
- The functionality is basically finished and will go public in some later release, but you feel that it hasn't yet gotten enough testing to officially support it.
- It might also just be an oversight (i.e. someone just forgot to add the corresponding documentation). This is certainly not the case for
Internal`
stuff (the name is a dead giveaway that it was only meant for internal use), but might be the case for some undocumented or partially documented option.