11
$\begingroup$

Since Mathematica 10 introduced the operator form, I have been a big fan of it. Whenever I use some buit-in functions, I first look up whether they support operator form.

To me, it was quite surprising to find that the two seemingly innocent functions Drop and Take do not support operator form as their typical use case requires two arguments and thus making them operator forms, if only one argument is given, does not seem to result in any ambiguity.

I later found that they actually accept one argument. Their current behaviour, when only one argument is given, is that they work as Identity. This is probably the reason why they cannot support operator form. What is the underlying reason for this behaviour and is there any chance they will support the operator form in later releases?

$\endgroup$

2 Answers 2

13
$\begingroup$

If they changed it, I'm pretty sure it would break some code somewhere, possibly in an obscure and hard to debug way. So it's a good thing that they didn't change it.


Why does the one argument behaviour make sense? Take a look at the 4th signature in the documentation:

Take[list, seq1, seq2, ...] gives a nested list in which elements specified by seq_i are taken at level i in list.

This is fully consistent with taking the whole list if there are no sequences specified. A function that uses Take might be passing it a Sequence[seq1, seq2, ...] which is assumed to be of arbitrary length (length 0 included).


BTW we already have a comparable operator form: Extract[{;;10}] is an operator that takes the 10 first elements of an expression.

$\endgroup$
1
  • 5
    $\begingroup$ Exactly. Vararg functions like Take and Drop cannot have an operator form. $\endgroup$
    – Stefan R
    Sep 21, 2015 at 19:17
4
$\begingroup$

Yes, Take and Drop are kernel functions and messing with them will probably break things. But at least in principle, it is not entirely true that varargs symbols can't have operator forms.

For example, we can specify a single argument operator for Take which works just fine:

Unprotect[Take];

Take[i_Integer] := Function[list, Take[list, i]];
Take[UpTo[i_Integer]] /; NonNegative[i] := Function[list, Take[list, UpTo[i]]]

lst = {{1}, {2, 3}, {}, {4, {5, 6}}, xyz[7, 8, 9]}    
Take[-2]@lst[[-1]]    
Take[UpTo[2]] /@ lst

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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