custom function with non-standard evaluation (behaves like Table)

|▌冷眼眸甩不掉的悲伤 提交于 2019-11-29 05:16:16

How about this?

SetAttributes[AnyTrue, HoldAll];

AnyTrue[expr_, {var_Symbol, lis_List}] :=
  LengthWhile[lis, 
    Not[TrueQ[ReleaseHold[Hold[expr] /. HoldPattern[var] -> #]]] &
  ] < Length[lis]

Includes short-circuiting via LengthWhile and keeps everything held where necessary so that things work as expected with var has a value outside the function:

In[161]:= x = 777;

In[162]:= AnyTrue[Print["x=", x]; x == 3, {x, {1, 2, 3, 4, 5}}]
During evaluation of In[162]:= x=1
During evaluation of In[162]:= x=2    
During evaluation of In[162]:= x=3
Out[162]= True

The built-in Or is short-circuiting, too, for what it's worth. (but I realize building up the unevaluated terms with e.g. Table is a pain):

In[173]:= Or[Print[1];True, Print[2];False]
During evaluation of In[173]:= 1
Out[173]= True

This doesn't match your spec but I often use the following utility functions, which are similar to what you have in mind (they use pure functions instead of expressions with a specified variable) and also do short-circuiting:

some[f_, l_List] := True ===                (* Whether f applied to some      *)
  Scan[If[f[#], Return[True]]&, l];         (*  element of list is True.      *)

every[f_, l_List] := Null ===               (* Similarly, And @@ f/@l         *)
  Scan[If[!f[#], Return[False]]&, l];       (*  (but with lazy evaluation).   *)

For example, Michael Pilat's example would become this:

In[1]:= some[(Print["x=", #]; # == 3)&, {1, 2, 3, 4, 5}]

   During evaluation of In[1]:= x=1
   During evaluation of In[1]:= x=2    
   During evaluation of In[1]:= x=3
Out[1]= True
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!