Why does sort return undef in scalar context ?

Discussion in 'Perl Misc' started by Willem, Aug 29, 2011.

  1. Willem

    Willem Guest

    Today I got bitten by a very strange bug/feature:

    I wrote a function that returned a sorted list of things.
    This function was used in several places, sometimes to use the things in
    some way, and in one place just to check if it returned any things.

    For example:

    ....
    for my $s (get_sorted_things($foo)) {
    do_something_with($s);
    }
    ....
    if (get_sorted_things($bar)) {
    warn "There were things for $bar!\n";
    }
    ....
    sub get_sorted_things
    {
    my %unique = map { $_->Key => $_ } get_things();
    return sort { $a->Property cmp $b->Property } values %unique;
    }

    And, because somebody decided that sort should always return undef
    when called in scalar context, this does not work!

    Why was it decided that sort returns undef in scalar context ?
    IMO it is much more logical and consistent to have it return the
    number of objects in the list that is to be sorted (it doesn't even
    need to sort them for that).


    SaSW, Willem
    --
    Disclaimer: I am in no way responsible for any of the statements
    made in the above text. For all I know I might be
    drugged or something..
    No I'm not paranoid. You all think I'm paranoid, don't you !
    #EOT
     
    Willem, Aug 29, 2011
    #1
    1. Advertising

  2. Willem

    Guest

    On Mon, 29 Aug 2011 20:36:26 +0000 (UTC), Willem <> wrote:

    >Today I got bitten by a very strange bug/feature:
    >
    >I wrote a function that returned a sorted list of things.
    >This function was used in several places, sometimes to use the things in
    >some way, and in one place just to check if it returned any things.
    >
    >For example:
    >
    >...
    >for my $s (get_sorted_things($foo)) {
    > do_something_with($s);
    >}
    >...
    >if (get_sorted_things($bar)) {
    > warn "There were things for $bar!\n";
    >}
    >...
    >sub get_sorted_things
    >{
    > my %unique = map { $_->Key => $_ } get_things();
    > return sort { $a->Property cmp $b->Property } values %unique;
    >}
    >
    >And, because somebody decided that sort should always return undef
    >when called in scalar context, this does not work!
    >
    >Why was it decided that sort returns undef in scalar context ?
    >IMO it is much more logical and consistent to have it return the
    >number of objects in the list that is to be sorted (it doesn't even
    > need to sort them for that).
    >
    >


    I don't know why this is the case, but you should fix it up in the
    function that wraps the return of sort().

    $ret = get_sort_stuff('aa'=>8, 'bb' => 1 );
    print "a_ret = $ret\n\n";

    @ret = get_sort_stuff('aa'=>8, 'bb' => 1 );
    print "b_ret = @ret\n\n";

    $ret = get_sort_stuff();
    print "c_ret = $ret\n\n";

    @ret = get_sort_stuff();
    print "d_ret = @ret\n\n";

    if (get_sort_stuff('aa'=>8, 'bb' => 1 )) {
    print "conditional > 0\n\n"
    }

    if (!get_sort_stuff()) {
    print "conditional = 0\n"
    }


    sub get_sort_stuff {
    my %unique = @_;
    print wantarray ? 'wantarray = 1' : 'wantarray = 0', "\n";
    return wantarray ?
    sort values %unique :
    values %unique ;
    }

    -sln
     
    , Aug 29, 2011
    #2
    1. Advertising

  3. Willem <> writes:

    [...]

    > for my $s (get_sorted_things($foo)) {
    > do_something_with($s);
    > }
    > ...
    > if (get_sorted_things($bar)) {
    > warn "There were things for $bar!\n";
    > }
    > ...
    > sub get_sorted_things
    > {
    > my %unique = map { $_->Key => $_ } get_things();
    > return sort { $a->Property cmp $b->Property } values %unique;
    > }
    >
    > And, because somebody decided that sort should always return undef
    > when called in scalar context, this does not work!


    The sort documentation actually says

    sort SUBNAME LIST
    sort BLOCK LIST
    sort LIST

    In list context, this sorts the LIST and returns the
    sorted list value. In scalar context, the behaviour of
    "sort()" is undefined.

    > Why was it decided that sort returns undef in scalar context ?
    > IMO it is much more logical and consistent to have it return the
    > number of objects in the list that is to be sorted


    'Much more logical' seems like a matter of opinion here. But it is
    certainly not 'more consistent since evaluating a list in scalar
    context returns the final element "as with the C comma operator"
    (perldata(1)). Evaluating an array in scalar context yields the number
    of elements in the array. The keys function behaves in this way but
    expecting that to return the number of keys in a scalar context makes
    IMHO more sense than expecting sort to return the number of items to
    be sorted in a scalar context.
     
    Rainer Weikusat, Aug 30, 2011
    #3
  4. Willem <> writes:
    > Today I got bitten by a very strange bug/feature:
    >
    > I wrote a function that returned a sorted list of things.
    > This function was used in several places, sometimes to use the things in
    > some way, and in one place just to check if it returned any things.
    >
    > For example:
    >
    > ...
    > for my $s (get_sorted_things($foo)) {
    > do_something_with($s);
    > }
    > ...
    > if (get_sorted_things($bar)) {
    > warn "There were things for $bar!\n";
    > }
    > ...
    > sub get_sorted_things
    > {
    > my %unique = map { $_->Key => $_ } get_things();
    > return sort { $a->Property cmp $b->Property } values %unique;
    > }
    >
    > And, because somebody decided that sort should always return undef
    > when called in scalar context, this does not work!
    >
    > Why was it decided that sort returns undef in scalar context ?
    > IMO it is much more logical and consistent to have it return the
    > number of objects in the list that is to be sorted (it doesn't even
    > need to sort them for that).


    Any "sensible" behavior for sort() in scalar context would not (need to)
    sort anything -- which implies to me that calling sort() in such a
    context doesn't make much sense. Similarly, "get_sorted_things($bar)"
    would be better written as some other operation on $bar that doesn't
    imply an unnecessary expensive sort.

    As Rainer Weikusat points out, the behavior of sort() in scalar context
    is actually undefined. IMHO it would make more sense for it to be an
    error.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Aug 30, 2011
    #4
  5. Willem

    Willem Guest

    Tad McClellan wrote:
    ) Willem <> wrote:
    )> Today I got bitten by a very strange bug/feature:
    )>
    )> I wrote a function that returned a sorted list of things.
    <snip>
    )> sub get_sorted_things
    )> {
    )> my %unique = map { $_->Key => $_ } get_things();
    )> return sort { $a->Property cmp $b->Property } values %unique;
    )> }
    )
    ) ... but get_sorted_things() does not consult any arguments!
    )
    ) What is the relationship between $foo and $bar and get_things()?

    It was JUST AN EXAMPLE! I happened to forget to include the argument.
    Here, I'll fix it for you:

    sub get_sorted_things
    {
    my ($arg) = @_;
    my %unique = map { $_->Key => $_ } get_things($arg);
    return sort { $a->Property cmp $b->Property } values %unique;
    }

    Better ? Or are you going to harp about that you don't know what
    get_things does ? It's irrelevant to the point of the example.

    ) Before I got to the definition of get_sorted_things(),
    ) I had guessed that $bar was an arrayref of things to sort,
    ) if it was then you could just do:
    )
    ) if (@$bar) {
    ) warn "There were things for $bar!\n";
    )
    ) But it isn't. So you can't.
    )
    ) And since I don't know what $bar is, I cannot even attempt to
    ) help you here.

    I don't need help. The code is just to exemplify what I ran into.
    I came up with a workaround as soon as I figured out the bug in sort().
    The arguments are irrelevant; all they do is show that the function
    returns a different sorted list on different invocations.

    What I want to know is *why* Larry chose to have sort() return undef
    in scalar context.

    )> And, because somebody
    )
    ) Larry Wall.
    )
    )> decided that sort should always return undef
    )> when called in scalar context, this does not work!
    )
    ) So fix it!
    )
    ) sub get_sorted_things {
    ) die "get_sorted_things() was called with a useless argument\n" if @_;
    )
    ) my %unique = map { $_->Key => $_ } get_things();
    ) if (wantarry) {
    ) return sort { $a->Property cmp $b->Property } values %unique;
    ) }
    ) else {
    ) return keys %unique;
    ) }
    ) }

    I am very well aware that (and how) you can workaround that bug, TYVM.

    )> Why was it decided that sort returns undef in scalar context ?
    )
    ) I dunno.
    )
    ) Have to ask Larry, or search for comments in the perl code I guess.
    )
    ) I would want it to return the first element, or the last element,
    ) or the median element, or ... but all of those would O(n log n),
    ) (ie. expensive, there are algorithms for determinig those things that
    ) have a better running time) so then I'd give up and make it
    ) undefined in a scalar context.
    )
    ) I don't know if that was his thinking or not.

    Well, if you use an array in scalar context, you get the count of items.
    If you use sort on an array, you get an array. Therefore, if you use sort
    on an array in scalar context, you should get the count of the array.

    I am well aware that you actually get a list, and that a list in scalar
    context does something different than an array in scalar context. That
    alone is quite horrid, IMO.

    )> IMO it is much more logical and consistent to have it return the
    )> number of objects in the list that is to be sorted
    )
    ) If you are writing a call to sort(), then you already know the list
    ) of things that you are going to ask sort() to sort.

    Not always, which is why I provided the example above.

    ) Why run it through another function only to find out something
    ) that you already have access to?

    Reusability.
    Here's the same example, but abstractly:

    - I have a function that does some work to retrieve a list of items, and as
    the final step it sorts the items.
    - Most of the time, I want to use the sorted list (in order), but sometimes
    I just want to check if there were any items.

    Now, because sort() returns undef, I have to make two separate functions,
    one which returns the list, and another that returns the sorted list.
    (The second uses the first of course).

    I consider that a workaround.

    ) Why would we want to call a function named sort() if we wanted
    ) something that did not even require sorting?

    Reusability. Polymorphism. Consistency. See above.


    SaSW, Willem
    --
    Disclaimer: I am in no way responsible for any of the statements
    made in the above text. For all I know I might be
    drugged or something..
    No I'm not paranoid. You all think I'm paranoid, don't you !
    #EOT
     
    Willem, Aug 30, 2011
    #5
  6. Willem

    Willem Guest

    wrote:
    ) I don't know why this is the case, but you should fix it up in the
    ) function that wraps the return of sort().

    My apologies.
    I hadn't made clear that I was well aware how to work around this issue.


    SaSW, Willem
    --
    Disclaimer: I am in no way responsible for any of the statements
    made in the above text. For all I know I might be
    drugged or something..
    No I'm not paranoid. You all think I'm paranoid, don't you !
    #EOT
     
    Willem, Aug 30, 2011
    #6
  7. Am 30.08.2011 18:51, schrieb Willem:
    > Now, because sort() returns undef, I have to make two separate functions,
    > one which returns the list, and another that returns the sorted list.
    > (The second uses the first of course).


    Well, you could force list context.

    $ perl -E'sub x{return sort qw(1 4 2)}; $n=()=x(); say $n'
    3

    - Wolf
     
    Wolf Behrenhoff, Aug 30, 2011
    #7
  8. Willem

    Willem Guest

    Rainer Weikusat wrote:
    ) The sort documentation actually says
    )
    ) sort SUBNAME LIST
    ) sort BLOCK LIST
    ) sort LIST
    )
    ) In list context, this sorts the LIST and returns the
    ) sorted list value. In scalar context, the behaviour of
    ) "sort()" is undefined.

    Ah, I must have found some different documentation.

    )> Why was it decided that sort returns undef in scalar context ?
    )> IMO it is much more logical and consistent to have it return the
    )> number of objects in the list that is to be sorted
    )
    ) 'Much more logical' seems like a matter of opinion here. But it is
    ) certainly not 'more consistent since evaluating a list in scalar
    ) context returns the final element "as with the C comma operator"

    The same could be said for map and grep. But those do return the count.

    ) (perldata(1)). Evaluating an array in scalar context yields the number
    ) of elements in the array. The keys function behaves in this way but
    ) expecting that to return the number of keys in a scalar context makes
    ) IMHO more sense than expecting sort to return the number of items to
    ) be sorted in a scalar context.

    IMO it's irrelevant that it makes "more" sense.
    I'm just countering the argument that it "doesn't make sense"
    by providing an example where it does make sense.

    If you were to say "It doesn't make enough sense to warrant implementing
    it that way", then *that* would be a matter of opinion.


    SaSW, Willem
    --
    Disclaimer: I am in no way responsible for any of the statements
    made in the above text. For all I know I might be
    drugged or something..
    No I'm not paranoid. You all think I'm paranoid, don't you !
    #EOT
     
    Willem, Aug 30, 2011
    #8
  9. Willem <> writes:
    > Rainer Weikusat wrote:


    [...]

    > )> Why was it decided that sort returns undef in scalar context ?
    > )> IMO it is much more logical and consistent to have it return the
    > )> number of objects in the list that is to be sorted
    > )
    > ) 'Much more logical' seems like a matter of opinion here. But it is
    > ) certainly not 'more consistent since evaluating a list in scalar
    > ) context returns the final element "as with the C comma operator"
    >
    > The same could be said for map and grep. But those do return the count.
    >
    > ) (perldata(1)). Evaluating an array in scalar context yields the number
    > ) of elements in the array. The keys function behaves in this way but
    > ) expecting that to return the number of keys in a scalar context makes
    > ) IMHO more sense than expecting sort to return the number of items to
    > ) be sorted in a scalar context.
    >
    > IMO it's irrelevant that it makes "more" sense.
    > I'm just countering the argument that it "doesn't make sense"
    > by providing an example where it does make sense.


    The purpose of map and grep is to produce an output list based on some
    input list and 'an operation' which is sucessively performed on each
    element of the input list. In both cases, the number of elements on
    the output list can be different from the number of elements on the
    input list, trivially for grep because its purpose is to filter the
    input list based on the return value of the operation and somewhat
    less trivially for map because 'the operation' may return an arbitrary
    number of output elements for each input element. In contrast to this,
    the purpose of sort is to return a permutation of the elements on the
    input list which implies that the number doesn't change. Consequently,
    it is pointless to invoke sort to determine this number.

    There is actually at least on similar operation in Perl, namely,
    reverse, which also returns a permutation of the input list. In scalar
    context, it will concatenate whatever the elements on the list
    stringify to and return a reversed string. This seems a little
    arbitrary and not really useful in many cases, eg,

    [rw@tear]~ $perl -de 0

    Loading DB routines from perl5db.pl version 1.3
    Editor support available.

    Enter h or `h h' for help, or `man perldebug' for more help.

    main::(-e:1): 0
    DB<1> print scalar(reverse(\$a, \$b, \$c))
    )0efcb38x0(RALACS)0ffcb38x0(RALACS)040db38x0(RALACS

    and extending this to sort, while 'consistent' also doesn't exactly
    appear useful:

    DB<2> print join('', sort(split(//, join('', \$a, \$b, \$c))))
    ((()))00000003334888AAAAAACCCLLLRRRSSSbbbccdefffxxx
     
    Rainer Weikusat, Aug 30, 2011
    #9
  10. >>>>> "Willem" == Willem <> writes:

    Willem> ) 'Much more logical' seems like a matter of opinion here. But it is
    Willem> ) certainly not 'more consistent since evaluating a list in scalar
    Willem> ) context returns the final element "as with the C comma operator"

    Willem> The same could be said for map and grep. But those do return
    Willem> the count.

    They return the count because the count is variable and can't be
    determined by a trivial inspection of the input.

    print "Just another Perl hacker,"; # the original

    --
    Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
    <> <URL:http://www.stonehenge.com/merlyn/>
    Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc.
    See http://methodsandmessages.posterous.com/ for Smalltalk discussion
     
    Randal L. Schwartz, Aug 30, 2011
    #10
  11. Willem

    Willem Guest

    Rainer Weikusat wrote:
    ) There is actually at least on similar operation in Perl, namely,
    ) reverse, which also returns a permutation of the input list. In scalar
    ) context, it will concatenate whatever the elements on the list
    ) stringify to and return a reversed string. This seems a little
    ) arbitrary and not really useful in many cases, eg,
    )
    ) [rw@tear]~ $perl -de 0
    )
    ) Loading DB routines from perl5db.pl version 1.3
    ) Editor support available.
    )
    ) Enter h or `h h' for help, or `man perldebug' for more help.
    )
    ) main::(-e:1): 0
    ) DB<1> print scalar(reverse(\$a, \$b, \$c))
    ) )0efcb38x0(RALACS)0ffcb38x0(RALACS)040db38x0(RALACS

    Wow that's pretty useless!

    You know, I think this stems from the old days when Perl was more of
    a simple scripting language, hacked together with functionality added
    when it "seemed useful", instead of making it consistent or anything.

    So I guess I have my answer.

    I wonder, what does Perl6 do with the result of sorting an array,
    when it is evaluated for its truth value?


    SaSW, Willem
    --
    Disclaimer: I am in no way responsible for any of the statements
    made in the above text. For all I know I might be
    drugged or something..
    No I'm not paranoid. You all think I'm paranoid, don't you !
    #EOT
     
    Willem, Aug 30, 2011
    #11
  12. Willem

    brian d foy Guest

    In article <>, Willem
    <> wrote:

    > Why was it decided that sort returns undef in scalar context ?
    > IMO it is much more logical and consistent to have it return the
    > number of objects in the list that is to be sorted (it doesn't even
    > need to sort them for that).


    If that's what you wanted, you wouldn't use sort() at all, so the
    language doesn't think to implement that context for an operator who's
    job is to sort.

    It's like asking why print() doesn't do your taxes.
     
    brian d foy, Aug 30, 2011
    #12
  13. Willem

    Willem Guest

    brian d foy wrote:
    ) In article <>, Willem
    )<> wrote:
    )
    )> Why was it decided that sort returns undef in scalar context ?
    )> IMO it is much more logical and consistent to have it return the
    )> number of objects in the list that is to be sorted (it doesn't even
    )> need to sort them for that).
    )
    ) If that's what you wanted, you wouldn't use sort() at all, so the
    ) language doesn't think to implement that context for an operator who's
    ) job is to sort.

    I explained in the rest of the post why, in fact, one would in some cases,
    so the language should have thought to implement it. It's not like it's
    doing anything useful in scalar context at the moment. Hell, it's
    even undefined behaviour (as I found out crossthread).


    To recap:
    There is a function that does a lot of work and in the end returns a
    sorted list of items. Most of the time I am interested in the actual
    list, sometimes I just want to know the number of items.

    Because of this oversight, I am forced to implement a workaround involving
    'wantarray', specifically checking the context, instead of just returning
    the sorted list, which would have been much cleaner.

    (There are other options, such as first assigning to an array and then
    returning the array, but the next maintenance programmer to come around
    might think 'hey I can return that sorted list directly!' and break
    stuff again.)


    NB: I do not need help working around this issue. This thread is
    a theoretical discussion on the merits of sort in scalar context.


    SaSW, Willem
    --
    Disclaimer: I am in no way responsible for any of the statements
    made in the above text. For all I know I might be
    drugged or something..
    No I'm not paranoid. You all think I'm paranoid, don't you !
    #EOT
     
    Willem, Aug 30, 2011
    #13
  14. Willem

    Alan Curry Guest

    In article <>,
    Willem <> wrote:
    >Rainer Weikusat wrote:
    >) There is actually at least on similar operation in Perl, namely,
    >) reverse, which also returns a permutation of the input list. In scalar
    >) context, it will concatenate whatever the elements on the list
    >) stringify to and return a reversed string. This seems a little
    >) arbitrary and not really useful in many cases, eg,
    >)
    >) [rw@tear]~ $perl -de 0
    >)
    >) Loading DB routines from perl5db.pl version 1.3
    >) Editor support available.
    >)
    >) Enter h or `h h' for help, or `man perldebug' for more help.
    >)
    >) main::(-e:1): 0
    >) DB<1> print scalar(reverse(\$a, \$b, \$c))
    >) )0efcb38x0(RALACS)0ffcb38x0(RALACS)040db38x0(RALACS
    >
    >Wow that's pretty useless!


    But in the simplest case (a single string argument), the behavior of scalar
    reverse is perfectly logical:

    $x = "foobar";
    $y = reverse $x;
    say $y;

    If a language built for text processing didn't have a reverse-string
    operation, that would be weird.

    --
    Alan Curry
     
    Alan Curry, Aug 31, 2011
    #14
  15. Willem

    Jim Gibson Guest

    In article <>, Willem
    <> wrote:

    > brian d foy wrote:
    > ) In article <>, Willem
    > )<> wrote:
    > )
    > )> Why was it decided that sort returns undef in scalar context ?
    > )> IMO it is much more logical and consistent to have it return the
    > )> number of objects in the list that is to be sorted (it doesn't even
    > )> need to sort them for that).
    > )
    > ) If that's what you wanted, you wouldn't use sort() at all, so the
    > ) language doesn't think to implement that context for an operator who's
    > ) job is to sort.
    >
    > I explained in the rest of the post why, in fact, one would in some cases,
    > so the language should have thought to implement it. It's not like it's
    > doing anything useful in scalar context at the moment. Hell, it's
    > even undefined behaviour (as I found out crossthread).


    I do not think that your use case is valid. It is silly to sort an
    array when all you want is the number of elements in the array. The
    subroutine that you wrote to do this is not a good example of good
    design. That could be why nobody on this groups agrees that what you
    want is desirable.

    > To recap:
    > There is a function that does a lot of work and in the end returns a
    > sorted list of items. Most of the time I am interested in the actual
    > list, sometimes I just want to know the number of items.
    >
    > Because of this oversight, I am forced to implement a workaround involving
    > 'wantarray', specifically checking the context, instead of just returning
    > the sorted list, which would have been much cleaner.


    This in not an oversight, but a deliberate choice by the language
    designer. You are mischaracterizing the situation.

    >
    > (There are other options, such as first assigning to an array and then
    > returning the array, but the next maintenance programmer to come around
    > might think 'hey I can return that sorted list directly!' and break
    > stuff again.)


    Any problems with maintenance of your code is more likely going to be
    due to poor design.


    I have another suggestion for what sort could return in scalar context:

    true if the array is already in sort, undef otherwise.

    --
    Jim Gibson
     
    Jim Gibson, Aug 31, 2011
    #15
  16. Willem

    Willem Guest

    Jim Gibson wrote:
    ) I do not think that your use case is valid. It is silly to sort an
    ) array when all you want is the number of elements in the array. The
    ) subroutine that you wrote to do this is not a good example of good
    ) design. That could be why nobody on this groups agrees that what you
    ) want is desirable.

    Well, the fact that you call it a subroutine, and not a function, clearly
    shows that you're stuck in the old perl4 days. And the fact that you claim
    that the *function* I wrote, with the given contract just below, is not
    good design, but *without* giving any explanation for that claim, means
    you're just trying to defend your narrow-minded view instead of actually
    trying to think about it.

    )> To recap:
    )> There is a function that does a lot of work and in the end returns a
    )> sorted list of items. Most of the time I am interested in the actual
    )> list, sometimes I just want to know the number of items.
    )>
    )> Because of this oversight, I am forced to implement a workaround involving
    )> 'wantarray', specifically checking the context, instead of just returning
    )> the sorted list, which would have been much cleaner.
    )
    ) This in not an oversight, but a deliberate choice by the language
    ) designer. You are mischaracterizing the situation.

    The deliberate choice was made because the language designer didn't see any
    use cases. If there *is* a use case, then that (not seeing a use case) is
    quite literally an oversight.

    )> (There are other options, such as first assigning to an array and then
    )> returning the array, but the next maintenance programmer to come around
    )> might think 'hey I can return that sorted list directly!' and break
    )> stuff again.)
    )
    ) Any problems with maintenance of your code is more likely going to be
    ) due to poor design.

    Why did you feel the need to throw in a gratuitous ad hominem attack ?
    You do realise that this very comment caused me to dismiss you as a viable
    discussion partner, right ? Why don't you go back hacking perl4 code,
    instead of criticizing the design of a function that happens to show
    a flaw in your favourite toy.

    ) I have another suggestion for what sort could return in scalar context:
    )
    ) true if the array is already in sort, undef otherwise.

    Classic perl4 thinking: Let's overload it to do something related,
    but different!


    SaSW, Willem
    --
    Disclaimer: I am in no way responsible for any of the statements
    made in the above text. For all I know I might be
    drugged or something..
    No I'm not paranoid. You all think I'm paranoid, don't you !
    #EOT
     
    Willem, Aug 31, 2011
    #16
  17. (Alan Curry) writes:
    > In article <>,
    > Willem <> wrote:
    >>Rainer Weikusat wrote:
    >>) There is actually at least on similar operation in Perl, namely,
    >>) reverse, which also returns a permutation of the input list. In scalar
    >>) context, it will concatenate whatever the elements on the list
    >>) stringify to and return a reversed string. This seems a little
    >>) arbitrary and not really useful in many cases, eg,
    >>)
    >>) [rw@tear]~ $perl -de 0
    >>)
    >>) Loading DB routines from perl5db.pl version 1.3
    >>) Editor support available.
    >>)
    >>) Enter h or `h h' for help, or `man perldebug' for more help.
    >>)
    >>) main::(-e:1): 0
    >>) DB<1> print scalar(reverse(\$a, \$b, \$c))
    >>) )0efcb38x0(RALACS)0ffcb38x0(RALACS)040db38x0(RALACS
    >>
    >>Wow that's pretty useless!

    >
    > But in the simplest case (a single string argument), the behavior of scalar
    > reverse is perfectly logical:
    >
    > $x = "foobar";
    > $y = reverse $x;
    > say $y;
    >
    > If a language built for text processing didn't have a reverse-string
    > operation, that would be weird.


    A 'reverse string' operation which also works in list context had
    nevertheless been a better idea, cf

    DB<16> p map { reverse $_; } qw(ab bc de)
    abbcde

    My original idea of the reason for this was that this probably a Perl4
    remnant because it seemed to make more sense in a language without
    references. But the Perl 4 documentation for reverse actually says
    that

    reverse(LIST)*
    In array context: returns the LIST in reverse order.
    In scalar context: returns the first element of LIST with bytes reversed.
     
    Rainer Weikusat, Aug 31, 2011
    #17
  18. Willem <> writes:
    > Jim Gibson wrote:
    > ) I do not think that your use case is valid. It is silly to sort an
    > ) array when all you want is the number of elements in the array. The
    > ) subroutine that you wrote to do this is not a good example of good
    > ) design. That could be why nobody on this groups agrees that what you
    > ) want is desirable.
    >
    > Well, the fact that you call it a subroutine, and not a function, clearly
    > shows that you're stuck in the old perl4 days.


    I usually prefer the term 'subroutine' because it emphasizes that this
    is not a function in the mathematical sense: It doesn't represent an
    equivalence relation but (ultimatively) refers to an ordered set of
    machine instruction performing a specific task. And I have never used
    a version of Perl older than 5.004.

    [...]

    > )> To recap:
    > )> There is a function that does a lot of work and in the end returns a
    > )> sorted list of items. Most of the time I am interested in the actual
    > )> list, sometimes I just want to know the number of items.
    > )>
    > )> Because of this oversight, I am forced to implement a workaround involving
    > )> 'wantarray', specifically checking the context, instead of just returning
    > )> the sorted list, which would have been much cleaner.
    > )
    > ) This in not an oversight, but a deliberate choice by the language
    > ) designer. You are mischaracterizing the situation.
    >
    > The deliberate choice was made because the language designer didn't see any
    > use cases. If there *is* a use case, then that (not seeing a use case) is
    > quite literally an oversight.


    If sort would return pi in scalar context, that would also be useful
    in some specific situations (as would any other value). But there is
    no more relation between the function of sort (return a specific
    permutation of its arguments) and 3.1415... than there is between
    permuting arguments and counting arguments.

    [...]

    > ) I have another suggestion for what sort could return in scalar context:
    > )
    > ) true if the array is already in sort, undef otherwise.
    >
    > Classic perl4 thinking: Let's overload it to do something related,
    > but different!


    In my opinion, this suggestion would still be a poor choice, but a
    more comprehensible one than the 'let it count its arguments' idea.
     
    Rainer Weikusat, Aug 31, 2011
    #18
  19. On 2011-08-29, Willem <> wrote:
    > Today I got bitten by a very strange bug/feature:


    Feature.

    Af there were ONE POSSIBLE logical value for it to return in scalar
    context, this would be implemented. Given that there are many
    possibilities (min? max? # of elts?), the result is one which would
    be detected ASAP as an indication of "bad usage scenario". (die()ing
    would be yet more convenient, but not backward-compatible.)

    Hope this helps,
    Ilya
     
    Ilya Zakharevich, Aug 31, 2011
    #19
  20. Willem

    Willem Guest

    Rainer Weikusat wrote:
    ) I usually prefer the term 'subroutine' because it emphasizes that this
    ) is not a function in the mathematical sense:

    You should be worrying more about the definition of 'function' in the
    computer sciences, because that's much more closely related to programming.

    ) It doesn't represent an
    ) equivalence relation but (ultimatively) refers to an ordered set of
    ) machine instruction performing a specific task. And I have never used
    ) a version of Perl older than 5.004.

    Even in mathematics, a function doesn't always represent an equivalence
    relation. Take lambda calculus, for example.

    )> The deliberate choice was made because the language designer didn't see any
    )> use cases. If there *is* a use case, then that (not seeing a use case) is
    )> quite literally an oversight.
    )
    ) If sort would return pi in scalar context, that would also be useful
    ) in some specific situations (as would any other value). But there is
    ) no more relation between the function of sort (return a specific
    ) permutation of its arguments) and 3.1415... than there is between
    ) permuting arguments and counting arguments.

    Yes there is. If you view sort in a functional-programming way, then
    it is: 'array -> sort -> array'. Using an array as a scalar gives
    the number of elements. Therefore using the result of sort as a scalar
    should give the number of elements as well. Simple logic.

    Compare, for example, a completely OO language, where there is a 'list'
    class. To get the perl behaviour of number-of-elements, you would simply
    implement a convert-to-integer member function, which the language then
    automatically calls whenever it has a 'list' but wants an 'integer'.

    Now, there is a sort function which takes a 'list' object and returns a
    'list' object. It is left as an exercise to figure out what would happen
    if you were to use sort() but want the result as an integer.

    PS: As far as I can tell from the online docs, it works like this
    in Perl6 as well.


    SaSW, Willem
    --
    Disclaimer: I am in no way responsible for any of the statements
    made in the above text. For all I know I might be
    drugged or something..
    No I'm not paranoid. You all think I'm paranoid, don't you !
    #EOT
     
    Willem, Aug 31, 2011
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,076
    Smokey Grindel
    Dec 2, 2006
  2. Clint Olsen
    Replies:
    6
    Views:
    378
    Jeff 'japhy' Pinyan
    Nov 13, 2003
  3. Mark

    Replace scalar in another scalar

    Mark, Jan 27, 2005, in forum: Perl Misc
    Replies:
    4
    Views:
    171
    Arndt Jonasson
    Jan 27, 2005
  4. Replies:
    3
    Views:
    87
  5. Tim McDaniel

    undef($foo) versus $foo = undef()?

    Tim McDaniel, Aug 19, 2009, in forum: Perl Misc
    Replies:
    6
    Views:
    151
    Peter J. Holzer
    Aug 19, 2009
Loading...

Share This Page