I would like to set

evenFunction[f_][a_, b_, c_, ...] = f[Abs[a], Abs[b], Abs[c], ...]

I have come up with two ways to do this so far.

  1. Use pure functions

    evenFunction = Function[{f}, f[Sequence @@ Abs[{##}]] &]
  2. Use pattern matching

    evenFunction[f_][x__] := f[Sequence @@ (Abs[{x}])]

What is bothering me is that, in both cases, I first have to turn the arguments into a list, and then back to a sequence. Is there a way without this?

  • 3
    $\begingroup$ evenFunction[f_][x__] := f @@ Abs[{x}] is a bit simpler. $\endgroup$
    – Szabolcs
    Oct 2 '15 at 15:52
  • $\begingroup$ Simply evenFunction[f_][x__] := Abs /@ f[x] would work if Map held its arguments unevaluated $\endgroup$
    – user
    Oct 2 '15 at 16:23
  • $\begingroup$ I like @Szabolcs's answer the best, but you could always force the unevaluation using evenFunction[f_][a__] := ReleaseHold@Map[Abs, Hold@f@a, {2}]. I don't think there's any reason why you would do this instead though. $\endgroup$
    – march
    Oct 2 '15 at 17:12

Well, the following meets your formal requirements

evenFunction[f_][args__] := f[Abs /@ Unevaluated[args]]

evenFunction[even][a, b, c]
even[Abs[a], Abs[b], Abs[c]]

But is it really better than

evenFunction[f_][args__] := f @@ Abs[{args}]

I, myself, would choose the 2nd version over the 1st.


It is not necessary to set the attribute SequenceHold as I originally did.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.