http://qs321.pair.com?node_id=1066563

BrowserUk has asked for the wisdom of the Perl Monks concerning the following question:

What is a map-like function, where the callback is passed l0 & l1; then l1 & l2; then l2 & l3...; and returns a list (unlike List::Util::reduce() which returns a scalar) called?


With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re: Want for a name?
by hdb (Monsignor) on Dec 11, 2013 at 13:36 UTC

      That's a possibility. One of the (many) uses is computing moving averages.

      I also thought of running, as in running sum; rolling as in rolling average.

      I think I'm favouring mapAdj as in map Adjacent or map Adjoining.

      I thought that for sure there would be a standard name for this, at least in functional languages/libraries, but looking around, it seems to be quite hard to code in Haskell or Clean.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Want for a name?
by oiskuu (Hermit) on Dec 11, 2013 at 09:59 UTC
    Hmm.. slideing window comes to mind. Or pipeline of depth 2.

    And more: stitch might be appropriate too. Or linked_map (from linked list).

      +1 for sliding window if n isn't always 2.
Re: Want for a name?
by Corion (Patriarch) on Dec 11, 2013 at 08:45 UTC

    I'm bad at naming things, so bear with me.

    I would consider pairwise, but that is already used, and it also does not describe your subroutine, as it does not pair things, but takes the right neighbour of every element.

    Likely Lisp has a name for that, maybe MAPCADR (for map Contents of Address, Data Register). That name wouldn't really be descriptive for anybody not knowing Lisp though.

    Maybe map_right_neighbour or map_rpair, or map_adjacent are ideas. I don't think that creating a formulaic name like map_a2 (with map being map_a1, and List::Util::pairwise being map_p2) would be helpful.

Re: Want for a name?
by choroba (Cardinal) on Dec 11, 2013 at 09:19 UTC
    What about borrowing a term from the regex lingo? Something like map_look_ahead...
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      maprange {3}, @list
Re: Want for a name? (between)
by tye (Sage) on Dec 11, 2013 at 16:24 UTC

    It gets called once for each space between pairs of items in the list. So I might call it "between" or "between_pairs".

    - tye        

      How about: adjoin?


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        Too much abstract freedom? N adjacent tree nodes, N neighbouring states, etc.

        You have a chain, an ordered sequence. For each element, one property is defined: the successor.

Re: Want for a name? nmapp npmap nwindowmap nslicemap
by Anonymous Monk on Dec 11, 2013 at 09:13 UTC

      splicemap  +$length , @list
      splicemap  -$length , @list
      splicemap [ $offset , +$length ] , @list
      splicemap [ $offset , -$length ] , @list
Re: Want for a name?
by jdporter (Paladin) on Dec 11, 2013 at 16:41 UTC

    I'd say "bubblemap" -- via analogy to bubblesort -- but unfortunately the term is already used in reference to concept maps.

      I personally believe that "sliding window" is absolutely the most relevant and widely recognized name for the concept.

      Therefore I'd recommend "windows"... except that that name is also already used for something else. :-( ;-)

      I reckon we are the only monastery ever to have a dungeon stuffed with 16,000 zombies.
Re: Want for a name?
by LanX (Saint) on Dec 11, 2013 at 17:41 UTC
    friends, neighbors, (over)laps

    DB<106> sub friends (&@){ my $code=shift; $last=$_; my @result; for (@_) { push @result, $code->($last,$_); $last=$_; } return @result; } DB<107> friends { $_[0]+$_[1] } 1..5 => (1, 3, 5, 7, 9)

    update
    maybe "friendwise" in analogy to "pairwise" since "friend" is a noun

    Cheers Rolf

    ( addicted to the Perl Programming Language)

      maybe "friendwise" ...

      Or "contiguwise"? "adjacentwise"? "adjointwise"? "adjacently"? "adjointly"?


      Give a man a fish:  <%-{-{-{-<

      Would there be a way to use $a and $b as in reduce?

        sure, you need to localize them.

        But $a and $b always have the risk to be lexicals from the outer scope², I wanted to avoid discussing that problem.¹

        It's about naming after all...

        Cheers Rolf

        ( addicted to the Perl Programming Language)

        ¹) compare this error

        DB<108> my $a=3; sort {$a <=> $b} @a Can't use "my $a" in sort comparison at ...

        ²) being bound to another package can be solved by investigating the caller, but checking for lexicals involves padwalker.

Re: Want for a name? (Final thoughts; strong feelings; votes?)
by BrowserUk (Patriarch) on Dec 12, 2013 at 05:39 UTC

    I really thought that lisp or scala or Haskell or similar would have already have a well-known name for this, but apparently not.

    Of the names posted in this thread, the top 8 below are my preferences in roughly descending order of preference. Any good reasoning for or against any of those?

    adjoin overlaps mapAdj moving rolling automap map_adjacent between slide pipeline stitch running MAPACDR map_right_neighbour map_rpair map_look_ahead maprange n-map-plus npmap nwindowmap nslicemap splicemap between_pairs forByTwo friends, neighbors, friendwise bubblemap

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      adjoin seems too similar to join which is unrelated. I would probably confuse overlaps with overload and override, but I already confuse the latter two, so it's probably mainly my problem. A vote for overlaps (BTW, wouldn't "overlaps" be enough?).
      لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
        adjoin seems too similar to join ...

        That's kind of why I liked it.

        ... which is unrelated.

        join intersperses adjacent elements of a list with something.

        This (in the simple 2 at a time variant) is often used to add adjacent elements of a list together -- ad-join.

        A vote for overlaps (BTW, wouldn't "overlaps" be enough?).

        Um. I thought about that, and still haven't reached a conclusion which is better.

        In the singular, it sort of implies something only happens once.

        But if you read 'overlaps' as a plural as in "there are many overlaps"; rather than the (*)???: "it overlaps", then it makes more sense I think.

        Not sure what grammatical term applies here?

        The nice thing about overlap(s) is it works for the variable width (depth?) of overlap also which adjoin doesn't.

        I think I'm beginning to favour overlap(s) also.

        But now I'm also thinking about overmap and mapover?


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
        > (BTW, wouldn't "overlaps" be enough?).

        Well, mentioning the plural brings a new perspective...

        For me designing and naming a good API is far more complicated than coding, since it involves human psychology.

        Especially since sometimes good names are already used or even only reserved.

        This brings a new concern, wasting an otherwise better used word.

        overlaps could mean much more things and especially in plural it could indicate tuples bigger than just a pair of values.

        The English grammar has no dualis alongside singular and plural like for instance Arabic, so only constructs like pair or couple indicate 2 tuples, and couples are normally disjoint. Maybe a construct with prefix "bi-" could solve this (think bigamie ;-)

        Other than describing the tuple as a whole one could try describing the relation between two elements.

        So my best guess ATM is "neighbor" but in singular(!). The neighbor can't mean anything else it describes a relation between 2 objects.

        Words like next or link already have different meaning and bichain sounds artificial in my ears.¹

        Otherwise I would consider successor or one of the synonyms like follower or one of it's synonyms like companion.

        As soon as the definition is clear seeking through a thesaurus is of help.

        Cheers Rolf

        ( addicted to the Perl Programming Language)

        updates

        ¹) bimap ?

      One reasonable metric for rating them might be: Imagine you're seeing the function name for the first time, together with a definition of its signature (parameter/return types). Would you have guessed its correct meaning? How sure would you have been?

      Of course that's still subjective, so let me present my intuitive reactions so that you can compare them to your own:

      Simple version of the function: Map a list to all its subsequences of 2 adjacent items

      For the "pairwise" version, the function would only take a code block and a list. Given that function signature, I think the only ones for which I would have guessed the correct meaning and would have been reasonably sure about it, are:

      RESULT_LIST = map_adjacent { CODE } LIST
      RESULT_LIST = neighbors { CODE } LIST

      A few comments on some of the others:

      • RESULT_LIST = adjoin { CODE } LIST
        Doesn't sound like it operates on adjoining items, but rather like it causes things to adjoin (in some unspecified way).
      • RESULT_LIST = overlaps { CODE } LIST
        Sounds like it does something less generic and more complicated, although I wouldn't be sure what. Maybe LIST accepts a list of ranges rather then numbers, and the function finds (and processes) overlapping ranges? Or something.
      • RESULT_LIST = mapAdj { CODE } LIST
        Map "adjacent"? Map "adjusted"? Map "adjunct"? ...
      • RESULT_LIST = between { CODE } LIST RESULT_LIST = between_pairs { CODE } LIST
        I might have guessed this one correctly, but would have felt unsure about it.
      • RESULT_LIST = pipeline { CODE } LIST
        Sounds like the return value of CODE becomes the first input parameter for the next iteration, like in List::Util's reduce. At least that would match my understanding of pipelines in computing.
      • RESULT_LIST = map_right_neighbour { CODE } LIST
        Sounds like it does one iteration strictly for each element of LIST, with $b set to the element's right neighbor, and on the last iteration, $b set to undef.

      Generalized version of the function: Map a list to all its subsequences of n adjacent items

      In this case, the function would likely take a code block, a number, and a list. Unfortunately, I don't think I would be very sure about any of my guesses in this scenario, for any of the suggested names. One that hasn't been suggested yet (probably because it's too long), but would be pretty self-explanatory for me, is:

      RESULT_LIST = natatime_sliding { CODE } NUMBER, LIST

      Those where there's at least a decent chance that I would have guessed the correct meaning, are, in descending order:

      RESULT_LIST = map_adjacent { CODE } NUMBER, LIST
      RESULT_LIST = moving { CODE } NUMBER, LIST
      RESULT_LIST = slide { CODE } NUMBER, LIST

      moving is nice because it's effectively a generalization of "moving average" to "moving <custom calculation>"...

      @moving_averages = moving { sum(@_)/@_ } $n, @data

      ...but of course if the context in which you're using it has nothing to do with statistics, that recognition value will be lost.

      between and map_right_neighbour wouldn't work at all anymore for n > 2.
      adjoin, overlaps, mapAdj and pipeline would still have the same problems as above.

        Thanks for your thoughtful review.

        natatime_sliding

        Sounds like OAPs complaining that their tea'n'chat session are getting later and later .... :) But yes, it's too long.

        mapAdj

        Map adjacent; map adjoining; map adjunct; all of those work.

        Since salva pointed out the scala version, I keep looking again at slide/sliding; but they make me think of sliding scales & sliding checksum, neither of which are appropriate here.

        As I said elsewhere, many function names (and keywords) do not mean much unless you know what they mean in the context of a computer program.

        Take reduce or join or grep or splice. Write the functionality of any of those out in full:

        take_a_list_of_values_convert_them_to_their_string_representations_if_ +necessary_intersperse_them_with_this_other_string_and_return_a_single +_string_formed_from_them_all( "\t", @nums);

        And it would be ridiculous.

        You only know what grep does, because you learnt it, not from the name, so the key things are to be vaguely mnemonic and memorable, and preferably short.

        I'm more and more persuaded by overlap & overmap.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Want for a name?
by Anonymous Monk on Dec 11, 2013 at 16:11 UTC
    Unclear!

    "reduce" doesn't work the way you described.

      "reduce" doesn't work the way you described.

      I didn't describe the way reduce works; so rather than "unclear" I'd suggest: "unread".

      And being that everyone else seems to get the meaning, that is your problem, not mine.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Want for a name?
by hdb (Monsignor) on Dec 11, 2013 at 20:21 UTC

    In addition to your question for a name you also been offered a generalization of the form to process not only two but n elements of the list at a time. But this is only one possible way to generalize. You could also think of it as applying an operation to each element of a list and a shifted version of the list, like this:

    1 2 3 4 5 6 7 8 | | | | | | | 1 2 3 4 5 6 7 8

    In this case the offset between the list and its shifted version would be an extra parameter and - as in autocorrelation - the name would be automap .

      In this case the offset between the list and its shifted version would be an extra parameter and - as in autocorrelation - the name would be automap .

      The 'auto' in autocorrelation comes from the Greek "self, one's own", which makes some kind of sense in that term.

      But in our industry and the more general world, 'auto' is short for automatic; as in C's auto keyword, and auto transmission.

      automap just doesn't hint of the function's purpose to me.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.