When g is in the local scope defined by Block, the following fails:

Block[{g, x},
  g[x] = StringExpression[x : LetterCharacter];
  SetAttributes[f, Listable];
  f = Function[{str}, StringMatchQ[str, g[x]], Listable];

eg. f[{"v", "e", "7", "2", "i"}] produces the message StringExpression::invld with text "Element g[x] is not a valid string or pattern element in g[x]" and returns

{StringMatchQ["v", g[x]], StringMatchQ["e", g[x]], 
    StringMatchQ["7", g[x]], StringMatchQ["2", g[x]], 
     StringMatchQ["i", g[x]]}

but instead when g is in the global scope ie when g is removed from the list of variables that are local to the Block, f works as expected.

On the previous example, evaluating f[{"v", "e", "7", "2", "i"}] returns {True, True, False, False, True}.

(Why is this happening and) would it be possible to make f work when g is local to the Block?

  • 1
    $\begingroup$ Function is HoldAll and once Block is done there is no reference to g which is inside f. You need to inject it with With or Function[...] /. DownValues[g] $\endgroup$
    – Kuba
    May 3, 2018 at 8:31
  • $\begingroup$ @Kuba thanks! With doesn't work with g[x] but /. DownValues[g] does the trick; a quick follow-up: when I define f as in SetAttributes[f, Listable]; f[str_] := StringMatchQ[str, g[x]], the problem persists for the same reasons? $\endgroup$
    – user42582
    May 3, 2018 at 8:57
  • 1
    $\begingroup$ Yes, because SetDelayed holds right hand side too. $\endgroup$
    – Kuba
    May 3, 2018 at 9:01


Browse other questions tagged or ask your own question.