Discussion:
[erlang-questions] Proposal: add lists:intersperse/2 and lists:intercalate/2
Jesper Louis Andersen
2016-03-02 14:47:41 UTC
Permalink
Hi Erlangers,

I'd really like to add two functions to the lists module from Haskell:

intersperse(List, Seperator) produces a list where each element is
separated by separator, i.e.

X = [1,2,3]
[1, x, 2, x, 3] = lists:intersperse(X, x),

and it's cousin, intercalate(ListOfLists, Separator) is
append(intersperse(ListOfLists, Seperator)), i.e,

Y = ["a", "b", "c"]
"a, b, c" = lists:intercalate(Y, ", "),

The implementations are straightforward and easy to write tests for, even
property based tests if needed.

The rationale for this proposal is that I find myself implementing this
function again and again in every project I write, and it is highly
generic. It belongs in a typical list module. OCaml libraries add it.
Haskell's Data.List has it. I believe Erlang, being a practical language,
should have it as well.

Thoughts?

--
J.
Pierre Fenoll
2016-03-02 14:54:11 UTC
Permalink
I find myself reimplementing the first one a lot, for use with iolists.
The second one is string:join/2, right?


> On 02 Mar 2016, at 06:47, Jesper Louis Andersen <***@gmail.com> wrote:
>
> Hi Erlangers,
>
> I'd really like to add two functions to the lists module from Haskell:
>
> intersperse(List, Seperator) produces a list where each element is separated by separator, i.e.
>
> X = [1,2,3]
> [1, x, 2, x, 3] = lists:intersperse(X, x),
>
> and it's cousin, intercalate(ListOfLists, Separator) is append(intersperse(ListOfLists, Seperator)), i.e,
>
> Y = ["a", "b", "c"]
> "a, b, c" = lists:intercalate(Y, ", "),
>
> The implementations are straightforward and easy to write tests for, even property based tests if needed.
>
> The rationale for this proposal is that I find myself implementing this function again and again in every project I write, and it is highly generic. It belongs in a typical list module. OCaml libraries add it. Haskell's Data.List has it. I believe Erlang, being a practical language, should have it as well.
>
> Thoughts?
>
> --
> J.
> _______________________________________________
> erlang-questions mailing list
> erlang-***@erlang.org
> http://erlang.org/mailman/listinfo/erlang-questions
Garrett Smith
2016-03-02 15:21:58 UTC
Permalink
I recently implemented the second as "join" - ala string, but for arbitrary
separators and list elements.

I think the name "intersperse" is descriptive enough.

"intercalculate" no so much. I'd go with "join".

In the interest of consistency with other lists functions, I'd put the list
argument last in each case.

On Wed, Mar 2, 2016 at 8:54 AM Pierre Fenoll <***@gmail.com> wrote:

> I find myself reimplementing the first one a lot, for use with iolists.
> The second one is string:join/2, right?
>
>
> > On 02 Mar 2016, at 06:47, Jesper Louis Andersen <
> ***@gmail.com> wrote:
> >
> > Hi Erlangers,
> >
> > I'd really like to add two functions to the lists module from Haskell:
> >
> > intersperse(List, Seperator) produces a list where each element is
> separated by separator, i.e.
> >
> > X = [1,2,3]
> > [1, x, 2, x, 3] = lists:intersperse(X, x),
> >
> > and it's cousin, intercalate(ListOfLists, Separator) is
> append(intersperse(ListOfLists, Seperator)), i.e,
> >
> > Y = ["a", "b", "c"]
> > "a, b, c" = lists:intercalate(Y, ", "),
> >
> > The implementations are straightforward and easy to write tests for,
> even property based tests if needed.
> >
> > The rationale for this proposal is that I find myself implementing this
> function again and again in every project I write, and it is highly
> generic. It belongs in a typical list module. OCaml libraries add it.
> Haskell's Data.List has it. I believe Erlang, being a practical language,
> should have it as well.
> >
> > Thoughts?
> >
> > --
> > J.
> > _______________________________________________
> > erlang-questions mailing list
> > erlang-***@erlang.org
> > http://erlang.org/mailman/listinfo/erlang-questions
> _______________________________________________
> erlang-questions mailing list
> erlang-***@erlang.org
> http://erlang.org/mailman/listinfo/erlang-questions
>
Robert Wilkinson
2016-03-02 15:05:23 UTC
Permalink
On Wed, Mar 02, 2016 at 03:47:41PM +0100, Jesper Louis Andersen wrote:
> Hi Erlangers,
>
> I'd really like to add two functions to the lists module from Haskell:
>
> intersperse(List, Seperator) produces a list where each element is
> separated by separator, i.e.
>
> X = [1,2,3]
> [1, x, 2, x, 3] = lists:intersperse(X, x),
>
> and it's cousin, intercalate(ListOfLists, Separator) is
> append(intersperse(ListOfLists, Seperator)), i.e,
>
> Thoughts?
>
> --
> J.

Hi Jesper

Please spell Separator consistently and correctly :-)

Bob
--
Kiss me, Kate, we will be married o' Sunday.
-- William Shakespeare, "The Taming of the Shrew"
Siraaj Khandkar
2016-03-02 17:02:49 UTC
Permalink
On 3/2/16 9:47 AM, Jesper Louis Andersen wrote:
> Hi Erlangers,
>
> I'd really like to add two functions to the lists module from Haskell:
>
> intersperse(List, Seperator) produces a list where each element is
> separated by separator, i.e.
>
> X = [1,2,3]
> [1, x, 2, x, 3] = lists:intersperse(X, x),
>
> and it's cousin, intercalate(ListOfLists, Separator) is
> append(intersperse(ListOfLists, Seperator)), i.e,
>
> Y = ["a", "b", "c"]
> "a, b, c" = lists:intercalate(Y, ", "),
>
> The implementations are straightforward and easy to write tests for, even
> property based tests if needed.
>
> The rationale for this proposal is that I find myself implementing this
> function again and again in every project I write, and it is highly
> generic. It belongs in a typical list module. OCaml libraries add it.
> Haskell's Data.List has it. I believe Erlang, being a practical language,
> should have it as well.
>
> Thoughts?

+1

Though I prefer the name "interleave" to "intersperse", since its
meaning is more-precise and closer to the intended behavior here.
Dmitry Kolesnikov
2016-03-02 17:30:02 UTC
Permalink
Hello,

“interleave” and “join” are friendly for non-native English programmers.

Otherwise +1

- Dmitry

> On Mar 2, 2016, at 7:02 PM, Siraaj Khandkar <***@khandkar.net> wrote:
>
> On 3/2/16 9:47 AM, Jesper Louis Andersen wrote:
>> Hi Erlangers,
>>
>> I'd really like to add two functions to the lists module from Haskell:
>>
>> intersperse(List, Seperator) produces a list where each element is
>> separated by separator, i.e.
>>
>> X = [1,2,3]
>> [1, x, 2, x, 3] = lists:intersperse(X, x),
>>
>> and it's cousin, intercalate(ListOfLists, Separator) is
>> append(intersperse(ListOfLists, Seperator)), i.e,
>>
>> Y = ["a", "b", "c"]
>> "a, b, c" = lists:intercalate(Y, ", "),
>>
>> The implementations are straightforward and easy to write tests for, even
>> property based tests if needed.
>>
>> The rationale for this proposal is that I find myself implementing this
>> function again and again in every project I write, and it is highly
>> generic. It belongs in a typical list module. OCaml libraries add it.
>> Haskell's Data.List has it. I believe Erlang, being a practical language,
>> should have it as well.
>>
>> Thoughts?
>
> +1
>
> Though I prefer the name "interleave" to "intersperse", since its meaning is more-precise and closer to the intended behavior here.
> _______________________________________________
> erlang-questions mailing list
> erlang-***@erlang.org
> http://erlang.org/mailman/listinfo/erlang-questions
Richard A. O'Keefe
2016-03-03 00:41:08 UTC
Permalink
On 3/03/16 6:02 am, Siraaj Khandkar wrote:
> Though I prefer the name "interleave" to "intersperse", since its
> meaning is more-precise and closer to the intended behavior here.

No, interleaving requires *two* sequences. This is interleave:

interleave([], []) -> [];
interleave([X|Xs], [Y|Ys]) -> [X,Y|interleave(Xs,Ys)].

interleave, v, OED, sense 3:
"Computing and Telecommunications. To interfile (two or more
digitized signals or sequences of information) by alternating
between them; to alternate (one such signal or sequence) with
others. Also, to divide (memory, etc.) between a number of
different tasks by allocating successive segments to each in turn."

(I must admit I hadn't encountered the word 'interfile' before.)
Siraaj Khandkar
2016-03-03 01:23:55 UTC
Permalink
On 3/2/16 7:41 PM, Richard A. O'Keefe wrote:
>
>
> On 3/03/16 6:02 am, Siraaj Khandkar wrote:
>> Though I prefer the name "interleave" to "intersperse", since its
>> meaning is more-precise and closer to the intended behavior here.
>
> No, interleaving requires *two* sequences. This is interleave:
>
> interleave([], []) -> [];
> interleave([X|Xs], [Y|Ys]) -> [X,Y|interleave(Xs,Ys)].
>
> interleave, v, OED, sense 3:
> "Computing and Telecommunications. To interfile (two or more
> digitized signals or sequences of information) by alternating
> between them; to alternate (one such signal or sequence) with
> others. Also, to divide (memory, etc.) between a number of
> different tasks by allocating successive segments to each in turn."
>
> (I must admit I hadn't encountered the word 'interfile' before.)

The way I understand it is:

- interleave: put 1 B between 2 As
- intersperse: put M Bs between N As

i.e. "intersperse" is more-general - interval length is unspecified.

Is this wrong?
Richard A. O'Keefe
2016-03-03 04:31:58 UTC
Permalink
On 3/03/16 2:23 pm, Siraaj Khandkar wrote:
>
>> interleave, v, OED, sense 3:
>> "Computing and Telecommunications. To interfile (two or more
>> digitized signals or sequences of information) by alternating
>> between them; to alternate (one such signal or sequence) with
>> others. Also, to divide (memory, etc.) between a number of
>> different tasks by allocating successive segments to each in turn."
>>
>> (I must admit I hadn't encountered the word 'interfile' before.)
>
> The way I understand it is:
>
> - interleave: put 1 B between 2 As
[A1,B1,A2,B2,A3,B3] will do.
[A1,B1,A2,B2,A3,B3,A4] will do.
Using the *same* B every time is not interleaving.

A simple example of interleaving: put the fingers of one hand between
the fingers of the other.

Please people, do NOT use the word "interleaving" to refer to what
the proposed "intersperse" function does. We need "interleaving"
to refer to interleaving.
> - intersperse: put M Bs between N As
OED sense 1: "to scatter or sprinkle between or among other things;
to place here and there in the course of something; to mingle
dispersedly or at intervals."

I don't think anyone looking at the OED would expect the Haskell
function definition. The only justification for adopting the names
intersperse and intercalate is that those *are* the names other
not-entirely-dissimilar programming languages are using.
Siraaj Khandkar
2016-03-04 15:33:57 UTC
Permalink
On 3/2/16 11:31 PM, Richard A. O'Keefe wrote:
>
> On 3/03/16 2:23 pm, Siraaj Khandkar wrote:
>>
>>> interleave, v, OED, sense 3:
>>> "Computing and Telecommunications. To interfile (two or more
>>> digitized signals or sequences of information) by alternating
>>> between them; to alternate (one such signal or sequence) with
>>> others. Also, to divide (memory, etc.) between a number of
>>> different tasks by allocating successive segments to each in turn."
>>>
>>> (I must admit I hadn't encountered the word 'interfile' before.)
>>
>> The way I understand it is:
>>
>> - interleave: put 1 B between 2 As
> [A1,B1,A2,B2,A3,B3] will do.
> [A1,B1,A2,B2,A3,B3,A4] will do.
> Using the *same* B every time is not interleaving.
>

The notion of sameness here is problematic, since you're now requiring
that the above-quoted "sequences of information" are sets, which is
unlikely the intended meaning.

If we have no uniqueness or distribution (i.e. how long until a repeat
is allowed) requirements for our two sequences, then there's no useful,
semantic distinction between a sequence of copied elements and a
sequence of randomly-generated elements.

Neither "interleaving" nor "interspersing" say anything about the
contents of the two sequences they operate on, where they differ is in
the degree to which they care about intervals between elements:

- "interleaving" promises a process which picks 1 element from A, then 1
element from B;
- "interspersing" only promises that some (undefined number of) elements
from A will end-up separated by some (undefined number of) elements from B.

One real problem, which goes against the requirement of the function
in-question, is that both, [a, b, a] and [a, b, a, b] seem to be allowed
by "interleave", but maybe not by "intersperse", but I'm not really sure
about this...


>> - intersperse: put M Bs between N As
> OED sense 1: "to scatter or sprinkle between or among other things;
> to place here and there in the course of something; to mingle
> dispersedly or at intervals."
>
> I don't think anyone looking at the OED would expect the Haskell
> function definition. The only justification for adopting the names
> intersperse and intercalate is that those *are* the names other
> not-entirely-dissimilar programming languages are using.
>

Just merely copying what has been done before, without looking into the
reasons, misses a valuable opportunity for improvement.
Richard A. O'Keefe
2016-03-07 03:18:46 UTC
Permalink
On 5/03/16 4:33 am, Siraaj Khandkar wrote:
>
> The notion of sameness here is problematic, since you're now requiring
> that the above-quoted "sequences of information" are sets, which is
> unlikely the intended meaning.

You just lost me. I was requiring that the sequences be SEQUENCES.
How does anything I wrote require them to be sets?

Here's what I was saying:
going from [a,b,c] and [1,2,3] to [a,1,b,2,c,3] *IS* interleaving
going from [a,b,c] and 0 to [a,0,b,0,c,0] is *NOT* interleaving.

The question is not whether a sequence contains repeated elements
but a question as to whether it *IS* a sequence in the first place,
I am happy to call [a,b,c] [0,0,0] -> [a,0,b,0,c,0] interleaving.

interleave([X|Xs], [Y|Ys]) -> [X,Y|interleave(Xs,Ys)];
interleave([], []) -> [].

Didn't I give that very code? This DOESN'T care whether there are
repeated elements in either sequence. It DOES care that it is given
two lists, not a list and a single element. Again, what I'm saying is
not that there is a problem with lists that *happen* to contain
duplicate elements, but that

not_interleave([X,Y|Zs], S) -> [X,S|not_interleave([Y|Zs], S)];
not_interleave(End, _) -> End.

is not interleaving.

We agree that "interleaving" does not "say anything about the
contents of the two sequences", which is why I didn't say anything
about the contents of the two sequences. We also agree that
it "operate[s] on" "two sequences", not one sequence and one
something else, which was my whole point.

Sigh.
Siraaj Khandkar
2016-03-07 16:59:55 UTC
Permalink
On 3/6/16 10:18 PM, Richard A. O'Keefe wrote:
>
>
> On 5/03/16 4:33 am, Siraaj Khandkar wrote:
>>
>> The notion of sameness here is problematic, since you're now requiring
>> that the above-quoted "sequences of information" are sets, which is
>> unlikely the intended meaning.
>
> You just lost me. I was requiring that the sequences be SEQUENCES.
> How does anything I wrote require them to be sets?
>
> Here's what I was saying:
> going from [a,b,c] and [1,2,3] to [a,1,b,2,c,3] *IS* interleaving
> going from [a,b,c] and 0 to [a,0,b,0,c,0] is *NOT* interleaving.

Both of the above results are functions of 2 sequences, the difference
is that 1st works with a pre-computed list, while the 2nd works with a
an infinite stream of 0s.

So the difference is in the sources of the sequences, not in how they're
combined.

This clearly calls for some distinction in API (i.e. how those sequences
are passed), but not a different description of the meaning of the
outcome (i.e. name).

One (quick and rough) example of an API distinction could be:

-spec interleave([A], {exactly, [A]} | {repeat, A}) -> [A].

Which can actually be made even more general, since repeating the same
element is just a special case of cycling a single element list:

-spec interleave([A], {exactly, [A]} | {cycle, [A]}) -> [A].

... but I digress ...

>
> The question is not whether a sequence contains repeated elements
> but a question as to whether it *IS* a sequence in the first place,
> I am happy to call [a,b,c] [0,0,0] -> [a,0,b,0,c,0] interleaving.
>

Right, the main difference in our points of view is that I see this 0 as
just an argument for a process which makes an infinite stream of 0s
(i.e. another sequence), while the rule for combining the sequences
remains exactly the same.

Since, if you truly only have one 0, then the best you can do is :

[1, 0, 2]

or maybe

[1, 0, 2, 3, 4, 5]

to insert more 0s - you need more 0s, hence you need a sufficiently-long
sequence of them; how that sufficiently-long sequence is computed is
unrelated to how it is combined with the 1st sequence.

What I'm naming is the rule for the combination.
Richard A. O'Keefe
2016-03-08 00:24:16 UTC
Permalink
On 8/03/16 5:59 am, Siraaj Khandkar wrote:

> Both of the above results are functions of 2 sequences, the difference
> is that 1st works with a pre-computed list, while the 2nd works with a
> an infinite stream of 0s.

(A) No. 0 is not an infinite stream of 0s.
(B) Erlang doesn't have infinite lists.
(C) Haskell *does* have infinite lists, but you still have to
write cycle [0] to get one.
(D) I was discussing *specific* code definitions:

intersperse(Sep, [X|Xs]) -> [X | intersperse_(Xs)];
intersperse(_, []) -> [].

intersperse_(Sep, [X|Xs]) -> [Sep,X | intersperse_(Xs)];
intersperse_(_, []) -> [].

interleave([X|Xs], [Y|Ys]) -> [X,Y | interleave(Xs, Ys)];
interleave([], []) -> [].

which have quite distinct interfaces. interleave/2 takes two
list(T) sequences; intersperse/2 takes a T and a list(T).

Someone raised the issue of finding functions.
It's actually quite hard in most programming languages to guess
the names of most built-in functions from their meaning.
For example, who would have guess that "read a line from
standard input" was called gets() in C?

Haskell has a web interface where you can give the *type* of
a function and get a list of well-known functions with that
type. Squeak has (or had, I haven't updated in a while) an
IDE interface where you can give an input-output *example*
of a function and get a list of well-known functions that give
that output for that input. It might be a good idea to do
that for at least the Erlang lists module, so that you could
do function_finder:find(",", ["a","b"], "a,b")
==> lists:intercalate/2
and function_finder:find([d,r,e,a,d], [a,d,d,e,r])
==> lists:sort/1
Siraaj Khandkar
2016-03-08 14:02:42 UTC
Permalink
On 3/7/16 7:24 PM, Richard A. O'Keefe wrote:
> On 8/03/16 5:59 am, Siraaj Khandkar wrote:
>
>> Both of the above results are functions of 2 sequences, the difference
>> is that 1st works with a pre-computed list, while the 2nd works with a
>> an infinite stream of 0s.
>
> (A) No. 0 is not an infinite stream of 0s.

Then, given a 0 and [1, 2, 3], you can't do much better than
[1, 0, 2, 3]


> (B) Erlang doesn't have infinite lists.

There's no primitive named "sequence" in Erlang either.


> (C) Haskell *does* have infinite lists, but you still have to
> write cycle [0] to get one.
> (D) I was discussing *specific* code definitions:
>
> intersperse(Sep, [X|Xs]) -> [X | intersperse_(Xs)];
> intersperse(_, []) -> [].
>
> intersperse_(Sep, [X|Xs]) -> [Sep,X | intersperse_(Xs)];
> intersperse_(_, []) -> [].

The above function clearly constructs the second sequence (of Seps) on
the fly.

Please note the obvious similarity to:

-spec seq(A) :: nil | {cons, A, seq(A)}.

>
> interleave([X|Xs], [Y|Ys]) -> [X,Y | interleave(Xs, Ys)];
> interleave([], []) -> [].
>
> which have quite distinct interfaces. interleave/2 takes two
> list(T) sequences; intersperse/2 takes a T and a list(T).
>
> Someone raised the issue of finding functions.
> It's actually quite hard in most programming languages to guess
> the names of most built-in functions from their meaning.
> For example, who would have guess that "read a line from
> standard input" was called gets() in C?
>
> Haskell has a web interface where you can give the *type* of
> a function and get a list of well-known functions with that
> type. Squeak has (or had, I haven't updated in a while) an
> IDE interface where you can give an input-output *example*
> of a function and get a list of well-known functions that give
> that output for that input. It might be a good idea to do
> that for at least the Erlang lists module, so that you could
> do function_finder:find(",", ["a","b"], "a,b")
> ==> lists:intercalate/2
> and function_finder:find([d,r,e,a,d], [a,d,d,e,r])
> ==> lists:sort/1

These are, indeed, great ideas!

There's been an effort to do similar for OCaml:
http://ocamloscope.herokuapp.com/

Which, I have to admit, I have not felt the urge to use in practice.
Dieter Schön
2021-05-12 15:53:16 UTC
Permalink
It seems that Jesper wrote this function a bit later in 2016, if I
interpret the logs correctly.

Only, the function is named join:

25> X = [1,2,3].
[1,2,3]
26> [1,0,2,0,3] = lists:join(0, X).
[1,0,2,0,3]
27>
27> Y = ["a", "b", "c"].
["a","b","c"]
28> "a, b, c" = lists:flatten(lists:join(", ", Y)).
"a, b, c"


regards,

dieter


On 23.03.21 21:18, Siraaj Khandkar wrote:
> Greetings Erlangers,
>
> Nothing serious, just some fun here. I stumbled on the function
> "add-between" in Racket stdlib, which reminded me of the lively, lolzy
> debate we had here 5 years ago :-D
>
>     $ racket
>     Welcome to Racket v7.9 [bc].
>     > (add-between '(a b c d) 0)
>     '(a 0 b 0 c 0 d)
>     >
>
> https://docs.racket-lang.org/reference/pairs.html#%28def._%28%28lib._racket%2Flist..rkt%29._add-between%29%29
>
>
>
> On 3/2/16 12:02 PM, Siraaj Khandkar wrote:
>> On 3/2/16 9:47 AM, Jesper Louis Andersen wrote:
>>> Hi Erlangers,
>>>
>>> I'd really like to add two functions to the lists module from Haskell:
>>>
>>> intersperse(List, Seperator) produces a list where each element is
>>> separated by separator, i.e.
>>>
>>> X = [1,2,3]
>>> [1, x, 2, x, 3] = lists:intersperse(X, x),
>>>
>>> and it's cousin, intercalate(ListOfLists, Separator) is
>>> append(intersperse(ListOfLists, Seperator)), i.e,
>>>
>>> Y = ["a", "b", "c"]
>>> "a, b, c" = lists:intercalate(Y, ", "),
>>>
>>> The implementations are straightforward and easy to write tests for,
>>> even
>>> property based tests if needed.
>>>
>>> The rationale for this proposal is that I find myself implementing this
>>> function again and again in every project I write, and it is highly
>>> generic. It belongs in a typical list module. OCaml libraries add it.
>>> Haskell's Data.List has it. I believe Erlang, being a practical
>>> language,
>>> should have it as well.
>>>
>>> Thoughts?
>>
>> +1
>>
>> Though I prefer the name "interleave" to "intersperse", since its
>> meaning is more-precise and closer to the intended behavior here.
Joe Armstrong
2016-03-02 18:28:04 UTC
Permalink
On Wed, Mar 2, 2016 at 3:47 PM, Jesper Louis Andersen
<***@gmail.com> wrote:
> Hi Erlangers,
>
> I'd really like to add two functions to the lists module from Haskell:
>
> intersperse(List, Seperator) produces a list where each element is separated
> by separator, i.e.
>
> X = [1,2,3]
> [1, x, 2, x, 3] = lists:intersperse(X, x),
>
> and it's cousin, intercalate(ListOfLists, Separator) is
> append(intersperse(ListOfLists, Seperator)), i.e,
>
> Y = ["a", "b", "c"]
> "a, b, c" = lists:intercalate(Y, ", "),
>
> The implementations are straightforward and easy to write tests for, even
> property based tests if needed.
>
> The rationale for this proposal is that I find myself implementing this
> function again and again in every project I write, and it is highly generic.
> It belongs in a typical list module. OCaml libraries add it. Haskell's
> Data.List has it. I believe Erlang, being a practical language, should have
> it as well.
>

This is a splendid function - I have one myself called interleave, the only
problem is that if somebody uses this and puts their code in a library on github
and somebody fetches this code and runs it with an *old* version of erlang
then they will get a error and probably blame your code.

This is why I have a single library called elib2_misc.erl where I put *all* the
stuff that should be somewhere else - then I ship this with my code.

The whole story of dependency analysis seems to be be in a very sad state.

I use the 'keep your fingers crossed and hope it will work' method.

Years ago I wanted to add a -needs(Vsn) annotation to module

For example:

-needs(erl18).

Means would mean you need version 18 of erlang.

That way if you added a needs annotation to the code that used the updated lists
then an earlier version of Erlang could give a meaningfull diagnostic
and not just
crash when the encountering a function 'from the future'.

Actually I had another problem today - a program I wrote in 2003 did not work
with the latest and greatest Erlang - not because the language had changed
but because the library functions had been renamed and moved around.

I guess a lint program would be useful here. It should be fairly
doable to download
all old erlangs and simple make lists of all the function names in all modules
and do a bit of consistency checking.

Cheers

/Joe




> Thoughts?
>
> --
> J.
>
> _______________________________________________
> erlang-questions mailing list
> erlang-***@erlang.org
> http://erlang.org/mailman/listinfo/erlang-questions
>
Jesse Gumm
2016-03-02 20:01:22 UTC
Permalink
I'd like to go ahead and throw in a big fat "same". I've also
reimplemented the wheel in Nitrogen with a `join` function that
interleaves a list of things with some other things. So cast my vote
for a lists:join. `join` I would argue is much more accessible, as 1)
it's quite common in other languages, 2) stays remains consistent with
string:join and filename:join, and 3) brevity is awesome.

-Jesse

On Wed, Mar 2, 2016 at 12:28 PM, Joe Armstrong <***@gmail.com> wrote:
> On Wed, Mar 2, 2016 at 3:47 PM, Jesper Louis Andersen
> <***@gmail.com> wrote:
>> Hi Erlangers,
>>
>> I'd really like to add two functions to the lists module from Haskell:
>>
>> intersperse(List, Seperator) produces a list where each element is separated
>> by separator, i.e.
>>
>> X = [1,2,3]
>> [1, x, 2, x, 3] = lists:intersperse(X, x),
>>
>> and it's cousin, intercalate(ListOfLists, Separator) is
>> append(intersperse(ListOfLists, Seperator)), i.e,
>>
>> Y = ["a", "b", "c"]
>> "a, b, c" = lists:intercalate(Y, ", "),
>>
>> The implementations are straightforward and easy to write tests for, even
>> property based tests if needed.
>>
>> The rationale for this proposal is that I find myself implementing this
>> function again and again in every project I write, and it is highly generic.
>> It belongs in a typical list module. OCaml libraries add it. Haskell's
>> Data.List has it. I believe Erlang, being a practical language, should have
>> it as well.
>>
>
> This is a splendid function - I have one myself called interleave, the only
> problem is that if somebody uses this and puts their code in a library on github
> and somebody fetches this code and runs it with an *old* version of erlang
> then they will get a error and probably blame your code.
>
> This is why I have a single library called elib2_misc.erl where I put *all* the
> stuff that should be somewhere else - then I ship this with my code.
>
> The whole story of dependency analysis seems to be be in a very sad state.
>
> I use the 'keep your fingers crossed and hope it will work' method.
>
> Years ago I wanted to add a -needs(Vsn) annotation to module
>
> For example:
>
> -needs(erl18).
>
> Means would mean you need version 18 of erlang.
>
> That way if you added a needs annotation to the code that used the updated lists
> then an earlier version of Erlang could give a meaningfull diagnostic
> and not just
> crash when the encountering a function 'from the future'.
>
> Actually I had another problem today - a program I wrote in 2003 did not work
> with the latest and greatest Erlang - not because the language had changed
> but because the library functions had been renamed and moved around.
>
> I guess a lint program would be useful here. It should be fairly
> doable to download
> all old erlangs and simple make lists of all the function names in all modules
> and do a bit of consistency checking.
>
> Cheers
>
> /Joe
>
>
>
>
>> Thoughts?
>>
>> --
>> J.
>>
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-***@erlang.org
>> http://erlang.org/mailman/listinfo/erlang-questions
>>
> _______________________________________________
> erlang-questions mailing list
> erlang-***@erlang.org
> http://erlang.org/mailman/listinfo/erlang-questions



--
Jesse Gumm
Owner, Sigma Star Systems
414.940.4866 || sigma-star.com || @jessegumm
Vlad Dumitrescu
2016-03-02 20:05:12 UTC
Permalink
On Wed, Mar 2, 2016 at 7:28 PM, Joe Armstrong <***@gmail.com> wrote:

> Years ago I wanted to add a -needs(Vsn) annotation to module
>
> For example:
>
> -needs(erl18).
>
> Means would mean you need version 18 of erlang.
>
> That way if you added a needs annotation to the code that used the updated
> lists
> then an earlier version of Erlang could give a meaningfull diagnostic
> and not just
> crash when the encountering a function 'from the future'.
>
> Actually I had another problem today - a program I wrote in 2003 did not
> work
> with the latest and greatest Erlang - not because the language had changed
> but because the library functions had been renamed and moved around.
>
> I guess a lint program would be useful here. It should be fairly
> doable to download
> all old erlangs and simple make lists of all the function names in all
> modules
> and do a bit of consistency checking.
>

One such tool is geas https://github.com/crownedgrouse/geas.

regards,
Vlad
Michael Truog
2016-03-03 01:25:20 UTC
Permalink
On 03/02/2016 10:28 AM, Joe Armstrong wrote:
> On Wed, Mar 2, 2016 at 3:47 PM, Jesper Louis Andersen
> <***@gmail.com> wrote:
>> Hi Erlangers,
>>
>> I'd really like to add two functions to the lists module from Haskell:
>>
>> intersperse(List, Seperator) produces a list where each element is separated
>> by separator, i.e.
>>
>> X = [1,2,3]
>> [1, x, 2, x, 3] = lists:intersperse(X, x),
>>
>> and it's cousin, intercalate(ListOfLists, Separator) is
>> append(intersperse(ListOfLists, Seperator)), i.e,
>>
>> Y = ["a", "b", "c"]
>> "a, b, c" = lists:intercalate(Y, ", "),
>>
>> The implementations are straightforward and easy to write tests for, even
>> property based tests if needed.
>>
>> The rationale for this proposal is that I find myself implementing this
>> function again and again in every project I write, and it is highly generic.
>> It belongs in a typical list module. OCaml libraries add it. Haskell's
>> Data.List has it. I believe Erlang, being a practical language, should have
>> it as well.
>>
> This is a splendid function - I have one myself called interleave, the only
> problem is that if somebody uses this and puts their code in a library on github
> and somebody fetches this code and runs it with an *old* version of erlang
> then they will get a error and probably blame your code.
>
> This is why I have a single library called elib2_misc.erl where I put *all* the
> stuff that should be somewhere else - then I ship this with my code.
>
> The whole story of dependency analysis seems to be be in a very sad state.
>
> I use the 'keep your fingers crossed and hope it will work' method.
>
> Years ago I wanted to add a -needs(Vsn) annotation to module
>
> For example:
>
> -needs(erl18).
>
> Means would mean you need version 18 of erlang.
>
> That way if you added a needs annotation to the code that used the updated lists
> then an earlier version of Erlang could give a meaningfull diagnostic
> and not just
> crash when the encountering a function 'from the future'.
>
> Actually I had another problem today - a program I wrote in 2003 did not work
> with the latest and greatest Erlang - not because the language had changed
> but because the library functions had been renamed and moved around.

https://github.com/erlang/eep/blob/master/eeps/eep-0044.md#the-otp_release-macro
combined with
https://github.com/erlang/eep/blob/master/eeps/eep-0044.md#the--error-directive should
do what you want, though it is more verbose and flexible.

> I guess a lint program would be useful here. It should be fairly
> doable to download
> all old erlangs and simple make lists of all the function names in all modules
> and do a bit of consistency checking.

Dialyzer seems like the Erlang lint program. If the Erlang install automatically generated a
plt file for it, it might be a bit easier to use it as part of normal compilation.

The alternative
might be to use http://erlang.org/doc/man/xref.html as a command line tool, if the checking
needs to only consider functions and not types. I am not aware of a standalone (escript)
to run xref, but that may be useful for normal Erlang development (aside from rebar or
other build tool usage).
Loïc Hoguin
2016-03-03 09:23:54 UTC
Permalink
On 03/03/2016 02:25 AM, Michael Truog wrote:
> The alternative
> might be to use http://erlang.org/doc/man/xref.html as a command line
> tool, if the checking
> needs to only consider functions and not types. I am not aware of a
> standalone (escript)
> to run xref, but that may be useful for normal Erlang development (aside
> from rebar or
> other build tool usage).

https://github.com/inaka/xref_runner

--
Loïc Hoguin
http://ninenines.eu
Author of The Erlanger Playbook,
A book about software development using Erlang
Éric Pailleau
2016-03-02 20:41:49 UTC
Permalink
_______________________________________________
erlang-questions mailing list
erlang-***@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions
Richard A. O'Keefe
2016-03-03 00:32:13 UTC
Permalink
On 3/03/16 3:47 am, Jesper Louis Andersen wrote:
> I'd really like to add two functions to the lists module from Haskell:
>
> intersperse(List, Seperator)
Why have you swapped the arguments? The Haskellfunction
Data.List.intersperse :: a -> [a] -> [a]
puts the separator *first*.

> produces a list where each element is separated by separator,

You can't separate one thing. The elements *are* separated by the
separator.
>
> and it's cousin, intercalate(ListOfLists, Separator) is
> append(intersperse(ListOfLists, Seperator)),
Once again, why have you switched the arguments?

Data.List.intercalate :: [a] -> [[a]] -> [a]

puts the separator *first*.

I've never really been happy with the name "intercalate".
To the extent that it's acceptableto use "intercalate"
for anything other than adding chunks to the calendar in
order to fix itup, it means what the intersperse function
does. However, the name _is_ established inHaskell, and
there's no point in gratuitous difference.

Which is why it is important to get the argument order right.

intersperse and intercalate are very nearly the same function.

intersperse sep xs = interwhatsit (:) [] (sep:) xs
intercalate sep xs = interwhatsit (++) [] (sep++) xs

interwhatsit :: (a -> b -> b) -> b -> (b -> b) -> [a] -> b
-- Combine End Separate Items

interwhatsit _ e _ [] = e
interwhatsit c e s (x:xs) = loop xs x
where loop [] x = c x e
loop (y:ys) x = c x $ s $ loop ys y

Do we want to have the special cases without the general case?
(There has to be a better name than interwhatsit. sepfoldr?)
>
> The rationale for this proposal is that I find myself implementing
> this function again and again in every project I write

Why would you do that rather than putting it in a utilities module and
just reusing that module?
> , and it is highly generic.
That sounds as though you have some other use in mind for these
functions than pasting strings together. I'd love to know what.
I've been using Haskell since before it had intersperse and
intercalate, and can't remember ever using them.
Jesper Louis Andersen
2016-03-05 10:03:17 UTC
Permalink
So to catch up:

* I need to learn how to spell separator :)
* Indeed, the argument order should be intersperse(Sep, Xs), not the other
way around. This looks consistent with most List functions.

* On Joe's comments of why not simply a utility library:

This would have been fine, were it not for the fact that Erlang is
miserably bad at handling ad-hoc utility libraries for other modules. There
is no way I can hide joe_utils.erl since it is a globally known name. This
creates lots of versioning problems down the road. In e.g., Standard ML or
OCaml, I could just package the modules such that 'module JoeUtils' is not
exported outside the scope of the individual libraries and applications.
But Erlang is not that language.

I also think intersperse/intercalate are so often used they shouldn't be in
everyones utils library but should be put in the stdlib base.

* 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 :)

One could argue we should just have tooling such as Hughes-combinators[0]
for output rather than the singular intersperse function, but it is by the
far the missing tool in the toolbox when trying to use standard Erlang as
were it a pretty-printing combinator library.

* On the name choice of 'intersperse/intercalate':

I think the semantics I'm aiming for is so close to the OCaml(Core)/Haskell
implementations I'm willing to reuse that name. Another valid name is
'join' which is common in many other languages. I don't think one is better
than the other, but the FP roots in me says we should adopt FP-language
naming.

NEXT STEP:

I'd like to produce the necessary PR for 'intersperse' first, which gives
me an idea of where to put changes. This builds a small unit of work which
should be easy to make concrete. We can always augment this with additional
functions later.' We need at least:

* The implementation in lists.erl (I don't think we need to make it fast
right away, so plain Erlang it is)
* Documentation of the function, with examples
* Tests with good coverage of the function.

Once this is done, adding 'intercalate' is easy, but the question is if it
is needed since once can just 'append' after having interspersed. The power
of having a special function is that it is amenable to certain
optimizations if they are kept as a larger block.

[0] The thing I have in mind here is John Hughes "The Design of a
Pretty-printing library"
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.38.8777



On Wed, Mar 2, 2016 at 3:47 PM, Jesper Louis Andersen <
***@gmail.com> wrote:

> Hi Erlangers,
>
> I'd really like to add two functions to the lists module from Haskell:
>
> intersperse(List, Seperator) produces a list where each element is
> separated by separator, i.e.
>
> X = [1,2,3]
> [1, x, 2, x, 3] = lists:intersperse(X, x),
>
> and it's cousin, intercalate(ListOfLists, Separator) is
> append(intersperse(ListOfLists, Seperator)), i.e,
>
> Y = ["a", "b", "c"]
> "a, b, c" = lists:intercalate(Y, ", "),
>
> The implementations are straightforward and easy to write tests for, even
> property based tests if needed.
>
> The rationale for this proposal is that I find myself implementing this
> function again and again in every project I write, and it is highly
> generic. It belongs in a typical list module. OCaml libraries add it.
> Haskell's Data.List has it. I believe Erlang, being a practical language,
> should have it as well.
>
> Thoughts?
>
> --
> J.
>



--
J.
Garrett Smith
2016-03-05 14:22:24 UTC
Permalink
On Sat, Mar 5, 2016 at 4:04 AM Jesper Louis Andersen <
***@gmail.com> 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.


> * On the name choice of 'intersperse/intercalate':
>
> I think the semantics I'm aiming for is so close to the
> OCaml(Core)/Haskell implementations I'm willing to reuse that name. Another
> valid name is 'join' which is common in many other languages. I don't think
> one is better than the other, but the FP roots in me says we should adopt
> FP-language naming.
>

In looking over the naming conventions in Erlang, one might assume that the
design pattern is for diversity rather than uniformity. That's a nice way
to look at it I think.

Personally I'd vote to converge on some standards rather than diverge - and
taking cues from Erlang, and not the many many other languages, will help
there. The clear analog is string:join. It's also short - saves valuable
typing cycles!
Björn-Egil Dahlberg
2016-03-05 14:38:23 UTC
Permalink
I think those functions are nice things to add to the lists module. No
reason to hide them in some weird extra lib module.

The names though. Naming isn't easy. I actually had to look up the word
"intercalate" and now I know it roughly means "insert". Perhaps it really
best describes what the functions does but .. can't we find anything
shorter?

2016-03-05 15:22 GMT+01:00 Garrett Smith <***@rre.tt>:

> On Sat, Mar 5, 2016 at 4:04 AM Jesper Louis Andersen <
> ***@gmail.com> 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.
>
>
>> * On the name choice of 'intersperse/intercalate':
>>
>> I think the semantics I'm aiming for is so close to the
>> OCaml(Core)/Haskell implementations I'm willing to reuse that name. Another
>> valid name is 'join' which is common in many other languages. I don't think
>> one is better than the other, but the FP roots in me says we should adopt
>> FP-language naming.
>>
>
> In looking over the naming conventions in Erlang, one might assume that
> the design pattern is for diversity rather than uniformity. That's a nice
> way to look at it I think.
>
> Personally I'd vote to converge on some standards rather than diverge -
> and taking cues from Erlang, and not the many many other languages, will
> help there. The clear analog is string:join. It's also short - saves
> valuable typing cycles!
>
>
> _______________________________________________
> erlang-questions mailing list
> erlang-***@erlang.org
> http://erlang.org/mailman/listinfo/erlang-questions
>
>
Richard A. O'Keefe
2016-03-07 03:50:22 UTC
Permalink
On 6/03/16 3:22 am, Garrett Smith wrote:

> On Sat, Mar 5, 2016 at 4:04 AM Jesper Louis Andersen
> <***@gmail.com
> <mailto:***@gmail.com>> 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.
Garrett Smith
2016-03-07 15:08:06 UTC
Permalink
On Sun, Mar 6, 2016 at 9:50 PM Richard A. O'Keefe <***@cs.otago.ac.nz> wrote:

> On 6/03/16 3:22 am, Garrett Smith wrote:
>
> > On Sat, Mar 5, 2016 at 4:04 AM Jesper Louis Andersen
> > <***@gmail.com
> > <mailto:***@gmail.com>> 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.
>

I agree to use lists:join with vigilance and trepidation. It won't make it
any less useful.


> 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.
>

It's vague, as is intercalculate, but as it's superficially doing what
string "join" does with chars has some precedence within Erlang. I wouldn't
call it hopeless.
Jesper Louis Andersen
2016-03-07 15:27:30 UTC
Permalink
This post might be inappropriate. Click to display it.
Garrett Smith
2016-03-07 15:53:09 UTC
Permalink
On Mon, Mar 7, 2016 at 9:28 AM Jesper Louis Andersen <
***@gmail.com> wrote:

>
> On Mon, Mar 7, 2016 at 4:08 PM, Garrett Smith <***@rre.tt> wrote:
>
>> It's vague, as is intercalculate, but as it's superficially doing what
>> string "join" does with chars has some precedence within Erlang. I wouldn't
>> call it hopeless.
>
>
> I'm probably leaning away from using 'join' at this point, since 'join'
> already have type
>
> join :: Monad M => m (m a) -> m a
>
>
so from an FP perspective, that name is highly confusing since it is in use
> in monadic context and is used to join monadic data into its own monadic
> context. For a list, join is essentially 'append':
>
> Prelude Control.Monad> join ["a", "b", "c"]
> "abc"
>
> But join is monadic, so `join $ Just Nothing` evaluates to `Nothing`.
>

Sigh. Okay, so the future naming discussions will involve with word monad
and monadic?

You've seen the discussions around adoption and the disruptive influence of
Elixir?

For whatever reason FP pedantry is not a draw for me. When I need
inspiration I look to Python. Maybe that's the wrong direction and we need
to drive our community through more gates.


> I mean, C++ also uses the word Functor, but they know jack shit about what
> that means mathematically. And almost every language knows jack shit about
> what join really is either :)
>

Oh, and functor.
Loïc Hoguin
2016-03-07 16:04:12 UTC
Permalink
On 03/07/2016 04:53 PM, Garrett Smith wrote:
> On Mon, Mar 7, 2016 at 9:28 AM Jesper Louis Andersen
> <***@gmail.com
> <mailto:***@gmail.com>> wrote:
>
>
> On Mon, Mar 7, 2016 at 4:08 PM, Garrett Smith <***@rre.tt
> <mailto:***@rre.tt>> wrote:
>
> It's vague, as is intercalculate, but as it's superficially
> doing what string "join" does with chars has some precedence
> within Erlang. I wouldn't call it hopeless.
>
>
> I'm probably leaning away from using 'join' at this point, since
> 'join' already have type
>
> join :: Monad M => m (m a) -> m a
>
> so from an FP perspective, that name is highly confusing since it is
> in use in monadic context and is used to join monadic data into its
> own monadic context. For a list, join is essentially 'append':
>
> Prelude Control.Monad> join ["a", "b", "c"]
> "abc"
>
> But join is monadic, so `join $ Just Nothing` evaluates to `Nothing`.
>
>
> Sigh. Okay, so the future naming discussions will involve with word
> monad and monadic?
>
> You've seen the discussions around adoption and the disruptive influence
> of Elixir?
>
> For whatever reason FP pedantry is not a draw for me. When I need
> inspiration I look to Python. Maybe that's the wrong direction and we
> need to drive our community through more gates.

I am completely with you on that. If the function was called
intercalculate I'd never find it and would continue writing my own.

Precision is important, but it's even more important to think about who
the users are (or who you want them to be) and to lose some of this
precision to make things clearer for them. And as far as I can tell,
people don't go to Erlang because of their mathematical background.

Human languages are interesting like that, because the more you go for
precision the less people understand what you mean. Specialized terms
are only good for people with the same specialization. If you want the
most people to get it, use terms that a fourth grader would understand.

--
Loïc Hoguin
http://ninenines.eu
Author of The Erlanger Playbook,
A book about software development using Erlang
Chandru
2016-03-08 07:24:41 UTC
Permalink
On 7 March 2016 at 16:04, Loïc Hoguin <***@ninenines.eu> wrote:

> On 03/07/2016 04:53 PM, Garrett Smith wrote:
>
>> On Mon, Mar 7, 2016 at 9:28 AM Jesper Louis Andersen
>> <***@gmail.com
>> <mailto:***@gmail.com>> wrote:
>>
>>
>> On Mon, Mar 7, 2016 at 4:08 PM, Garrett Smith <***@rre.tt
>> <mailto:***@rre.tt>> wrote:
>>
>> It's vague, as is intercalculate, but as it's superficially
>> doing what string "join" does with chars has some precedence
>> within Erlang. I wouldn't call it hopeless.
>>
>>
>> I'm probably leaning away from using 'join' at this point, since
>> 'join' already have type
>>
>> join :: Monad M => m (m a) -> m a
>>
>> so from an FP perspective, that name is highly confusing since it is
>> in use in monadic context and is used to join monadic data into its
>> own monadic context. For a list, join is essentially 'append':
>>
>> Prelude Control.Monad> join ["a", "b", "c"]
>> "abc"
>>
>> But join is monadic, so `join $ Just Nothing` evaluates to `Nothing`.
>>
>>
>> Sigh. Okay, so the future naming discussions will involve with word
>> monad and monadic?
>>
>> You've seen the discussions around adoption and the disruptive influence
>> of Elixir?
>>
>> For whatever reason FP pedantry is not a draw for me. When I need
>> inspiration I look to Python. Maybe that's the wrong direction and we
>> need to drive our community through more gates.
>>
>
> I am completely with you on that. If the function was called
> intercalculate I'd never find it and would continue writing my own.
>
>
I second this. I'm part of the vast number of unwashed masses who've never
heard of the term intercalculate, and if I came across it in a developer's
code would think that they were being a bit too clever. Like many others I
have written this piece of code several times and invariably named it
'concat_with_separator' - a mouthful but it conveys (at least to me) what
exactly the function is doing.

cheers,
Chandru
Mike French
2016-03-08 07:42:35 UTC
Permalink
This post might be inappropriate. Click to display it.
Ivan Uemlianin
2016-03-08 08:21:21 UTC
Permalink
> ... 'intercalculate' ... 'intercalate' ...
>

Let's call the whole thing off.
Joe Armstrong
2016-03-08 16:56:13 UTC
Permalink
I'd call it punctuate (to mark or divide with punctuation marks) - since this
is what I'd use this of, so punctuate(Claues, ';') means a a ';'
between clauses.

We could make a new library called stacks which is all of lists renamed with new
things in and phase out lists.

Lists are actually stacks - explaining how to reverse a stack to beginners
is far easier than a list - I just get them to think of a stack of
plates in a restaurant,
one empty one full ....

Just because lisp go it wrong doesn't mean to say that everybody else
should follow


/Joe


On Mon, Mar 7, 2016 at 11:24 PM, Chandru
<***@gmail.com> wrote:
> On 7 March 2016 at 16:04, Loïc Hoguin <***@ninenines.eu> wrote:
>>
>> On 03/07/2016 04:53 PM, Garrett Smith wrote:
>>>
>>> On Mon, Mar 7, 2016 at 9:28 AM Jesper Louis Andersen
>>> <***@gmail.com
>>> <mailto:***@gmail.com>> wrote:
>>>
>>>
>>> On Mon, Mar 7, 2016 at 4:08 PM, Garrett Smith <***@rre.tt
>>> <mailto:***@rre.tt>> wrote:
>>>
>>> It's vague, as is intercalculate, but as it's superficially
>>> doing what string "join" does with chars has some precedence
>>> within Erlang. I wouldn't call it hopeless.
>>>
>>>
>>> I'm probably leaning away from using 'join' at this point, since
>>> 'join' already have type
>>>
>>> join :: Monad M => m (m a) -> m a
>>>
>>> so from an FP perspective, that name is highly confusing since it is
>>> in use in monadic context and is used to join monadic data into its
>>> own monadic context. For a list, join is essentially 'append':
>>>
>>> Prelude Control.Monad> join ["a", "b", "c"]
>>> "abc"
>>>
>>> But join is monadic, so `join $ Just Nothing` evaluates to `Nothing`.
>>>
>>>
>>> Sigh. Okay, so the future naming discussions will involve with word
>>> monad and monadic?
>>>
>>> You've seen the discussions around adoption and the disruptive influence
>>> of Elixir?
>>>
>>> For whatever reason FP pedantry is not a draw for me. When I need
>>> inspiration I look to Python. Maybe that's the wrong direction and we
>>> need to drive our community through more gates.
>>
>>
>> I am completely with you on that. If the function was called
>> intercalculate I'd never find it and would continue writing my own.
>>
>
> I second this. I'm part of the vast number of unwashed masses who've never
> heard of the term intercalculate, and if I came across it in a developer's
> code would think that they were being a bit too clever. Like many others I
> have written this piece of code several times and invariably named it
> 'concat_with_separator' - a mouthful but it conveys (at least to me) what
> exactly the function is doing.
>
> cheers,
> Chandru
>
>
> _______________________________________________
> erlang-questions mailing list
> erlang-***@erlang.org
> http://erlang.org/mailman/listinfo/erlang-questions
>
Richard A. O'Keefe
2016-03-08 23:18:44 UTC
Permalink
On 8/03/16 8:24 pm, Chandru wrote:
> On 7 March 2016 at 16:04, Loïc Hoguin <***@ninenines.eu
> <mailto:***@ninenines.eu>> wrote:
>
>
> I am completely with you on that. If the function was called
> intercalculate I'd never find it and would continue writing my own.
>
>
> I second this. I'm part of the vast number of unwashed masses who've
> never heard of the term intercalculate,

Please, if you are going to pour scorn on a word, at least COPY
the thing correctly. The proposal is not "intercalCULate" but
"intercalate",
and it's a real English word with a history going back at least 400 years
in English, 500 years in French, and 2500 years in Latin.

I think it's a bad name not because nobody knows what it means (I'd expect
any skilled native speaker of English to have met it several times) but
because
it means to insert ONE (unusual) thing into a sequence of (ordinary) things,
as in one leap day or one leap month into a year.

> and if I came across it in a developer's code would think that they
> were being a bit too clever. Like many others I have written this
> piece of code several times and invariably named it
> 'concat_with_separator' - a mouthful but it conveys (at least to me)
> what exactly the function is doing.
Since 1997 (if not before) the SML Basis Library has included

fun concatWith _ [] = ""
| concatWith separator (string :: strings) =
concat (string :: map (fn x => separator^x) strings)

(*) I am using that as a specification. It would be a horrible
implementation.

Since 2015 that library includes

fun concatWithMap separator f data =
concatWith separator (map f data)

except that the point of concatWithMap is to fuse the calculations.
concat{,With}{,Map} are available on all vector-like types in the SML Basis.

Would those names do?
Chandru
2016-03-09 10:27:05 UTC
Permalink
On 8 March 2016 at 23:18, Richard A. O'Keefe <***@cs.otago.ac.nz> wrote:

> On 8/03/16 8:24 pm, Chandru wrote:
>
>> On 7 March 2016 at 16:04, Loïc Hoguin <***@ninenines.eu <mailto:
>> ***@ninenines.eu>> wrote:
>>
>>
>> I am completely with you on that. If the function was called
>> intercalculate I'd never find it and would continue writing my own.
>>
>>
>> I second this. I'm part of the vast number of unwashed masses who've
>> never heard of the term intercalculate,
>>
>
> Please, if you are going to pour scorn on a word, at least COPY
> the thing correctly. The proposal is not "intercalCULate" but
> "intercalate",
> and it's a real English word with a history going back at least 400 years
> in English, 500 years in French, and 2500 years in Latin.
>

Okay, sorry, my mistake.


>
> I think it's a bad name not because nobody knows what it means (I'd expect
> any skilled native speaker of English to have met it several times) but
> because
> it means to insert ONE (unusual) thing into a sequence of (ordinary)
> things,
> as in one leap day or one leap month into a year.


I looked up the definition and while I couldn't find one which restricts
the insertion to ONE thing, it certainly doesn't say it is the repeated
insertion into a sequence, so clearly intercalate is the wrong choice here.


>
> and if I came across it in a developer's code would think that they were
>> being a bit too clever. Like many others I have written this piece of code
>> several times and invariably named it 'concat_with_separator' - a mouthful
>> but it conveys (at least to me) what exactly the function is doing.
>>
> Since 1997 (if not before) the SML Basis Library has included
>
> fun concatWith _ [] = ""
> | concatWith separator (string :: strings) =
> concat (string :: map (fn x => separator^x) strings)
>
> (*) I am using that as a specification. It would be a horrible
> implementation.
>
>
I personally would be happy with concat_with or concat_with_separator.

I find the proposal for the use of 'join' wrong. In plain English, joining
things doesn't usually involve inserting things in between.

regards,
Chandru
Richard A. O'Keefe
2016-03-09 23:41:14 UTC
Permalink
On 9/03/16 11:27 pm, Chandru wrote:
>
> I looked up the definition and while I couldn't find one which
> restricts the insertion to ONE thing, it certainly doesn't say it is
> the repeated insertion into a sequence, so clearly intercalate is the
> wrong choice here.
OED sense 1:
To insert (an additional day, days, or month) in the calendar in
order to bring
the current reckoning of time into harmony with the natural solar year.
[The Gregorian calendar inserts ONE day into the year.
The Hebrew calendar inserts ONE month into the year.
Some lunar calendars insert ONE day into a month to catch up with
what the real moon is doing.]

OED sense 2:
To insert or interpose something additional, extraneous, or out of
the ordinary
course, between the ordinary members of any series or the successive
parts of any whole
[One of the examples actually refers to inserting ONE letter into a
word.]
Jesper Louis Andersen
2016-03-07 16:12:40 UTC
Permalink
On Mon, Mar 7, 2016 at 4:53 PM, Garrett Smith <***@rre.tt> wrote:

> Sigh. Okay, so the future naming discussions will involve with word monad
> and monadic?



leaning /= decided.

* I really like `join` for its context in other languages as the thing that
"joins stuff with a separator".
* I like intersperse as a name because it has an extremely precise
specification where join is vague.

One simple decision could be a majority point: the majority expect it to be
join, and we are probably never going to see monadic joins in Erlang (they
require typed worlds anyway for their full power). Besides, Haskell
programmers are more likely to be able to adapt I think.


--
J.
Garrett Smith
2016-03-07 16:31:13 UTC
Permalink
On Mon, Mar 7, 2016 at 10:13 AM Jesper Louis Andersen <
***@gmail.com> wrote:

>
> Besides, Haskell programmers are more likely to be able to adapt I think.
>

Some, perhaps.

Though I could see others flocking from Erlang to Haskell because we can't
keep our monads straight!

>
Richard A. O'Keefe
2016-03-07 23:55:31 UTC
Permalink
On 8/03/16 4:53 am, Garrett Smith wrote:
>
> For whatever reason FP pedantry is not a draw for me. When I need
> inspiration I look to Python. Maybe that's the wrong direction and we
> need to drive our community through more gates.

I don't know what "drive our community through more gates" means,
but copying Python is *definitely* the wrong direction. Heck, even
*Python* (3) hasn't followed Python (2) When it comes to cultural
compatibility with Erlang, Python is better than COBOL, PL/I, or RPG.
But that's about as far as I'd go.

For what it's worth, in Swift there is no 'join' function; instead there
are JoinGenerator and JoinSequence *types*.

Monads aren't pedantry: they're (an instance of) *power*. If you can
view something as a Monad, then you get a range of useful operations
for free. (And this applies to other things like Monoid as well.) It's
not, I think, unfair to say that
Haskell : Erlang :: Category Theory : Naive Set Theory.
I'm a set theory person myself; I have been trying for years to get
further than chapter 3 of any category theory textbook and failing.
(Not unlike the way I get the generalisation of vector spaces to
tensor algebras, but then Clifford algebras trigger math-acrophobia.)
I am very happy with Haskell as a typed functional language, but the
Haskell community does tend to push abstraction to levels where my
ears bleed. But I understand why they are doing it, and it's not
pedantry: it's the passionate pursuit of programming power from
precise analogies. It's the entirely reasonable desire to take a
piece of code that might have worked in Lisp or Erlang and say
"WHY does it work? How can we KNOW before we call it that it's
going to work?" It's the lazy programmer's wish to write something
just once crossed with the software engineer's wish that it should be
*safe* to do so.
Mike French
2016-03-08 07:46:33 UTC
Permalink
For me, Clifford Algebras are all about the physics, not the math.

Haskell : Erlang :: Clifford Algebra : Gibbs' vector notation

So the usual Gibbs vector analysis stuff is a pile of loosely typed expressions that work most of the time if you are careful, but Clifford Algebra is a beautiful strongly typed hierarchy, which is usually correct by construction, but rarely used in the real world.

I would honestly implore everyone to read some of David Hestenes's work on Geometric Algebra for the sheer aesthetic pleasure of seeing how something can be beautiful, powerful and true (in the physics sense of gaining useful insight) all at the same time.

Regards,
Mike
________________________________________
From: erlang-questions-***@erlang.org <erlang-questions-***@erlang.org> on behalf of Richard A. O'Keefe <***@cs.otago.ac.nz>
Sent: Tuesday, March 8, 2016 02:55
To: Garrett Smith; Jesper Louis Andersen
Cc: Erlang (E-mail)
Subject: Re: [erlang-questions] Proposal: add lists:intersperse/2 and lists:intercalate/2

On 8/03/16 4:53 am, Garrett Smith wrote:
>
> For whatever reason FP pedantry is not a draw for me. When I need
> inspiration I look to Python. Maybe that's the wrong direction and we
> need to drive our community through more gates.

I don't know what "drive our community through more gates" means,
but copying Python is *definitely* the wrong direction. Heck, even
*Python* (3) hasn't followed Python (2) When it comes to cultural
compatibility with Erlang, Python is better than COBOL, PL/I, or RPG.
But that's about as far as I'd go.

For what it's worth, in Swift there is no 'join' function; instead there
are JoinGenerator and JoinSequence *types*.

Monads aren't pedantry: they're (an instance of) *power*. If you can
view something as a Monad, then you get a range of useful operations
for free. (And this applies to other things like Monoid as well.) It's
not, I think, unfair to say that
Haskell : Erlang :: Category Theory : Naive Set Theory.
I'm a set theory person myself; I have been trying for years to get
further than chapter 3 of any category theory textbook and failing.
(Not unlike the way I get the generalisation of vector spaces to
tensor algebras, but then Clifford algebras trigger math-acrophobia.)
I am very happy with Haskell as a typed functional language, but the
Haskell community does tend to push abstraction to levels where my
ears bleed. But I understand why they are doing it, and it's not
pedantry: it's the passionate pursuit of programming power from
precise analogies. It's the entirely reasonable desire to take a
piece of code that might have worked in Lisp or Erlang and say
"WHY does it work? How can we KNOW before we call it that it's
going to work?" It's the lazy programmer's wish to write something
just once crossed with the software engineer's wish that it should be
*safe* to do so.
Siraaj Khandkar
2016-03-08 14:12:13 UTC
Permalink
There's really no necessity to appeal to technical algebraic terminology
(at least in this case :)). In common, everyday usage, "join" means to
connect multiple components into one (usually using some sort of a
connector part), so, for strings - its common usage is just fine, while
for sequences/lists - the closest match seems to be fold/reduce and friends.


On 3/8/16 2:46 AM, Mike French wrote:
> For me, Clifford Algebras are all about the physics, not the math.
>
> Haskell : Erlang :: Clifford Algebra : Gibbs' vector notation
>
> So the usual Gibbs vector analysis stuff is a pile of loosely typed expressions that work most of the time if you are careful, but Clifford Algebra is a beautiful strongly typed hierarchy, which is usually correct by construction, but rarely used in the real world.
>
> I would honestly implore everyone to read some of David Hestenes's work on Geometric Algebra for the sheer aesthetic pleasure of seeing how something can be beautiful, powerful and true (in the physics sense of gaining useful insight) all at the same time.
>
> Regards,
> Mike
> ________________________________________
> From: erlang-questions-***@erlang.org <erlang-questions-***@erlang.org> on behalf of Richard A. O'Keefe <***@cs.otago.ac.nz>
> Sent: Tuesday, March 8, 2016 02:55
> To: Garrett Smith; Jesper Louis Andersen
> Cc: Erlang (E-mail)
> Subject: Re: [erlang-questions] Proposal: add lists:intersperse/2 and lists:intercalate/2
>
> On 8/03/16 4:53 am, Garrett Smith wrote:
>>
>> For whatever reason FP pedantry is not a draw for me. When I need
>> inspiration I look to Python. Maybe that's the wrong direction and we
>> need to drive our community through more gates.
>
> I don't know what "drive our community through more gates" means,
> but copying Python is *definitely* the wrong direction. Heck, even
> *Python* (3) hasn't followed Python (2) When it comes to cultural
> compatibility with Erlang, Python is better than COBOL, PL/I, or RPG.
> But that's about as far as I'd go.
>
> For what it's worth, in Swift there is no 'join' function; instead there
> are JoinGenerator and JoinSequence *types*.
>
> Monads aren't pedantry: they're (an instance of) *power*. If you can
> view something as a Monad, then you get a range of useful operations
> for free. (And this applies to other things like Monoid as well.) It's
> not, I think, unfair to say that
> Haskell : Erlang :: Category Theory : Naive Set Theory.
> I'm a set theory person myself; I have been trying for years to get
> further than chapter 3 of any category theory textbook and failing.
> (Not unlike the way I get the generalisation of vector spaces to
> tensor algebras, but then Clifford algebras trigger math-acrophobia.)
> I am very happy with Haskell as a typed functional language, but the
> Haskell community does tend to push abstraction to levels where my
> ears bleed. But I understand why they are doing it, and it's not
> pedantry: it's the passionate pursuit of programming power from
> precise analogies. It's the entirely reasonable desire to take a
> piece of code that might have worked in Lisp or Erlang and say
> "WHY does it work? How can we KNOW before we call it that it's
> going to work?" It's the lazy programmer's wish to write something
> just once crossed with the software engineer's wish that it should be
> *safe* to do so.
>
Richard Carlsson
2016-03-10 07:00:03 UTC
Permalink
2016-03-07 15:55 GMT-08:00 Richard A. O'Keefe <***@cs.otago.ac.nz>:

> the passionate pursuit of programming power from
> precise analogies.
>

Parables, perhaps?
Jesper Louis Andersen
2016-04-11 12:06:27 UTC
Permalink
Reviving this. There is now a PR for the proposal:

https://github.com/erlang/otp/pull/1012

The name is hard. I'm on the verge of asking Robert Virding what it should
be and then use him as the BDFL. I'm not going to ask Joe, since then we
would have disagreement between him and Robert :)



On Wed, Mar 2, 2016 at 3:47 PM, Jesper Louis Andersen <
***@gmail.com> wrote:

> Hi Erlangers,
>
> I'd really like to add two functions to the lists module from Haskell:
>
> intersperse(List, Seperator) produces a list where each element is
> separated by separator, i.e.
>
> X = [1,2,3]
> [1, x, 2, x, 3] = lists:intersperse(X, x),
>
> and it's cousin, intercalate(ListOfLists, Separator) is
> append(intersperse(ListOfLists, Seperator)), i.e,
>
> Y = ["a", "b", "c"]
> "a, b, c" = lists:intercalate(Y, ", "),
>
> The implementations are straightforward and easy to write tests for, even
> property based tests if needed.
>
> The rationale for this proposal is that I find myself implementing this
> function again and again in every project I write, and it is highly
> generic. It belongs in a typical list module. OCaml libraries add it.
> Haskell's Data.List has it. I believe Erlang, being a practical language,
> should have it as well.
>
> Thoughts?
>
> --
> J.
>



--
J.
Siraaj Khandkar
2016-04-11 12:59:19 UTC
Permalink
I think my personal reservation about the name "intersperse" is
addressed by the possibility of later extending to include interval
specification, something like this:

intersperse(A, [A], Interval) -> [A]
when Interval :: random | {regular, pos_integer()} | ... .

where the default is thought of as {regular, 1}.


P.S. I'm crossing my fingers, hoping Robert will not like "join"! :-)


On 4/11/16 8:06 AM, Jesper Louis Andersen wrote:
> Reviving this. There is now a PR for the proposal:
>
> https://github.com/erlang/otp/pull/1012
>
> The name is hard. I'm on the verge of asking Robert Virding what it should
> be and then use him as the BDFL. I'm not going to ask Joe, since then we
> would have disagreement between him and Robert :)
>
>
>
> On Wed, Mar 2, 2016 at 3:47 PM, Jesper Louis Andersen <
> ***@gmail.com> wrote:
>
>> Hi Erlangers,
>>
>> I'd really like to add two functions to the lists module from Haskell:
>>
>> intersperse(List, Seperator) produces a list where each element is
>> separated by separator, i.e.
>>
>> X = [1,2,3]
>> [1, x, 2, x, 3] = lists:intersperse(X, x),
>>
>> and it's cousin, intercalate(ListOfLists, Separator) is
>> append(intersperse(ListOfLists, Seperator)), i.e,
>>
>> Y = ["a", "b", "c"]
>> "a, b, c" = lists:intercalate(Y, ", "),
>>
>> The implementations are straightforward and easy to write tests for, even
>> property based tests if needed.
>>
>> The rationale for this proposal is that I find myself implementing this
>> function again and again in every project I write, and it is highly
>> generic. It belongs in a typical list module. OCaml libraries add it.
>> Haskell's Data.List has it. I believe Erlang, being a practical language,
>> should have it as well.
>>
>> Thoughts?
Benoit Chesneau
2016-04-15 07:12:55 UTC
Permalink
this would be. an interresting addition...
On Mon, 11 Apr 2016 at 14:59, Siraaj Khandkar <***@khandkar.net> wrote:

> I think my personal reservation about the name "intersperse" is
> addressed by the possibility of later extending to include interval
> specification, something like this:
>
> intersperse(A, [A], Interval) -> [A]
> when Interval :: random | {regular, pos_integer()} | ... .
>
> where the default is thought of as {regular, 1}.
>
>
> P.S. I'm crossing my fingers, hoping Robert will not like "join"! :-)
>
>
> On 4/11/16 8:06 AM, Jesper Louis Andersen wrote:
> > Reviving this. There is now a PR for the proposal:
> >
> > https://github.com/erlang/otp/pull/1012
> >
> > The name is hard. I'm on the verge of asking Robert Virding what it
> should
> > be and then use him as the BDFL. I'm not going to ask Joe, since then we
> > would have disagreement between him and Robert :)
> >
> >
> >
> > On Wed, Mar 2, 2016 at 3:47 PM, Jesper Louis Andersen <
> > ***@gmail.com> wrote:
> >
> >> Hi Erlangers,
> >>
> >> I'd really like to add two functions to the lists module from Haskell:
> >>
> >> intersperse(List, Seperator) produces a list where each element is
> >> separated by separator, i.e.
> >>
> >> X = [1,2,3]
> >> [1, x, 2, x, 3] = lists:intersperse(X, x),
> >>
> >> and it's cousin, intercalate(ListOfLists, Separator) is
> >> append(intersperse(ListOfLists, Seperator)), i.e,
> >>
> >> Y = ["a", "b", "c"]
> >> "a, b, c" = lists:intercalate(Y, ", "),
> >>
> >> The implementations are straightforward and easy to write tests for,
> even
> >> property based tests if needed.
> >>
> >> The rationale for this proposal is that I find myself implementing this
> >> function again and again in every project I write, and it is highly
> >> generic. It belongs in a typical list module. OCaml libraries add it.
> >> Haskell's Data.List has it. I believe Erlang, being a practical
> language,
> >> should have it as well.
> >>
> >> Thoughts?
> _______________________________________________
> erlang-questions mailing list
> erlang-***@erlang.org
> http://erlang.org/mailman/listinfo/erlang-questions
>
Loading...