1

I'm trying to take a conditional expression like "3 > 1" as an argument for a function but without its evaluation before being passed. HoldForm works fine in situations like this:

*In[1]:=*  3 > 1

*Out[1]=*  True


*In[2]:=*  3 > 1 // HoldForm

*Out[2]=*  3 > 1

However, it doesn't work if I use lists....

*In[3]:=* a = {3, 2, 1};
b = {1, 2, 3};

*In[4]:=* a[[1]] > b[[1]]

*Out[4]=*  True

*In[5]:=* a[[1]] > b[[1]] // HoldForm

*Out[5]=* a[[1]] > b[[1]] 

I would like to have '3 > 1' as my output for Out[5]. Using Evaluate[a[[1]]], etc., does not work. Thanks for your help.

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
Kendall
  • 21
  • 2

1 Answers1

1

"I'm trying to take a conditional expression like "3 > 1" as an argument for a function but without its evaluation before being passed" -- that sounds like you need a hold Attribute on your function, e.g. HoldFirst.

For your last example you appear to want a way to evaluate Part but keep Greater unevaluated. If you are using Mathematica 10 or later Inactivate may be a good choice:

a = {3, 2, 1};
b = {1, 2, 3};

SetAttributes[f1, HoldFirst]

f1[bool_] := Inactivate[bool, Greater | Less | GreaterEqual | LessEqual | Inequality]


f1[a[[1]] > b[[1]]]

FullForm[%]
3 > 1

Inactive[Greater][3,1]

Another approach is to use HoldForm and specifically evaluate Part:

SetAttributes[f2, HoldFirst]
f2[bool_] := HoldForm[bool] /. p_Part :> RuleCondition[p]

f2[a[[1]] > b[[1]]]
3 > 1   (* HoldForm *)

For an explanation of RuleCondition see:

If you wish to use this output as input that will fully evaluate you can substitute Defer for HoldForm.

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371