I'm having some problems with writing a function that takes options. One of the option values is a function. I one to get at this value but keep it unevaluated. I tried every single thing I could possibly think of but nothing worked so far.
Basically, to illustrate this is what I tried:
SetAttributes[Foo, HoldRest];
Options[Foo] = {Blah -> None}
Foo[x_, OptionsPattern[]] :=
Module[{blah},
blah = OptionValue[Automatic, Automatic, Blah, Hold];
.
.
.
Then when I have:
func[a_, b_, c_] := a + b + c;
I'd like to be able to call Foo with:
Foo[2, Blah -> func[1, 2, 3]]
And have the "blah" variable (inside Foo) to be unevaluated, i.e. blah = func[1, 2, 3].
Thanks for all the help in advance!
Edit:
For reasons that are too long to elaborate, I cannot use RuleDelayed (:>). I'm trying to write a function that will be in a package, used by other people that don't really know Mathematica, so they would have no clue what :> is. Using rules (->) for specifying options and their values is the standard way and they familiar with that.
So to further illustrate, let's say that I'm trying to write a number generator function that takes a function that generates the actual number as one of it's options:
Options[GenerateNumbers] = {GeneratorFunction -> None};
GenerateNumbers[n_, OptionsPattern[]] :=
Module[{func},
func = OptionValue[GeneratorFunction];
Table[func, {n}]
]
]
Now, if I called this function with values as follows:
GenerateNumbers[5, GeneratorFunction -> RandomReal[10]]
It would return a list of 5 numbers that are the same, since RandomReal[10] gets evaluated once and not at every iteration of Table. I want to prevent this. The problem is more complicated but it's along these lines.
Thanks!
Use a name for the OptionsPattern and then wrap the captured sequence object with a List and an Unevaluated. A very minimal way of capturing the right-hand side for Blah is:
SetAttributes[Foo, HoldRest]; Options[Foo] = {Blah -> None};
Foo[x_, opts : OptionsPattern[]] :=
Module[{blah},
blah = OptionValue[Foo, Unevaluated[{opts}], Blah, Hold];
blah]
Testing it out:
In[2]:= Foo[x, Blah -> (1 + 1)]
Out[2]= Hold[1 + 1]
Why don't you use RuleDelayed?
Foo[2, Blah :> func[1, 2, 3]]
In this case blah=Hold[func[1, 2, 3]] as expected.
Your usage of the options is a little strange. If you want to pass some expression wrapped in Hold, why not wrap it in Hold when passing, like Blah->Hold[func[1,2,3]]? Anyway, assuming this simple definition for Foo:
Foo[x_, OptionsPattern[]] :=
Module[{blah},
blah = OptionValue[Automatic, Automatic, Blah, Hold];
blah
],
you can accomplish what you want by passing an option with RuleDelayed rather than Rule:
In[7]:= func[a_, b_, c_] := a + b + c;
In[8]:= Foo[2, Blah :> func[1, 2, 3]]
Out[8]= Hold[func[1, 2, 3]]
HTH
Edit:
If you don't want Hold wrapped around, here is one way to get rid of it:
In[25]:=
ClearAll[setDelayedHeld];
SetAttributes[setDelayedHeld, HoldFirst];
setDelayedHeld[lhs_, Hold[rhs_]] := lhs := rhs
In[28]:=
Clear[Foo];
Foo[x_, OptionsPattern[]] :=
Module[{blah},
setDelayedHeld[blah, OptionValue[Automatic, Automatic, Blah, Hold]];
OwnValues[blah]]
In[30]:= Foo[2, Blah :> func[1, 2, 3]]
Out[30]= {HoldPattern[blah$1018] :> func[1, 2, 3]}
I return OwnValues for blah to show that it was assigned func[1,2,3] without evaluating the latter - if this is what you want.
Related
Best way to get the Dimension of a till now unknown symbol.
For example:
foo = Dimensions[undefined][[1,1]];
foo /.undefined -> {{1,2},{3,4}}
Theses lines of code do not work. Does anyone know, how to write this correctly?
I have to import the the values by substitutions. 'foo' as a function and 'a' as a parameter is unfortunately no alternative for me.
You have the right idea in your self-answer and I voted for it. However you should be aware that MatrixQ is not as general as you might want. For example a three dimensional tensor will fail it:
tensor = RandomInteger[9, {3, 2, 4}];
MatrixQ[tensor]
False
Dimensions can be used on an expression that is not even a List:
f[f[1, 2], f[3, 3]] // Dimensions
{2, 2}
Further your use of Part is not correct. Note the warning message:
dim[undefined][[1, 1]]
During evaluation of In[106]:= Part::partd: Part specification dim[undefined][[1,1]] is longer than depth of object. >>
dim[undefined][[1, 1]]
There is no part (1, 1) in the output of Dimensions. If you instead use [[1]] you will simply extract undefined from dim[undefined]. Instead you should include the part extraction in the definition of dim, or if you have Mathematica 10+ you can use Indexed.
I propose:
dims[x : _[__], part__: All] := Dimensions[x][[part]]
Now:
dims[undefined] /. undefined -> tensor
{3, 2, 4}
dims[undefined, 1] /. undefined -> tensor
3
dims[undefined, 2] /. undefined -> f[f[1, 2], f[3, 3]]
2
Visit the dedicated Mathematica Stack Exchange site:
I found a possibility:
Need to wrap 'Dimensions'
dim[x_?MatrixQ] := Dimensions[x];
...
foo = dim[undefined][[1,1]];
foo /.undefined -> {{1,2},{3,4}}
This works!
I have a list and I want to apply a logical test to each element, and if any one of them does not satisfy this condition, then return false. I want to write this in Mathematica or find a built-in function, but seems ForAll does not actually do that.
My question is: how to do this most efficiently?
Bonus: how about similarly for Exists function: i.e. if there is any element in the list satisfy the condition, return true.
The answer to the first portion of your question might be something along these lines:
forAll[list_, cond_] := Select[list, ! cond## &, 1] === {};
which is used like this:
forAll[{1, 2, 3, 3.5}, IntegerQ]
The "exists" function is already natively implemented as MemberQ. It could be reimplemented as:
exists[list_,cond_] := Select[list, cond, 1] =!= {};
Use it like
exists[Range#100, (10 == # &)]
which returns true as 10 is an element causing the Select to return {10} which is not equal to {}.
This answer is not intended to show the most efficient method, but rather an alternative method that serves the pedagogical purpose of showing some important core functionality in Mathematica.
nixeagle's answer avoids explicitly testing every element of the list. If the test doesn't lend itself to inclusion in the third argument of Select, then the below might be useful.
To do this, you need to learn about the standard Or and And functions, as well as the Map (/#) and Apply (##) commands which are extremely important for any Mathematica user to learn. (see this tutorial)
Here is a simple example.
In[2]:= data = RandomInteger[{0, 10}, {10}]
Out[2]= {10, 1, 0, 10, 1, 5, 2, 2, 4, 1}
In[4]:= # > 5 & /# data
Out[4]= {True, False, False, True, False, False, False, False, False, \
False}
In[6]:= And ## (# > 5 & /# data)
Out[6]= False
What is going on here is that you are mapping the function ("greater than 5") to each element of the list using Map, to get a list of True/False values. You are then applying the standard logical function And to the whole list to get the single Boolean value.
These are all very much core functionality in Mathematica and I recommend you read the documentation for these functions carefully and practice using them.
This is not the most efficient method, but for small problems you will not notice the difference.
In[11]:= Do[Select[data, ! # > 5 &, 1] === {}, {10000}] // Timing
Out[11]= {0.031, Null}
In[12]:= Do[And ## (# > 5 & /# data);, {10000}] // Timing
Out[12]= {0.11, Null}
For Exists, the alternative to Select would be MatchQ for patterns or MemberQ for explicit values. The documentation has some useful examples.
Not to be taken too seriously, but this
ClearAll[existsC];
existsC[cond_] := With[
{c = cond},
Compile[
{{l, _Integer, 1}},
Module[
{flag = False, len = Length#l},
Do[
If[cond[l[[i]]],
flag = True; Break[];
];,
{i, 1, len}];
flag
],
CompilationTarget -> "C"
]
]
appears to be around 300 times faster than nixeagle's solutions on my machine. What this does is to emit a compiled function which takes a list and compares its elements to the given condition (fixed at compile-time), returning True if any of them matches.
It is used as follows: Compile with the appropriate cond, eg
t = existsC[# == 99999 &];
and then
t[Range#100000] // timeIt
returns 2.33376*10^-6 (a worst-case scenario, as I am just searching linearly and the matching element is at the end) while
exists[Range#100000, (99999 == # &)] // timeIt
returns 0.000237162 (here, timeIt is this).
A pattern based approach:
forAll[list_, test_] := MatchQ[ list, _[__?test] ]
MemberQ already implements exists.
Mathematica 10 has a new function for this: AllTrue. When all elements pass the test my function appears to be a bit faster:
a = Range[2, 1*^7, 2];
AllTrue[a, EvenQ] // Timing // First
forAll[a, EvenQ] // Timing // First
1.014007
0.936006
However with an early exit the benefit of the new function becomes apparent:
a[[123456]] = 1;
AllTrue[a, EvenQ] // Timing // First
forAll[a, EvenQ] // Timing // First
0.031200
0.265202
Even though && and || perform short-circuit evaluation, i.e., don't evaluate their arguments unnecessarily, I suspect that solutions based on Select[] or Map[] won't benefit much from this. That's because they apply the logical test to every element, building a list of Boolean truth-values before performing the conjunction/disjunction among them. If the test you've specified is slow, it can be a real bottleneck.
So here is a variant that does short-circuit evaluation of the condition as well:
allSatisfy[list_, cond_] :=
Catch[Fold[If[cond[#2], True, Throw[False]] &, True, list]]
Testing if any element in the list satisfies the condition is nicely symmetric:
anySatisfy[list_, cond_] :=
Catch[Fold[If[cond[#2], Throw[True], False] &, False, list]]
Of course this could equally have been done (and candidly speaking, more easily) using procedural loops such as While[], but I have a soft spot for functional programming!
nixeagle got the bonus part, but the way I would've done the first part is as follows:
AllSatisfy[expr_, cond_] := Length#Select[expr, cond] == Length#expr
There's a simple solution:
In[1401]:= a = {1, 2, 3}
Out[1401]= {1, 2, 3}
In[1398]:= Boole[Thread[a[[2]] == a]]
Out[1398]= {0, 1, 0}
In[1400]:= Boole[Thread[a[[2]] >= a]]
Out[1400]= {1, 1, 0}
In[1402]:= Boole[Thread[a[[2]] != a]]
Out[1402]= {1, 0, 1}
Success!
I want to repeat a function n times on a table, For n=2 I have the following code, How can I be sure that the function had run twice since my fc is differend every time?
smat = Table[{9, 8, 10}, {3}]
f[x_?Table] := ReplacePart[
x, {{2, 1} -> x[[2]][[1]] - #, {2, 2} -> x[[2]][[2]] + #}] &# fc[x[[2]][[1]]];
fc[k_?NumericQ] := Count[RandomReal[{0, 1}, k], x_ /; x < .1]
Nest[f, smat, 2]
This is probably what you want:
smat = Table[{9, 8, 10}, {3}]
ClearAll[f, fc];
f[x_List] :=
ReplacePart[
x, {{2, 1} -> x[[2]][[1]] - #, {2, 2} -> x[[2]][[2]] + #}] &#
fc[x[[2]][[1]]];
fc[k_?NumericQ] := Count[RandomReal[{0, 1}, k], x_ /; x < .1]
Nest[f, smat, 2]
ClearAll clears any previous definitions for those symbols (just in case). f[x_?Table] won't work; you want f[x_List], which means that the argument has a List head (Table is not a Head, and ? isn't what you want here).
I am not sure I have really answered your question though...
EDIT: To be clear, f[x_?something] means "apply something to x and, if it returns True, evaluate the right hand side of the := that follows. Look up PatternTest in Mathematica's documentation for more.
Acl covered the problems with the code pretty well, so I won't. To answer your question, though, I'd first separate your functions f and fc in separate cells, with fc being declared prior to f, and preface each cell with Clear[<function name>]. Now, to test if f is being applied twice, temporarily replace fc with
fc[_]:= a
or use another "dummy" value other than a, but it should be symbolic to increase readability. As a point of note, {1,2,3} + a == {1 + a, 2 + a, 3 + a}, so if f is applied twice, each term in x[[2]][[1]] and x[[2]][[2]] will have 2 a added to it.
Now, if you are unsure if fc is working correctly by itself, I'd apply it to a number separate cases without f, first.
I have discovered that InString[] does not work in MathLink mode when sending input with EnterExpressionPacket header. So I need to define my own function that returns previous input line. One way I have developed here does not work in some cases:
In[1]:= Unevaluated[2 + 2]
With[{line = $Line - 1}, HoldForm[In[line]]] /. (DownValues[In])
Out[1]= Unevaluated[2 + 2]
Out[2]= 2 + 2
This is because RuleDelayed has no HoldAllComplete attribute. Adding this attribute makes this OK:
In[1]:= Unprotect[RuleDelayed];
SetAttributes[RuleDelayed, HoldAllComplete];
Protect[RuleDelayed];
Unevaluated[2 + 2]
With[{line = $Line - 1}, HoldForm[In[line]]] /. DownValues[In]
Out[4]= Unevaluated[2 + 2]
Out[5]= Unevaluated[2 + 2]
But modifying built-in functions generally is not a good idea. Is there a better way to do this?
It seems that I have solved the problem. Here is the function:
In[1]:=
getLastInput := Module[{num, f},
f = Function[{u, v},
{u /. {In -> num, HoldPattern -> First}, HoldForm[v]}, HoldAllComplete];
First#Cases[
Block[{RuleDelayed = f}, DownValues[In]],
{$Line - 1, x_} -> x, {1}, 1]]
In[2]:=
Unevaluated[2+2]
getLastInput
Out[2]=
Unevaluated[2+2]
Out[3]=
Unevaluated[2+2]
And I just have got the answer to the question on InString in MathLink mode from Todd Gayley (Wolfram Research):
InString is only assigned when using
EnterTextPacket, not
EnterExpressionPacket. There is no
string form of the input when sending
EnterExpressionPacket (whose content
is, by definition, already an
expression).
EDIT:
I just have found that my code does not work with input expressions with head Evaluate. The solution is to replace HoldForm by HoldComplete in my code:
getLastInput := Module[{num, f},
f = Function[{u, v},
{u /. {In -> num, HoldPattern -> First}, HoldComplete[v]}, HoldAllComplete];
First#Cases[
Block[{RuleDelayed = f}, DownValues[In]],
{$Line - 1, x_} -> x, {1}, 1]]
This works well. Another approach would be to unprotect HoldForm and set up attribute HoldAllComplete on it. I'm wondering why HoldForm does not have this attribute by default?
EDIT 2:
In the comments for the main question Leonid Shifrin suggested much better solution:
getLastInput :=
Block[{RuleDelayed},SetAttributes[RuleDelayed,HoldAllComplete];
With[{line=$Line-1},HoldComplete[In[line]]/.DownValues[In]]]
See comments for details.
EDIT 3:
The last code can be made even better for by replacing HoldComplete by double HoldForm:
getLastInput :=
Block[{RuleDelayed},SetAttributes[RuleDelayed,HoldAllComplete];
With[{line=$Line-1},HoldForm#HoldForm[In[line]]/.DownValues[In]]]
The idea is taken from presentation by Robby Villegas of Wolfram Research at the 1999 Developer Conference. See subsection "HoldCompleteForm: a non-printing variant of HoldComplete (just as HoldForm is to Hold)" in "Working With Unevaluated Expressions" notebook posted here.
I would use $Pre and $Line for this; unlike $PreRead, it's applied to input expressions, not input strings or box forms. All you need is to assign it a function that has the HoldAllComplete attribute, like this one which I've adapted from the example in the documentation:
SetAttributes[saveinputs, HoldAllComplete];
saveinputs[new_] :=
With[{line = $Line},
inputs[line] = HoldComplete[new]; new]
$Pre = saveinputs;
I tested this with MathLink, and the behavior seems to be what you desired (I've elided some of the transcript to highlight the key point):
In[14]:= LinkWrite[link,
Unevaluated[
EnterExpressionPacket[
SetAttributes[saveinputs, HoldAllComplete];
saveinputs[new_] :=
With[{line = $Line},
inputs[line] = HoldComplete[new]; new];
$Pre = saveinputs;]]]
In[15]:= LinkRead[link]
Out[15]= InputNamePacket["In[2]:= "]
In[20]:= LinkWrite[link,
Unevaluated[EnterExpressionPacket[Evaluate[1 + 1]]]]
In[21]:= LinkRead[link]
Out[21]= OutputNamePacket["Out[2]= "]
In[21]:= LinkRead[link]
Out[21]= ReturnExpressionPacket[2]
In[24]:= LinkWrite[link, Unevaluated[EnterExpressionPacket[DownValues[inputs]]]]
In[26]:= LinkRead[link]
Out[26]= ReturnExpressionPacket[
{HoldPattern[inputs[2]] :> HoldComplete[Evaluate[1 + 1]],
HoldPattern[inputs[3]] :> HoldComplete[DownValues[inputs]]}]
I just have found simpler but dangerous way:
In[3]:= Unevaluated[2 + 2]
Trace[In[$Line - 1]] // Last
Trace[In[$Line - 1]] // Last
Out[3]= Unevaluated[2 + 2]
Out[4]= Unevaluated[2 + 2]
During evaluation of In[3]:= $RecursionLimit::reclim: Recursion depth of 256 exceeded. >>
During evaluation of In[3]:= $RecursionLimit::reclim: Recursion depth of 256 exceeded. >>
During evaluation of In[3]:= $IterationLimit::itlim: Iteration limit of 4096 exceeded. >>
Out[5]= Hold[In[$Line-1]]
Does anybody know a way to make it safe?
I have earlier asked how to make allTrue[{x,list},test] function that protects the placeholder symbol x from evaluation in current context in the same way as Table[expr,{x,...}] protects x
The recipe that I ended up using failed intermittently, and I found the problem down to be caused by automatic conversion of lists to PackedArrays. Here's a failing example
SetAttributes[allTrue, HoldAll];
allTrue[{var_, lis_}, expr_] :=
LengthWhile[lis,
TrueQ[ReleaseHold[Hold[expr] /. HoldPattern[var] -> #]] &] ==
Length[lis];
allTrue[{y, Developer`ToPackedArray[{1, 1, 1}]}, y > 0]
I want allTrue[{x,{1,2,3}},x>0] to return True regardless of whether {1,2,3} gets automatically converted into PackedArray, what is a better way to implement it?
This is a version I've been using for quite a while (wrote it for a second edition of my book originally, but I ended up using it a lot). If arguments represent some unevaluated code, then the test function must have HoldAll or HoldFirst attributes if we want a single piece of code representing one specific clause to be passed to it in its unevaluated form (which may or may not be desirable).
ClearAll[fastOr];
Attributes[fastOr] = {HoldRest};
fastOr[test_, {args___}] := fastOr[test, args];
fastOr[test_, args___] :=
TrueQ[Scan[
Function[arg, If[test[arg], Return[True]], HoldAll],
Hold[args]]];
Edit: I just noticed that the solution by Daniel Reeves at the bottom of the page linked in the question, is very similar to this one. The main difference is that I care about both short-circuiting and keeping arguments unevaluated (see below), while Daniel focuses on the short-circuiting part only.
It does have a short-circuiting behavior. We need HoldRest attribute since we want to preserve the arguments in their unevaluated form. We also need the HoldAll (or HoldFirst) attribute in a pure function to preserve each of the arguments unevaluated until it is passed to test. Whether or not it gets evaluated before it is used in the body of test depends now on the attributes of test. As an example:
Clear[fullSquareQ];
fullSquareQ[x_Integer] := IntegerQ[Sqrt[x]];
In[13]:= Or ## Map[fullSquareQ, Range[50000]] // Timing
Out[13]= {0.594, True}
In[14]:= fastOr[fullSquareQ, Evaluate[Range[10000]]] // Timing
Out[14]= {0., True}
Here is an example where we pass as arguments some pieces of code inducing side effects (printing). The code of the last argument has no chance to execute, since the result has already been determined at the previous clause:
In[15]:= fastOr[# &, Print["*"]; False, Print["**"]; False,
Print["***"]; True, Print["****"]; False]
During evaluation of In[15]:= *
During evaluation of In[15]:= **
During evaluation of In[15]:= ***
Out[15]= True
Note that, since fastOr accepts general pieces of unevaluated code as clauses for Or, you have to wrap your list of values in Evaluate if you don't care that they are going to be evaluated at the start ( as is the case with the Range example above).
Finally, I will illustrate the programmatic construction of held code for fastOr, to show how it can be used (consider it a tiny crash course on working with held expressions if you wish). The following function is very useful when working with held expressions:
joinHeld[a___Hold] := Hold ## Replace[Hold[a], Hold[x___] :> Sequence[x], {1}];
Example:
In[26]:= joinHeld[Hold[Print[1]], Hold[Print[2], Print[3]], Hold[], Hold[Print[4]]]
Out[26]= Hold[Print[1], Print[2], Print[3], Print[4]]
Here is how we use it to construct programmatically the held arguments that were used in the example with Print-s above:
In[27]:=
held = joinHeld ## MapThread[Hold[Print[#]; #2] &,
{NestList[# <> "*" &, "*", 3], {False, False, True, False}}]
Out[27]= Hold[Print["*"]; False, Print["**"]; False, Print["***"]; True, Print["****"]; False]
To pass it to fastOr, we will use another useful idiom: append (or prepend) to Hold[args] until we get all function arguments, and then use Apply (note that, in general, if we don't want the piece we are appending / prepending to evaluate, we must wrap it in Unevaluated, so the general idiom looks like Append[Hold[parts___],Unevaluated[newpart]]):
In[28]:= fastOr ## Prepend[held, # &]
During evaluation of In[28]:= *
During evaluation of In[28]:= **
During evaluation of In[28]:= ***
Out[28]= True
Regarding the original implementation you refer to, you can look at my comment to it I made some while ago. The problem is that TakeWhile and LengthWhile have bugs for packed arrays in v. 8.0.0, they are fixed in the sources of 8.0.1 - so, starting from 8.0.1, you can use either mine or Michael's version.
HTH
Edit:
I just noticed that in the post you referred to, you wanted a different syntax. While it would not be very difficult to adopt the approach taken in fastOr to this case, here is a different implementation, which arguably is in closer correspondence with the existing language constructs for this particular syntax. I suggest to use Table and exceptions, since iterators in Table accept the same syntax as you want. Here it is:
ClearAll[AnyTrue, AllTrue];
SetAttributes[{AnyTrue, AllTrue}, HoldAll];
Module[{exany, exall},
AnyTrue[iter : {var_Symbol, lis_List}, expr_] :=
TrueQ[Catch[Table[If[TrueQ[expr], Throw[True, exany]], iter], exany]];
AllTrue[iter : {var_Symbol, lis_List}, expr_] :=
Catch[Table[If[! TrueQ[expr], Throw[False, exall]], iter], exall] =!= False;
];
A few words of explanation: I use Module on the top level since the custom exception tags we need to define just once, can as well do that at definition-time. The way to break out of Table is through exceptions. Not very elegant and induces a small performance hit, but we buy automatic dynamic localization of your iterator variables done by Table, and simplicity. To do this in a safe way, we must tag an exception with a unique tag, so we don't catch some other exception by mistake. I find using Module for creating persistent exception tags to be a very useful trick in general. Now, some examples:
In[40]:= i = 1
Out[40]= 1
In[41]:= AnyTrue[{i, {1, 2, 3, 4, 5}}, i > 3]
Out[41]= True
In[42]:= AnyTrue[{i, {1, 2, 3, 4, 5}}, i > 6]
Out[42]= False
In[43]:= AllTrue[{i, {1, 2, 3, 4, 5}}, i > 3]
Out[43]= False
In[44]:= AllTrue[{i, {1, 2, 3, 4, 5}}, i < 6]
Out[44]= True
In[45]:= AllTrue[{a, {1, 3, 5}}, AnyTrue[{b, {2, 4, 5}}, EvenQ[a + b]]]
Out[45]= True
In[46]:= AnyTrue[{a, {1, 3, 5}}, AllTrue[{b, {2, 4, 5}}, EvenQ[a + b]]]
Out[46]= False
I started with an assignment to i to show that possible global values of iterator variables don't matter - this is taken care of by Table. Finally, note that (as I commented elsewhere), your original signatures for AllTrue and AnyTrue are a bit too restrictive, in the sense that the following does not work:
In[47]:= lst = Range[5];
AllTrue[{i, lst}, i > 3]
Out[48]= AllTrue[{i, lst}, i > 3]
(since the fact that lst represents a list is not known at the pattern-matching time, due to HoldAll attribute). There is no good reason to keep this behavior, so you can just remove the _List checks: AnyTrue[iter : {var_Symbol, lis_}, expr_] and similarly for AllTrue, and this class of use cases will be covered.