6
$\begingroup$

Suppose I wanted to define a number of functions that accepts expressions of the form: myFcn[x_ > y_]:= {...does something...}; myFcn[x_ >= y_]:= {...does something...}; myFcn[x_ == y_]:= {...does something else...}; etc...

But, when == is used to call the function, e.g. C = myFcn[A == B], A == B is evaluated before it has a chance to be passed on to myFcn. This does not happen with other operators, like <, <=, >, so I was surprised when it did not worked.

I am aware that I can use C = myFcn[Unevaluated[A==B]] to delay evaluation of expression, but this would have to be "rigged" in each function call externally.

Is there a more elegant way of defining the functions so that == could be used just as other operators?

Many thanks.

$\endgroup$
8
  • 4
    $\begingroup$ myFcn should have a Hold* attribute to do what you want. $\endgroup$ Commented Jul 1, 2015 at 2:56
  • 1
    $\begingroup$ Alternatively, you could use Conditions's such as myFcn[x_ , y_] /; x < y := { ...does stuff...}, but unfortunately I don't have time to write that up right now. $\endgroup$
    – march
    Commented Jul 1, 2015 at 3:11
  • $\begingroup$ I think < and == should behave the same way in this respect, though, so the issue you're seeing may stem from some other source. $\endgroup$ Commented Jul 1, 2015 at 3:15
  • $\begingroup$ @Guesswhoitis. Thanks! It seems to be exactly what I need. I used SetAttributes[myFcn, HoldAll] in this application. Would you be so kind to elaborate in case we want to hold one particular input argument out of many unevaluated as oppose to all of them (HoldAll), the first one (HoldFirst) or all but the first (HoldRest), As in X = myFcn[A, B, C==D, E, ...], holding C==D unevaluated while all others use default behavior. $\endgroup$
    – AlexanderF
    Commented Jul 1, 2015 at 4:08
  • 1
    $\begingroup$ You should have a look at the tutorial. $\endgroup$
    – Jens
    Commented Jul 1, 2015 at 5:20

1 Answer 1

2
$\begingroup$
SetAttributes[myFcn, HoldAll]

myFcn[f_[x_, y_]] := Switch[f,
  Greater, {1, SymbolName[f], x, y},
  GreaterEqual, {2, SymbolName[f], x, y},
  Equal, {3, SymbolName[f], x, y}
  ]

myFcn[A > B]
(* {1, "Greater", A, B} *)

myFcn[A >= B]
(* {2, "GreaterEqual", A, B} *)

myFcn[A == B]
(* {3, "Equal", A, B} *)
$\endgroup$
1
  • $\begingroup$ Thanks! This seems to be the way to go. Haven't tested it for performance but it gets the job done in an elegant and readable way! +1 $\endgroup$
    – AlexanderF
    Commented Oct 14, 2015 at 15:32

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.