6
$\begingroup$

Bug introduced in 10.4 and persisting through 11.1.1


Up until 10.4 you could not match on internal Association structure at all: https://mathematica.stackexchange.com/a/119542/6804

Now you can, but it seems flawed still: the following patterns should match <|"c" -> {0}|> but not <|"c" -> {1}|>. These work:

gok1[KeyValuePattern@{"c" -> c_List /; First@c == 0}] := 0;
gok2[KeyValuePattern@{"c" -> c_List}] := 0 /; First@c == 0;

(I still don't understand why they support the second variant, after all the RHS in := should not be a Pattern...).

But this one does not:

gfail[KeyValuePattern@{"c" -> c_List}] /; First@c == 0 := 0;

giving First::normal: Nonatomic expression expected at position 1 in First[c]. but only the first time it is used, e.g. via

gfail[<|"c" -> {0}|>]
gfail[<|"c" -> {1}|>]

or

gfail[{"c" -> {0}}]
gfail[{"c" -> {1}}]

So the culprit seems to be the KeyValuePattern. If it is not involved, everything works fine:

hok[{"c" -> c_List}] /; First@c == 0 := 0;
hok1[{"c" -> c_List /; First@c == 0}] := 0;
hok2[{"c" -> c_List}] := 0 /; First@c == 0;

hok[{"c" -> {0}}]
hok[{"c" -> {1}}]
hok1[{"c" -> {0}}]
hok1[{"c" -> {1}}]
hok2[{"c" -> {0}}]
hok2[{"c" -> {1}}]

Am I missing something or can somebody confirm this as a probable bug?

$\endgroup$
  • 1
    $\begingroup$ It seems in patt /; test c isn't shared but for lhs:>rhs/;test it is: a : KeyValuePattern[{"c" -> c_List}] :> a /; (First[c] === 0). Just an observation, don't know if the observerd behavior is to be expected (isn't for me). $\endgroup$ – Kuba Jun 28 '16 at 20:55
  • $\begingroup$ Is it useful to make contact with these answers? (108925) (109383) $\endgroup$ – Jess Riedel Jun 29 '16 at 1:04
4
$\begingroup$

It is a bug that the local variable c isn't shared with Condition when the latter appears at the LHS outside of the KeyValuePattern. The following simplified examples demonstrate the bug:

gfail1[KeyValuePattern@{"c" -> c_}] /; c == 0 := 0
gfail2[KeyValuePattern@{"c" -> c_} /; c == 0] := 0

gfail1[<|"c" -> 0|>]
gfail2[<|"c" -> 0|>]
gfail1[<|"c" -> 0|>]

gfail2[<|"c" -> 0|>]

These cases demonstrate the expected behavior:

gok1[KeyValuePattern@{"c" -> c_ /; c == 0}] := 0
gok2[KeyValuePattern@{"c" -> c_}] := 0 /; c == 0

gok1[<|"c" -> 0|>]
gok2[<|"c" -> 0|>]
0

0

Please report it to the tech support.


(I still don't understand why they support the second variant, after all the RHS in := should not be a Pattern...).

Actually the RHS with Condition IS a part of the pattern expression, please read this excellent answer by Leonid Shifrin.

$\endgroup$
  • $\begingroup$ Alright, I filed a report. $\endgroup$ – masterxilo Jul 1 '16 at 0:25
  • $\begingroup$ @masterxilo Have you received any response? $\endgroup$ – Alexey Popkov Apr 29 '17 at 5:42
2
$\begingroup$

Consider

test[p : KeyValuePattern@{"c" -> c_List}] /; First[p["c"]] == 0 := $Succeeded
test[p : KeyValuePattern@{"c" -> c_List}] := $Failed

then

test[<|"c" -> {0, 1}|>]

$Succeeded

test[<|"c" -> {1, 1}|>]

$Failed

Perhaps that is form you are looking for.

$\endgroup$
  • $\begingroup$ Nice, I didnt even try to find a workaround. $\endgroup$ – masterxilo Jun 29 '16 at 9:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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