Group Abstract Group Abstract

Message Boards Message Boards

0
|
6K Views
|
6 Replies
|
7 Total Likes
View groups...
Share
Share this post:

[?] Use Cases with RuleDelayed?

Posted 6 years ago

Let us assume very simple and dumb example of pattern extracting from some data list by Cases[]:

Cases[{{1}, {2}}, x_ -> x[[1]]]

One can run it and get

During evaluation of In[1]:= Part::partd: Part specification x[[1]] is longer than depth of object.

Out[1]= {1, 2}

What a hell, why x is not an array?

Or a little more complex example:

In[287]:= Cases[{"2","1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1"}, mList_String -> StringExtract[mList, All], 1]

During evaluation of In[287]:= StringExtract::strse: String or list of strings expected at position 1 in StringExtract[mList,All].

Out[287]= {{"2"},{"1", "0", "0", "0", "0", "1", "0", "0", "0", "0", "1", "0", "0", "0", "0", "1"}}

One can tell, that as we get after all an correct output there is no big problem in such warnings. But if we go a little deeper the real problem rises:

In[304]:= Cases[{"2", "1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1"}, mList_String -> ToExpression[StringExtract[mList, All]], 1]

During evaluation of In[304]:= StringExtract::strse: String or list of strings expected at position 1 in StringExtract[mList,All].
During evaluation of In[304]:= ToExpression::notstrbox: StringExtract[mList,All] is not a string or a box. ToExpression can only interpret strings or boxes as Wolfram Language input.

Out[304]= {$Failed, $Failed}

Any correct result at all. 

So, what is exact problem with Cases[] and how to fix it correctly (i managed to make a simple and dirty fix, but do not like it)?

POSTED BY: Maksym Snegirev
6 Replies

The difference between Rule and RuleDelayed is explained under Properties & Relations.

Every online documentation page has a Feedback link at the bottom. You can suggest improvements there.

https://reference.wolfram.com/language/ref/Rule.html

POSTED BY: Szabolcs Horvát

Can you please give me an example of such pattern substitution where the use of the immediate Rule[] is essential? Maybe the documentation need to be changed for usage :> in most cases and only in rare occasions -> need to be used?

Sometimes you must have immediate evaluation to get the token that you are pattern matching. Let's say you are evaluating an expression that has x in it, you want to make a rule with x-- the only way to do that is to use immediate evaluation. Below, "express" would be the result of some other calculations that has variable "x" in it.

In[1]:= express = f[x]

Out[1]= f[x]

In[2]:= Cases[{1, 2, 3}, x_ -> express]

Out[2]= {f[1], f[2], f[3]}

In[3]:= Cases[{1, 2, 3}, x_ :> express]

Out[3]= {f[x], f[x], f[x]}

In this case, the RuleDelayed gives the "wrong" answer for what was intended. Rule would be correct here.

My point is that similar explanation must be in "Possible issues" section of Rule[] doc page. But today such section is absent at all. And maybe some references in Cases[] and similar derived stuff too.

That is a good suggestion. You should contact support (and point them to this thread). I have made similar documentation suggestions in the past and they have been very responsive. The link is here for technical support.

Regards,

Neil

POSTED BY: Neil Singer

My point is that similar explanation must be in "Possible issues" section of Rule[] doc page. But today such section is absent at all. And maybe some references in Cases[] and similar derived stuff too.

Because of Cases[] and others applications tell about "patterns":

Cases[{Subscript[e, 1],\[Ellipsis]},pattern->rhs]
gives a list of the values of rhs corresponding to the Subscript[e, i] that match the pattern. 

Patterns are not self-essential, it must be applied to something before calculations. By principal goal it need to be a deferred calculation.

But Wolfram Kernel takes the different point. It's not a real bug, it is peculiarity, but it tends to disambiguation and potential errors.

Because of documentation "clearly" instruct us

Find the sum of every pair of elements:
In[2]:= Cases[{{1, 2}, {2}, {3, 4, 1}, {5, 4}, {3, 3}}, {a_, b_} -> a + b]
Out[2]= {3, 9, 6}

But tells nothing about that if one have already put somewhere deep in code a simple definition like

a = 100;

you'll surprisingly got

In[6]:= Cases[{{1, 2}, {2}, {3, 4, 1}, {5, 4}, {3, 3}}, {a_, b_} -> 
  a + b]
Out[6]= {102, 104, 103}

instead.

That's the point.

In both cases most of the time they will have the same result but in certain situations you must choose one or the other to get the behavior that you want.

Can you please give me an example of such pattern substitution where the use of the immediate Rule[] is essential? Maybe the documentation need to be changed for usage :> in most cases and only in rare occasions -> need to be used?

POSTED BY: Maksym Snegirev
POSTED BY: Neil Singer
POSTED BY: Maksym Snegirev
Posted 6 years ago

You are supposed to be using RuleDelayed (:>) and not Rule (->) in a situation where you don't want the right-hand side to evaluate at once:

Cases[{{1}, {2}}, x_ :> x[[1]]]
   {1, 2}

Cases[{"2", "1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1"}, 
      mList_String :> ToExpression[StringExtract[mList, All]], 1]
   {{2}, {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}}

FWIW, it is a little unfair to label as a "bug" a situation where the inappropriate function was used.

POSTED BY: J. M.
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard