# StringMatchQ and Alternatives throws message in init.m

The report of this issue, which itself relates to code of my answer here, exposed a behavior I cannot explain. If I use StringMatchQ in combination with Alternative inside the init.m a message is thrown on start of the kernel.

You can test this by putting this line in your init.m

StringMatchQ["name", "noMatch" | "name"];


and when you start the kernel you see two messages saying

Throw::nocatch: Uncaught Throw[False] returned to top level.

Surrounding the statement by Catch does not help. The solution is to substitute this regex-alternative into a logical Or

StringMatchQ["name", "noMatch"] || StringMatchQ["name", "name"]


but that doesn't explain the issue. What am I missing here?

-
Yes, I got the same. Also, StringMatchQ["name", "noMatch" | "name"] returns False in a new notebook if it's in init.m. If I change "noMatch" to something like "foo" it returns True. When I take it out of init.m and restart Mathematica, it returns True. Seems like a bug somewhere... –  Michael E2 Jan 2 '13 at 8:01
I can't test right now, can only guess. When one uses Mathematica - style patterns in string-related functions, those patterns get compiled to regexes. This procedure is the likely source of exceptions you see. Why this only happens in the init.m files I have no idea, can't dig deeper at the moment. It could be for example that it relies on Java and Java is not yet available, or may be something else of a similar nature. –  Leonid Shifrin Jan 2 '13 at 12:44
@MichaelE2 That's odd. I haven't even tested the real return-value, only investigated in the Throw. Nice finding. –  halirutan Jan 2 '13 at 13:37
Apparently Catch doesn't work properly in the init.m file. I get the exhibited error message if I put Catch[Throw[False]] in my init file using V7, V8 or V9. In the example at hand, a Catch is used in StringPatternDumprule1b (called by StringPatternPatternConvert called by StringMatchQ). –  WReach Jan 2 '13 at 16:26
@WReach It is not the first time that I saw Catch failing. It looked like Catch is tied to a particular stack, and in some cases it looks like evaluation is using different stacks for parts of it. I may have just given a wrong explanation, but this is what it looked like. I did not have the time to dig deeper and obtain a fully satisfactory answer for these cases. –  Leonid Shifrin Jan 2 '13 at 19:41
show 1 more comment

Cause

The problem is due to a bug involving Catch and init.m that occurs in (at least) Mathematica versions 7, 8 and 9. It has been reported to Wolfram Support and they have acknowledged it as a bug. At time of writing, WRI has offered neither diagnosis nor workaround for this problem.

Reproduction Steps and Analysis

To reproduce the issue, place the following expression in the init.m file and then restart the session:

$result = StringMatchQ["name", "noMatch" | "name"];  The message window will show two instances of the message Throw::nocatch: Uncaught Throw[False] returned to top level. Furthermore, StringMatchQ no longer functions correctly in the new session: $result
(* False *)

StringMatchQ["name", "noMatch" | "name"]
(* False *)


This second result is extremely disturbing since it means that all evaluations in the new session that could potentially involve StringMatchQ must be treated with suspicion (and who knows what else is suspect as well). The good news is that occurrence of this problem must be extremely rare because it has gone unnoticed since at least 2008.

Judicious use of Trace and similar debugging tools reveals that it is possible to produce the exhibited error messages using a simpler form:

Throw[Catch[False]]


However, this simpler form does not corrupt the behaviour of StringMatchQ.

Catch is relevant to the current matter at hand because StringMatchQ calls StringPatternPatternConvert, which in turn calls StringPatternDumprule1b. This last has the following replacement rule (in outline):

(List|Alternatives)[a__] :>
If[Catch[(If[!SingleCharacterQ[#1],Throw[False]]&) /@ {a};True], ...]


This rule is applicable to the exhibited troublesome expression because it involves the use of Alternatives, and a Throw occurs because the strings are longer than single characters:

StringMatchQ["name", "noMatch" | "name"];


Workaround

Experimentation reveals a workaround, for versions 8 and 9 at least. Catch and StringMatchQ will operate properly if run as an immediate scheduled task instead of directly inline. For example, we can place the following lines in the init.m file:

RunScheduledTask[
$result = StringMatchQ["name", "noMatch" | "name"] ; RemoveScheduledTask @$ScheduledTask
, {0}
]


The resulting session functions properly:

\$result
(* True *)

StringMatchQ["name", "noMatch" | "name"]
(* True *)


Apparently, the scheduled task environment is isolated from whatever causes this problem.

I cannot stress enough that this is an empirical result with neither proper explanatory backing nor WRI endorsement.

-