in reply to Re: What should be returned in scalar context?
in thread What should be returned in scalar context?

Answering the last question first, no that isn't equivalent to just have a map since a map in scalar context coerces like an array does - it tells you how many elements that you have, not what any of them are.

I have used that style in functions which transform elements where you might reasonably want to transform one or many elements. The hidden assumption is that it only makes sense to impose scalar context when you are transforming a single element, so behaving badly if you try to transform multiple elements in scalar context is OK.

As for why I would like to standardize somewhat, like I said before, it is all about setting expectations. The trouble with doing something different in each case is underscored by the fact that a top-notch Perl programmer like yourself could be tripped up by what a built-in function does in scalar context. (And to be honest upon seeing you claim that the two should be the same, I actually ran a test program before I was confident in claiming that map had the behaviour that I was specifically trying to work around.)

Besides which, I think that it is overkill to have to give an issue like this serious consideration with every function that I write. Having a default that just flows from my fingers would smooth out the development process.

  • Comment on Re: Re: What should be returned in scalar context?

Replies are listed 'Best First'.
Re: What should be returned in scalar context?
by Abigail-II (Bishop) on Dec 02, 2003 at 15:39 UTC
    Besides which, I think that it is overkill to have to give an issue like this serious consideration with every function that I write. Having a default that just flows from my fingers would smooth out the development process.
    It's not that for every function I write I contemplate what I am going to do in list context, and what I am going to do in scalar context. I just do whatever seems right at the time, and that's usually the right choice. But it's seldom consistent.

    Abigail

Re: Re: Re: What should be returned in scalar context?
by ysth (Canon) on Dec 03, 2003 at 18:44 UTC
    Tilly:
    # And for something completely different... sub foo { if (1 != @_) { return map $foo($_), @_; } # body of foo here. return $whatever; }
    Abigail-II:
    Why the test on the number of arguments, and the recursion? Wouldn't the following be equivalent?:
    sub foo { map { # body of foo here. $whatever } @_ }
    Tilly:
    Answering the last question first, no that isn't equivalent to just have a map since a map in scalar context coerces like an array does - it tells you how many elements that you have, not what any of them are.
    The original function also has a map in scalar context problem. Something like this is probably what you want:
    sub foo { (map { # body of foo here. $whatever } @_)[0..$#_]; }
    Though I this may be clearer:
    sub foo { my @ret = map { # body of foo here $whatever; } @_; @ret[0..$#ret]; }
      You missed the significance of the phrase, The hidden assumption is that it only makes sense to impose scalar context when you are transforming a single element, so behaving badly if you try to transform multiple elements in scalar context is OK. Which is an explicit reference to the misbehaviour that you are pointing out.

      Returning a nonsense result that the programmer will puzzle over makes sense to me because strange answers are a clue that you are doing something wrong. Returning something sort of sensible may make the mistake less immediately apparent. Putting an explicit error makes more sense still - if you want to put the effort out. Retrofitting a 2 line map into an existing function is easier than rewriting it.

      I'm puzzled by this

      sub foo { # vvvv Temp array my @ret = map { # body of foo here $whatever; } @_; # <<< list 1 # vvvvvvvv list 2 @ret[0..$#ret]; # ^^^^^^^^^^^^^^ list 3 }

      Why generate one temporary array and three lists to achieve the same effect as

      sub foo { map { # body of foo here $_[ $_ ] ...; $whatever; } 0..$#ret; }

      which creates 2 lists and no temporary array.

      What am I missing?


      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "Think for yourself!" - Abigail
      Hooray!
      Wanted!

        What am I missing?

        Note that the node title mentions "scalar context". This is what you are missing. Compare your two foo()s when called in a scalar context.

                        - tye