1
$\begingroup$

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?

$\endgroup$
  • 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
9
$\begingroup$

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.

Update

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

$\endgroup$

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.