# Define antisymmetric function [duplicate]

This question already has an answer here:

Assume I'm trying to naively define an antisymmetric functionf[x_, y_] := -f[y, x]and assign it a value at some point f[1, 2] = 1;. After this, calling {f[1, 2], f[2, 1]} gives {1,-1} as desired. However, evaluating f[1,3] leads to an infinite recursion with result Hold[f[1, 3]].

My goal is to write a definition of f[x,y] in such a way that it tries both variants f[x,y] and -f[y,x] to see if a value is assigned for any of them. If it is, the function should evaluate to this value. If it isn't, then it should stay unevaluated but avoid the infinite loop.

## marked as duplicate by Michael E2, MarcoB, Jens, AccidentalFourierTransform, halirutan♦Jul 10 '18 at 23:09

This works as requested:

Clear@f
Module[
{enabled = True},
f[x_, y_] /; enabled := Block[
{enabled = False},
With[
{res = f[y, x]},
-res /; res =!= Unevaluated@f[y, x]
]
]
]


Testing it:

f[1, 2]
(* f[1, 2] *)

f[2, 1] = 2
(* 2 *)

f[1, 2]
(* -2 *)

f[2, 1]
(* 2 *)


### How

There are a few things that make this work:

• The Module/Condition(/;)/Block combination ensures that the definition is not infinitely reinserted into itself (you can remove the Module if you don't worry about the enabled flag colliding with anything
• In this setting, we can safely evaluate f[y,x] is safe.
• The last part is the second Condition(res =!= Unevaluated@…), which only applies the "flipping" of arguments if it actually evaluates to something else
• This works in my actual problem, great! The fact that x==Unevaluated[x] gives True seems counter-intuitive to me. I was thinking about how to check whether some change in expression really occurs, and this is the way to go. – Weather Report Jul 6 '18 at 6:36