Except that in the case of sort, it's behaviour isn't documented. :(
Personally, I think it's a _good_ idea that sort() isn't doing
anything in scalar context. This _is_ useful in situations where
you are doing 'return sort LIST'. Because this means that if you
call such a sub in void or scalar context, no resources are wasted
by doing a sort.
Here's is a doc-patch:
--- pod/perlfunc.pod.orig Wed Jun 12 11:25:04 2002
+++ pod/perlfunc.pod Wed Jun 12 11:26:46 2002
@@ -4483,7 +4483,9 @@
=item sort LIST
-Sorts the LIST and returns the sorted list value. If SUBNAME or BLOCK
+In list context, this sorts the LIST and returns the sorted list value.
+In scalar context, sort doesn't do anything and an undefined value is
+returned. If SUBNAME or BLOCK
is omitted, C<sort>s in standard string comparison order. If SUBNAME is
specified, it gives the name of a subroutine that returns an integer
less than, equal to, or greater than C<0>, depending on how the elements
Thanks, applied.
> --- pod/perlfunc.pod.orig Wed Jun 12 11:25:04 2002
> +++ pod/perlfunc.pod Wed Jun 12 11:26:46 2002
> @@ -4483,7 +4483,9 @@
>
> =item sort LIST
>
> -Sorts the LIST and returns the sorted list value. If SUBNAME or BLOCK
> +In list context, this sorts the LIST and returns the sorted list value.
> +In scalar context, sort doesn't do anything and an undefined value is
> +returned. If SUBNAME or BLOCK
> is omitted, C<sort>s in standard string comparison order. If SUBNAME is
> specified, it gives the name of a subroutine that returns an integer
> less than, equal to, or greater than C<0>, depending on how the elements
--
$jhi++; # http://www.iki.fi/jhi/
# There is this special biologist word we use for 'stable'.
# It is 'dead'. -- Jack Cohen
Seems to me that it would be less surprising and more useful for it to
behave like an identity map() does in scalar context, especially
considering C<return sort ...>. i.e., do no sorting, but _return the
number of items in the list_.
OTOH, it would be all right if we were to document that it
_currently_ happens to return undef in scalar context because we're
reserving that interface to do something nice with it in future.
However, I don't know that it is possible for us to do something better
than returning the number of elements.
Sarathy
gs...@ActiveState.com
Well, that depends on how you define "better". :-)
In Perl 6 scalar sort is likely to return a reference to an anonymous
sorted list (or possibly an iterator that looks like an anonymous
sorted list). If that reference is evaluated in a numeric context,
it produces the length. If it's evaluated in a string context, it
produces a string representation of the list. In a boolean context,
it'd be true if there were any elements in the list. To the extent
that we can detect those contexts, we can optimize away the sort,
not to mention the construction of the anonymous list.
So I'd recommend not doing anything inconsistent with that. On the
other hand, I'd not recommend doing anything consistent with it
either, since the rest of Perl 5 is not designed to handle references
the way Perl 6 will. If our goal is to simplify the translator,
then it would be best to leave the behavior as it currently is.
If the goal is to make Perl 5 work more like Perl 6, then returning a
magical scalar that knows to do different things in numeric, string,
or reference context would be appropriate. But I doubt scalar sort
is really worth that much effort at this point. Maybe as part of a
more general effort. But if there is a more general effort to sidle
towards Perl 6 semantics in 5.10, we have to be careful. Using magic
to emulate vtables could be a recipe for slowth.
Larry
sort knows that it's not in list context and can simply not bother
with the sort yet still return a useful value to avoid the "return sort
@foo" gotcha. I took a shot writing a patch, but there's something I'm
missing because I kept getting "Can't coerce ARRAY into integer". Possibly
something about ck_sort(), and that's out of my league.
--- pp_sort.c 2002/06/11 19:10:54 1.1
+++ pp_sort.c 2002/06/12 16:42:16
@@ -1425,8 +1425,9 @@
I32 is_xsub = 0;
if (gimme != G_ARRAY) {
- SP = MARK;
- RETPUSHUNDEF;
+ dTARGET;
+ SETi(SP - ORIGMARK);
+ RETURN;
}
ENTER;
--
This sig file temporarily out of order.
Patch below my sig.
--Brent Dax <bren...@cpan.org>
@roles=map {"Parrot $_"} qw(embedding regexen Configure)
Early in the series, Patrick Stewart came up to us and asked how warp
drive worked. We explained some of the hypothetical principles . . .
"Nonsense," Patrick declared. "All you have to do is say, 'Engage.'"
--Star Trek: The Next Generation Technical Manual
--- perlfunc.pod.old Wed Jun 12 11:02:28 2002
+++ perlfunc.pod Wed Jun 12 11:05:28 2002
@@ -4510,6 +4510,9 @@
You also cannot exit out of the sort block or subroutine using any of
the
loop control operators described in L<perlsyn> or with C<goto>.
+In scalar context, C<sort> returns C<undef>. However, this behavior is
likely
+to change in future versions of Perl, so it would be best not to depend
upon it.
+
When C<use locale> is in effect, C<sort LIST> sorts LIST according to
the
current collation locale. See L<perllocale>.
Fine with me, but I'd rather have "behavior in scalar context is undefined"
rather than "in scalar context, it does yadda-yadda-yadda" because the
latter may silently implies usefulness.
Sarathy
gs...@ActiveState.com
Fine, be that way. ;^)
--- perlfunc.pod.old Wed Jun 12 11:02:28 2002
+++ perlfunc.pod Wed Jun 12 11:27:42 2002
@@ -4510,6 +4510,9 @@
You also cannot exit out of the sort block or subroutine using any of
the
loop control operators described in L<perlsyn> or with C<goto>.
+The behavior of C<sort> in scalar context is currently undefined. This
may
+change in a future version of Perl.
+
When C<use locale> is in effect, C<sort LIST> sorts LIST according to
the
current collation locale. See L<perllocale>.
--Brent Dax <bren...@cpan.org>
That was my position last time we had a long discussion on this -
that "something nice" being return first (or last) element that we
would get with a sort. equivalent of
my ($a) = sort ...
or
my $a = (sort...)[-1];
Except of course we don't need to do the full sort - but just a
binary search for the smallest/largest element. (Like knock-out
stage of certain topical sporting events!)
That isn't a trivial piece of code, so no one has written it yet.
And that still leaves us with the related "sort in a void context"
case to warn and think of a meaning for (the obvious one being
an in-place sort...)
So for 5.8 a tweak to the above doc patch ?
>However, I don't know that it is possible for us to do something better
>than returning the number of elements.
>
>
>Sarathy
>gs...@ActiveState.com
--
Nick Ing-Simmons
http://www.ni-s.u-net.com/
Hmm, so Michael's suggestion of returning the length is going to
be perl6-ish in two of the three cases. And the other case
"string representation of the list" is not any easy thing to do for perl5.
That drastic of a change in semantics should probably not be controlled
by the presence of an absence. The sort operator provides a view of
an existing array without changing the array itself. Sorting in place
should be a different operator or method, I believe. Though in Perl 6
(you're gonna get tired that phrase :-) there's no need for such an
operator because you can just bind the sorted view back onto the array:
@array := sort @array;
That doesn't imply a copy as a straight = would.
Of course, it's still potentially more readable to say
sort_in_place @array;
But a bare
sort @array;
may or may not have an easily determined context. It would be next
to criminal to sort a module's array that wasn't expecting it merely
because somebody accidentally called the routine in a void context.
This is much worse than returning the length of the array in numeric
context.
Larry
I think one of the ideas thrown about once upon a time was that sort
in void context _having a single array reference as its argument_
would do in-place.
Agreed - you are much better at language design than I am :-) - particularly
when my day-job these days is dominated by "clever" hardware tricks,
puts me in quite the wrong frame of mind.