12
$\begingroup$

Bug fixed in 11.2.0


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?

$\endgroup$
8
  • 1
    $\begingroup$ 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... $\endgroup$
    – Michael E2
    Commented Jan 2, 2013 at 8:01
  • $\begingroup$ 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. $\endgroup$ Commented Jan 2, 2013 at 12:44
  • $\begingroup$ @MichaelE2 That's odd. I haven't even tested the real return-value, only investigated in the Throw. Nice finding. $\endgroup$
    – halirutan
    Commented Jan 2, 2013 at 13:37
  • 2
    $\begingroup$ 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 StringPattern`Dump`rule1b (called by StringPattern`PatternConvert called by StringMatchQ). $\endgroup$
    – WReach
    Commented Jan 2, 2013 at 16:26
  • $\begingroup$ @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. $\endgroup$ Commented Jan 2, 2013 at 19:41

1 Answer 1

12
$\begingroup$

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:

Catch[Throw[False]]

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

Catch is relevant to the current matter at hand because StringMatchQ calls StringPattern`PatternConvert, which in turn calls StringPattern`Dump`rule1b. 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.

$\endgroup$
2
  • $\begingroup$ (1) I am at a loss to explain the subsequent failure of the StringMatchQ outside to the initialization phase. I wonder if it might be a caching effect specific to that particular invocation (why it would be cached I do not know)? $\endgroup$ Commented Nov 27, 2016 at 17:23
  • $\begingroup$ (2) The issue with init.m is that various "exceptions" (things handled with signalling) are disabled when it is run. Throw is such a being. By the time it is seen, after reenabling, the surrounding Catch is long gone. There is some experimental work in progress to address this but I do not know (yet) whether it will prove to be successful, let alone when it might be released. $\endgroup$ Commented Nov 27, 2016 at 17:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.