[erlang-questions] Proposal: add lists:intersperse/2 and lists:intercalate/2

Richard A. O'Keefe <>
Mon Mar 7 04:50:22 CET 2016


On 6/03/16 3:22 am, Garrett Smith wrote:

> On Sat, Mar 5, 2016 at 4:04 AM Jesper Louis Andersen 
> < 
> <mailto:>> wrote:
>
>     So to catch up:
>
>     * On Richard's comments of other uses than for a string:
>
>     The obvious use in Erlang is to produce iolist() types for binary
>     data: intersperse($, [<<"a">>, <<"b">>, <<"c">>]) is relatively
>     common in my code. The slightly less obvious use is to interleave
>     a simplifier step in between every optimization step of a
>     compiler, but I've only done that once in my life and I'm not sure
>     it is that useful :)
>
>
> Yep, iolists is the application I have for this.

This looks like a "string" use to me (in the sense of data type for 
representing
text, not in the list of character code sense).

I always worry about things like this because of the difficulty the receiver
will have decoding it.  Reverting to lists for a minute, suppose I do
intersperse($,, ["a,b","c,,,d"]) and write the resulting iolist, or
intercalate(",", ["a,b","c,,,d"]).
How does the receiver decode "a,b,c,,,d" so as to recover the original 
input?

For example, I might use an escape character.
Let's say the escape character is #.
I'd want to generate "a#,b,c#,#,#,d".

Here is a paragraph from the documentation of my Smalltalk system.

  Joining is intrinsically problematic.  Just pasting a bunch of things
  together is normally not an issue, but introducing a separator may
  mislead you into thinking that the output can be decoded. It is
  especially tempting when there is a related 'split' method.  Consider
     $, join: #('a' 'b' 'c')   ===> 'a,b,c'
     $, split: 'a,b,c'         ===> an OrderedCollection('a' 'b' 'c')
  in Pharo.  Doesn't it look as though these are inverses? But try
     $, join: #('a,b' 'c,,,d') ===> 'a,b,c,,,d'
     $, split: 'a,b,c,,,d'     ===> an OrderedCollection('a' 'b' 'c' '' 
'' 'd')
  No, they are not inverses.  True inverses would be something like
     $, join: #('a,b' 'c,,,d') escape: $#
     ===> 'a#,b,c#,#,#,d'
     $, split: 'a#,b,c#,#,#,d' escape: $#
     ===> anOrderedCollection('a,b' 'c,,,d').
  But those methods do not exist in Pharo.  Use splitting and joining
  methods with vigilant trepidation; make sure that your separator
  does *not* appear in the data you are joining.


The use of binaries really doesn't change this: as long as what I'm going to
do is to send a sequence of characters somewhere, I need a documented
justification for sending something I can't decode.

In your actual use, you may KNOW that the separator cannot appear in
the list elements you're gluing together, so for you it may be safe.

The problem with 'join' as a name is that it is hopelessly vague.
Xs++Ys joins Xs and Ys.  [{K,X,Y} || {K,X} <- Xs, {K,Y} <- Ys} also
joins Xs and Ys.  Some versions of join will let me do
"a, b, and c" and some won't. And so it goes.



More information about the erlang-questions mailing list