Why `Drop` and `Take` do not support a operator form
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.
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