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$
2
  • 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, 2016 at 20:55
  • $\begingroup$ Is it useful to make contact with these answers? (108925) (109383) $\endgroup$ Jun 29, 2016 at 1:04

2 Answers 2

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$
2
  • $\begingroup$ Alright, I filed a report. $\endgroup$
    – masterxilo
    Jul 1, 2016 at 0:25
  • $\begingroup$ @masterxilo Have you received any response? $\endgroup$ Apr 29, 2017 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$
1
  • $\begingroup$ Nice, I didnt even try to find a workaround. $\endgroup$
    – masterxilo
    Jun 29, 2016 at 9:46

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.