[erlang-questions] Proposal: add lists:intersperse/2 and lists:intercalate/2
Richard A. O'Keefe
ok@REDACTED
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
> <jesper.louis.andersen@REDACTED
> <mailto:jesper.louis.andersen@REDACTED>> 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