A short mental gauntlet for your scalar sort proposal.

schwern on 2006-02-08T09:50:20

My last entry about what to do with sort in scalar context generated some new proposals. Rather than rebut them one by one, here's a short mental gauntlet for any proposal to run though:

* If sort() should do X, why not map and grep?

* Why not use a user defined function?

* Will it help in the common "return sort ..." gotcha?

* Can you think of common cases where you want to write a function which returns the entire list in list context but only do X in scalar?

Let's take, for example, the proposal to have sort return whether the list was sorted.

* It makes no sense for map and grep.

* It is easily done as a user defined function.

* It doesn't help at all with the "return sort" gotcha.

* I can't think of any reason why I'd write a function that returns either a list or the fact that some internal list is sorted.

That one's shooting fish in a barrel for example purposes. Another was to return either the first or last element of the sorted list and also to return an iterator. I leave those to the reader as its late and I'm tired.


What will the end user see...

Alias on 2006-02-08T11:06:55

I'm throwing in my vote for scalar sort just returning list length.

But why, it seems so pointless and a waste of CPU.

The answer is that from the OUTSIDE of the method call, the user doesn't necesarily know that it went through sort, or whether the data for the list came pre-sorted.

All they know is that they called a method and it returned a list. And the general assumption will be that scalar of it returns the quantity.

As for wasting CPU with the sort, who's to know that the sort doesn't create some form of side-effect.

So rather than going to some form of magic (first/last/etc) I say we just go for the most simple, straight forward, predictable, and symmetrical solution, and just return the number of elements.

Re:

Aristotle on 2006-02-08T18:22:13

I’d say to skip sorting and return the number of elements efficiently. It would help the common case (return sort in scalar context), and I’ve never written a sort block with side effects, can’t imagine what it’d be useful for, or have seen any such thing in anyone else’s code, whether on PerlMonks or the CPAN.

I believe that unlike being undefined in scalar context, not sorting in scalar context is a kind of surprise that’s not very surprising, and if anyone really needs to use side effects in the sort block, they can still enforce list context otherwise. Having to do that would warn onlookers that something really unusual is going on, too, which I consider the right Huffman coding/cost distribution for this feature.

Oh no, side effects.

schwern on 2006-02-10T21:41:52

Someone's going to bring up side effects and point out that we're swapping one gotcha for another. The new gotcha being "sort in scalar context will not execute your code block, so if it has side effects they will not occur".

The defense to that is that side effects in sort are so rare that this is hardly a real world gotcha. Does anyone put side effects in their sort?

Re:

Aristotle on 2006-02-10T23:18:51

I wouldn’t worry about that.

First: we’re not trading gotchas:

$ perl -le'@x = sort {++$_; $a cmp $b} qw(foo bar baz); print $_ || "nada"'
3
$ perl -le'$x = sort {++$_; $a cmp $b} qw(foo bar baz); print $_ || "nada"'
nada

This is already part of the “sort in scalar context is undefined” gotcha.

Second – and as I’ve said –, I’ve never wanted to use side effects in a sort block, I can’t imagine a good reason that needs it, and I’ve never seen anyone else do it on PerlMonks or other fora.

For obvious reasons I won’t claim with certainty that noone does this. But I’d be willing to bet money that the number of instances where this would cause a problem are so vanishingly rare as to be ignorable.

Unfortunately the CPAN code search currently throws 500 Internal Server Error when searching on phrases, and I have no minicpan set up either. So someone else will have to look for hard numbers, if they’re necessary.

Meta note

Aristotle on 2006-02-08T18:10:19

I think you wanted to link http://use.perl.org/user/schwern/journal/28577, not http://use.perl.org/user/schwern/journal/.

Re:Meta note

schwern on 2006-02-10T21:38:39

Thanks, I've fixed that.

__

Abigail on 2006-02-09T21:19:21

If sort() should do X, why not map and grep?
That's easy. With map and grep, you can't determine the size of the output list purely from the size of the input list. So, having map and grep return the sizes of their output lists (if the functions were run in list context) in scalar context make sense.

For sort to ignore its first (optional) argument, and have it act as a counting function doesn't make any sense. We already have a function that does this: the list assignment in scalar context.

Re:

Aristotle on 2006-02-10T23:32:31

It’s not that having sort act as a counting function is useful. It’s that no credible argument can be made against it, and that no suggestions for any sensible alternative have been forthcoming in 10 years.

return should do what I mean

mr_bean on 2006-02-10T08:49:39

I just tried to return an array and assign it to
a scalar. I couldn't understand why I wasn't
getting a reference to the array.

Re:return should do what I mean

Ovid on 2006-02-10T15:26:02

That's actually the default behavior in Perl 6. You're jumping the gun :)

Jumping the gun Re:return should do what I mean

n1vux on 2006-02-13T19:52:54

Well, if the default behavior in Perl 6 is to en-reference the returned /l/i/s/t/ array in scalar context, perhaps with all the Perl6isms creeping into Perl 5.10 it would be consistent to "use feature :scalar_sort;" should allow "return sort {f} @A" to morph to "return [sort {f} @A]" in scalar context ?

/me Ducks and covers, looking for nomex rug to finish the drop-and-roll with ... :-)

undef still seems safest ...