6
$\begingroup$

I'm experimenting with the Through function. I suspect there is a way to use that function to obtain both the mean and difference of two values. But this doesn't work:

 Through[{Mean, Subtract}[1175., 247.]]

It reports the error:

Mean::argx: Mean called with 2 arguments; 1 argument is expected.

The corollary raises a similar error:

 Through[{Mean, Subtract}[{1175., 247.}]]

Subtract::argr: Subtract called with 1 argument; 2 arguments are expected.

I think the problem is caused by the Mean function taking only one argument as a list of values, whereas Subtract takes its arguments as two separate values. It reminds me of destructuring as found in other languages, hence the title. Feel free to edit that for something more descriptive.

Is there a way to do what I try? Since I'm learning the Wolfram Language, I would prefer a solution working in the general case rather that a solution specific to the Mean and Subtract functions.

$\endgroup$
7
$\begingroup$

Here is one way to do what you ask

Through[{Mean@*List, Subtract}[1175., 247.]]
(* {711., 928.}*)

This works by using Composition (in its operator form) to apply List and then Mean to the inputs.

You could also "Lift" (is that the correct functional programming term?) Subtract to operate on lists (as suggested by @LukasLang)

Through[{Mean, Apply[Subtract]}[{1175., 247.}]]
(* {711., 928.}*)
| improve this answer | |
$\endgroup$
  • 1
    $\begingroup$ I knew there was some @... notation that would be involved. Thank @mikado. Could you ellaborate a little on the way it works? $\endgroup$ – Sylvain Leroux Dec 8 '19 at 16:38
  • 2
    $\begingroup$ It might be worth to add Through[{Mean, Apply@Subtract}[1175., 247.]] as the "inverse" approach (where a list is supplied and converted to a sequence of arguments) $\endgroup$ – Lukas Lang Dec 9 '19 at 10:46
  • 1
    $\begingroup$ @Lukas, Thank you! I took the liberty of editing the Mikado's answer to quote your comment (I also fixed a small typo in the code where you wrote [1175., 247.] for [{1175., 247.}]. Feel free to revert that edit if you desagree. $\endgroup$ – Sylvain Leroux Dec 9 '19 at 15:16
4
$\begingroup$

One way is to force Mean to aggregate the two arguments into a list,

Through[{Mean[{##}] &, Subtract}[1175., 247.]]

Please notice the double ##. With only one # the mean will be applied only on the first argument.

Or you can modify the call to Subtract to force it to break the list into separate arguments:

Through[{Mean, Subtract[#[[1]], #[[2]]] &}[{1175., 247.}]]
| improve this answer | |
$\endgroup$
  • $\begingroup$ I saw something like that already. It wraps Mean in a lambda function. Am I right? $\endgroup$ – Sylvain Leroux Dec 8 '19 at 16:39
  • $\begingroup$ I'm not 100% sure I know what a lambda function is... the first one operates by placing the argument 1175., 247 where the # is, so that the two numbers are placed into a list (as required by Mean). The second works the opposite, by separating the list argument into its two components (as required by Subtract). $\endgroup$ – bill s Dec 8 '19 at 16:43
  • 1
    $\begingroup$ @SylvainLeroux Mathematica's equivalent of a lambda function is referred to as a "Pure" function. See the help on Function for an explanation. $\endgroup$ – mikado Dec 8 '19 at 16:47
  • 2
    $\begingroup$ I think the first one should be Mean[{##}]& - otherwise, you will keep only the first argument $\endgroup$ – Lukas Lang Dec 9 '19 at 10:45
  • $\begingroup$ You're right @Lukas. I' editing Bill's answer with that. I add en extra explntion of the problem, since one-character edits are not allowed. Feel free to edit that if I was wrong. $\endgroup$ – Sylvain Leroux Dec 9 '19 at 15:22

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.