9

This must be a duplicate but I can't find any related post. I want to pass two arguments to a function using postfix syntax like

f[a_,b_]:=a+b;
1,2//f

More generally, can somebody explain to me in better detail how I can use these kind of constructions: @f , ~~f~~, and //f

dionys
  • 4,321
  • 1
  • 19
  • 46
Kafkarudo
  • 619
  • 5
  • 9

3 Answers3

13

Let me start with the second question first as it is more direct. You can see for yourself how these inputs work:

f @ x
x ~f~ y
x // f
f[x]
f[x, y]
f[x]

The first and third only work with a single argument. Similar to but distinct from the first is @@ which is shorthand for Apply, and it allows:

f @@ {x, y}
f[x, y]

Here the Head List is replaced with f. For more clarity see: Scan vs. Map vs. Apply

With the single-argument forms you can use Sequence to insert multiple arguments, but only if the function (f) does not have the Attribute SequenceHold or HoldAllComplete:

f @ Sequence[x, y]
Sequence[x, y] // f
f[x, y]
f[x, y]

And an example of where this will not work:

Rule @ Sequence[x, y]

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

Rule[Sequence[x, y]]

If you wish to use a multi-argument function with // application you can make it a parametrized, SubValues, or operator form function, all meaning essentially the same thing. See:

A very simple example:

f[a__][x_] := g[a, x]

Now:

y // f[x]
g[x, y]
x // f[1, 2, 3]
g[1, 2, 3, x]

See the first bulleted link above for more examples and theory.

Related:

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
  • 1
    Note that you can always use x // f[#, ...]& if you need to supply extra arguments like in Table[{i, 2^i}, {i, 24, 0, -1}] // TableForm[#, TableHeadings -> {None, {"i", "2^i"}}] & – Ludovic Kuty Feb 10 '17 at 12:08
  • 1
    @lkuty Oh yes, that's a very useful pattern. It is mentioned in an answer to one of the questions I linked: http://mathematica.stackexchange.com/a/6957/121. I make use of it quite often, e.g. http://mathematica.stackexchange.com/a/136196/121 – Mr.Wizard Feb 10 '17 at 12:29
7

(Just answering the first question. Others have answered the second question thoroughly.)

It's worth mentioning that you can do

{x,y} // (f @@ #) &

f[x,y]

(No parentheses needed, but I added them for clarity.)

You could even make your own function to do this (slightly) more compactly, especially if you have trouble remembering the @'s and #'s :

ClearAll[pf]
pf[ argList_, f_ ] := f @@ argList

Then you can do what you want using an infix operator:

{x,y} ~pf~ f

f[x,y]

Edit:

Lately I've taken to writing my first example above as

{x,y} // Apply[f] 

or

{x,y} // Apply@f

which I fine somewhat more readable, particularly when there are other pure functions involved. Note that this uses the operator form of Apply.

jjc385
  • 3,473
  • 1
  • 17
  • 29
3

According to my basic understand of these notations:

For infix notation, the function must be a binary operator, e.g.

g[x_, y_] := x^2 - y^2;

Then

5~g~2

Gives

25-4=21

For postfix notation, the function must take one argument

f[{x_,y_}]:=x^2-y^2

So

{5,2}//f

gives 21

John McGee
  • 2,538
  • 11
  • 15