# Why doesn't Mathematica use uniform criteria for validating Options?

Plot[Sin[x], {x, 0, 1}, pp -> 0]


Gives as expected:

Plot::optx: Unknown option pp in Plot[Sin[x],{x,0,1},pp->0]. >>

However:

Import["http://i.stack.imgur.com/JrxBD.png", pp -> "HSB"]


returns no error.

Is there a language design reason for this, or is it just lack of standards?

-
More than once have I wondered why Export is broken, then I see I misspelled some option –  ssch Jan 6 '13 at 19:51
@Nasser: I fail to see what is invalid in your example. It is a perfectly well-formed Mathematica expression and it does what I expect it to do. Nothing is in conflict, it is just that Frame is higher up in the regulatory chain than FrameTicksStyle. I very much hope that WRI won't issue such warnings in the future! –  István Zachar Jan 6 '13 at 20:24
The only reliable way to enforce some standard is to do it on the language level. This is particularly true for languages like Mathematica, which offer a great number of possible ways to solve problems. –  Leonid Shifrin Jan 6 '13 at 20:41
@Nasser remember that your Options values can be functions, so you can turn them on or off without modifying the statement –  belisarius Jan 6 '13 at 20:51
Note that Options[Image] returns an empty list, thus, Image has no options. –  Mark McClure Jan 7 '13 at 2:15

The main points of this answer are that,first, it seems rather difficult to have a fully universal mechanism for option-validation, and second, such a mechanism is not currently available in Mathematica on the language level (meaning automation of complete option-checking, including both the option's name and value).

In the particular case in question, Import does not have options, but the strict option-checking via OptionPattern probably wasn't employed because Import has a rich syntax and may have arguments containing rules that look like options (while they aren't). Generally, OptionValue -- OptionsPattern were introduced in V6, so I am sure that there is a lot of internal code that still uses OptionQ instead (which IMO is perfectly fine as long as option names, values, etc are checked by other means). Also, it may not always be advantageous to use the newer constructs.

Let's also keep in mind that even OptionsPattern -- OptionValue don't give you full option-checking, since these constructs don't check the value of a passed option, only its name. So, in practice, checking the validity of a given passed option is still a necessity for production-quality code, even if the newer constructs are used. I am not aware of any further system-wide automation for this (which may be just my ignorance), so it looks like this is dealt with on a case-by-case basis.

Philosophically, I think that the original design, using the semantics of rules and pattern-matching to have options (optional named arguments) in the language without introducing any additional constructs, was quite neat. Later, it probably became clear that options and their checking represent a special case, common enough that the introduction of some additional (rather magical) constructs to handle them specially could be justified. It may be, that at some point some additional constructs will be introduced to automate validating the values of options (or may be not). But, there is always a tradeoff between the purity of the language design, and safety/automation: from the viewpoint of pure semantics of options, the newer OptionValue -- OptionsPattern constructs weren't really needed, rules + pattern-matching were enough.

While we are at it, let me mention (shameless plug) that I made my own attempt to automate the option-validating process by means of packages which I wrote and named CheckOptions and PackageOptionChecks and which live here. The former basically parses the definition(s) of a particular function and generates new definitions which validate the options according to some declarative specifications. The latter brings the functionality of the former to entire packages, and adds some convenient declarative syntax to specify how options are to be validated. Both can be used to "protect" options for functions you write yourself, as well as for functions/packages written by someone else. The latter package can be used to protect options of functions in some other package without modifying the source code of that other package.

I would hesitate to recommend using these packages in production, unless you inspect exactly how they modify the original functions' definitions (or are otherwise sure that they won't break anything), since they are rather intrusive in the way they work, but I found them quite helpful for debugging. For your own packages, where you control and understand the code, however, I would consider using them as an option (if you are concerned about option-checking), particularly if your code does not use some meta-programming tricks such as run-time generation of functions' definitions. One practical example of their use is the package PackageSymbolsDependencies, which lives at the same page.

-
I'm not fully understanding your point. Obviously, at some time while executing the function (perhaps at the very end), Mma should be able to decide if the Options received are valid or not. While I understand the code overhead for validation could be very big in cases like Export, deciding going silent about a syntax error doesn't seems wise if it was done on purpose. +1, obviously :) –  belisarius Jan 6 '13 at 20:11
@belisarius I actually don't get an error when I execute your code with Import. My point is that consistent checking of options is something not very easy to automate on the language level without introducing yet more constructs to the language. So, it is then at the mercy of a particular developer who may have missed some cases etc. So, if some option value is not validated properly, it should be considered a bug, but my point is that I am unaware of any general mechanism to automate this validation process. –  Leonid Shifrin Jan 6 '13 at 20:15
One thing I find practically very painful with the new construct is the difference between Options[Plot] and Options[Import]. The former is informative, the latter sucks. With the new philosophy it becomes a guru issue to know how to use some of the functions, and/or and endless wander in the documentation! –  chris Jan 6 '13 at 20:26
@belisarius No problem :) As an example of application of that package, you can have a look at another package on the same page, PackageSymbolsDependencies. –  Leonid Shifrin Jan 6 '13 at 20:26
@chris I agree that this may be a problem. A related issue is that many new options and especially sub-options have strings as their names, rather than symbols. I expressed my opinion on this in this answer, and I still mostly hold it (in particular, it is harder to search for the string options in the documentation etc), but I also encountered cases where string options may be more appropriate, since that answer. –  Leonid Shifrin Jan 6 '13 at 20:36

I think this particular scenario has to do with how you can create your own Import/Export filters: Developing an Import Converter

Regarding 'verification' as in the Plot[Sin[x], {x, -Pi, Pi}, Frame -> True, FrameTicksStyle -> Red] example given by Nasser, keep in mind that you might have options parameterized like so:

Manipulate[
Plot[Sin[x], {x, -Pi, Pi}, Frame -> frame, FrameTicksStyle -> Red]

, {frame, {True, False}}]


Also note cases like this:

plot = Plot[Sin[x], {x, -Pi, Pi}, Frame -> True, FrameTicksStyle -> Red];
show = Show[plot, Frame -> False];

Options[show]

{Frame -> False, Frame -> True, FrameTicksStyle -> RGBColor[1, 0, 0], ...}


Personally I don't think it's worth it anyways because it is extra complexity that doesn't provide much benefit. But if it was implemented, I think the ideal site would be at the syntax highlighting level, to whatever degree that is possible.

-