19
$\begingroup$

# is the first argument of a pure function, #n the nth, ## are all variables and ##n all beginning with the nth variable.

Now, I would like to access the last argument. In a list, this would be mylist[[-1]]. Additionally, I would like to access all but the last argument which would be Drop[mylist,-1] for a list. Can this be achieved and if yes, how?

The reason for this is that I would like to pass all but the last argument to another function which can take different numbers of input arguments. Of course, I could change the order of the arguments, taking the last argument first, but this makes the arguments appear in a less logical order.

Example:

f1[a_:0,b_]:=a+b;
f2[a_:0,b_,c_]:=f1[a,b]*c

If I wanted to write f2 as a pure function, how would I do this?

$\endgroup$
  • 6
    $\begingroup$ f = {##}[[-1]] &? $\endgroup$ – Henrik Schumacher Jan 10 '18 at 20:45
  • $\begingroup$ @Henrik that's too easy. Could have never thought of that! Thank you so much! $\endgroup$ – riddleculous Jan 10 '18 at 20:54
  • 1
    $\begingroup$ f2 = With[{args = {##}}, f1 @@ Most[args] Last[args]] & $\endgroup$ – user42582 Jan 10 '18 at 20:57
  • 5
    $\begingroup$ @riddleculous why do you insist on a pure function? What about f2[a_:0, b__,c_]:=f1[a,b]*c, notice double _ next to b, it stands for one or more arguments. $\endgroup$ – Kuba Jan 10 '18 at 21:24
  • 3
    $\begingroup$ @riddleculous sure, whatever fits your needs. Btw, I just realized I asked once a closely related question: Why there is no SlotSequence (##) form analogical to #[[ ;; n]] $\endgroup$ – Kuba Jan 11 '18 at 8:39
19
$\begingroup$

So, maybe f = {##}[[-1]] & is what you are looking for.

$\endgroup$
  • $\begingroup$ So the solution of the example would be f2 = f1 @@ {##}[[;; -2]]*{##}[[-1]] & resp. f2 = f1 @@ Most[{##}]*Last[{##}] &. $\endgroup$ – riddleculous Jan 10 '18 at 21:15
7
$\begingroup$

Defining f2 in terms of f1 and c can be also obtained by using

f2 = With[{args = {##}}, f1 @@ Most[args] Last[args]] &

although, admittedly, using Part seems more natural.

Another way to achieve the same end is using patterns:

f2 = With[{args = {##}}, args /. {x__, y_} :> f1@x y] &

Although both definitions 'work', they feel like 'workarounds'; It would be really interesting to see a purely functional solution to this problem, if that is possible that is.

$\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.