Discussion:
[erlang-patches] Add lists:init/1 - got tired of implementing it
unknown
2013-04-25 15:12:36 UTC
Permalink
Hi,

Yesterday I implemented, for the umpteenth time, the init-function. (I
guess being taught Haskell at one point could be blamed partly for the
coding style requiring this function...) It is a trivial function that I
think should be part of the standard lists module. This patch adds the
function, tests in lists_SUITE, and documentation of the function.

The implementation is trivial: reverse(tl(reverse(List))).

If I've missed some religious reason for not having this function feel
free to drop the patch ;-)

Cheers,
Hans

git fetch git://github.com/hanssv/otp.git add_init_to_lists

https://github.com/hanssv/otp/compare/erlang:maint...add_init_to_lists
https://github.com/hanssv/otp/compare/erlang:maint...add_init_to_lists.patch
unknown
2013-04-25 15:54:10 UTC
Permalink
Sounds to me like it would have been better implemented as something like:

init([_]) -> [];
init([H|T]) -> [H|init(T)].

As this would avoid re-building the list twice, once on each reversal.

Regards,
Fred.
Post by unknown
Hi,
Yesterday I implemented, for the umpteenth time, the init-function. (I
guess being taught Haskell at one point could be blamed partly for the
coding style requiring this function...) It is a trivial function that I
think should be part of the standard lists module. This patch adds the
function, tests in lists_SUITE, and documentation of the function.
The implementation is trivial: reverse(tl(reverse(List))).
If I've missed some religious reason for not having this function feel
free to drop the patch ;-)
Cheers,
Hans
git fetch git://github.com/hanssv/otp.**git<http://github.com/hanssv/otp.git>add_init_to_lists
https://github.com/hanssv/otp/**compare/erlang:maint...add_**init_to_lists<https://github.com/hanssv/otp/compare/erlang:maint...add_init_to_lists>
https://github.com/hanssv/otp/**compare/erlang:maint...add_**
init_to_lists.patch<https://github.com/hanssv/otp/compare/erlang:maint...add_init_to_lists.patch>
______________________________**_________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/**listinfo/erlang-patches<http://erlang.org/mailman/listinfo/erlang-patches>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-patches/attachments/20130425/7c10fc85/attachment.html>
unknown
2013-04-25 15:57:48 UTC
Permalink
What about non-tail-recursiveness, though?
Post by unknown
init([_]) -> [];
init([H|T]) -> [H|init(T)].
As this would avoid re-building the list twice, once on each reversal.
Regards,
Fred.
Post by unknown
Hi,
Yesterday I implemented, for the umpteenth time, the init-function. (I
guess being taught Haskell at one point could be blamed partly for the
coding style requiring this function...) It is a trivial function that I
think should be part of the standard lists module. This patch adds the
function, tests in lists_SUITE, and documentation of the function.
The implementation is trivial: reverse(tl(reverse(List))).
If I've missed some religious reason for not having this function feel
free to drop the patch ;-)
Cheers,
Hans
git fetch git://github.com/hanssv/otp.**git<http://github.com/hanssv/otp.git>add_init_to_lists
https://github.com/hanssv/otp/**compare/erlang:maint...add_**
init_to_lists<https://github.com/hanssv/otp/compare/erlang:maint...add_init_to_lists>
https://github.com/hanssv/otp/**compare/erlang:maint...add_**
init_to_lists.patch<https://github.com/hanssv/otp/compare/erlang:maint...add_init_to_lists.patch>
______________________________**_________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/**listinfo/erlang-patches<http://erlang.org/mailman/listinfo/erlang-patches>
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-patches/attachments/20130425/ff435e38/attachment.html>
unknown
2013-04-25 16:18:34 UTC
Permalink
I don't think there's any benefit in tail-recursion when you're
rebuilding an entirely new list. Given the limited number of arguments,
the list you're creating by not being tail-recursive is in all points
similar to the one you would have to maintain on the stack through tail
recursions. Maybe a bit larger, but given you don't have to trash it,
you're likely to avoid GC costs by doing it that way.

See http://erlang.2086793.n4.nabble.com/Efficiency-of-a-list-construction-td3538122.html#a3538379
and http://ferd.ca/erlang-s-tail-recursion-is-not-a-silver-bullet.html
for more information.

What I would worry about in my implementation is adding a clause
of 'init([]) -> error(badarg)' to be consequent in failures with the rest
of the lists module, and not get a 'function_clause' error there when
someone passes in an empty list.
Post by unknown
What about non-tail-recursiveness, though?
Post by unknown
init([_]) -> [];
init([H|T]) -> [H|init(T)].
As this would avoid re-building the list twice, once on each reversal.
Regards,
Fred.
Post by unknown
Hi,
Yesterday I implemented, for the umpteenth time, the init-function. (I
guess being taught Haskell at one point could be blamed partly for the
coding style requiring this function...) It is a trivial function that I
think should be part of the standard lists module. This patch adds the
function, tests in lists_SUITE, and documentation of the function.
The implementation is trivial: reverse(tl(reverse(List))).
If I've missed some religious reason for not having this function feel
free to drop the patch ;-)
Cheers,
Hans
git fetch git://github.com/hanssv/otp.**git<http://github.com/hanssv/otp.git>add_init_to_lists
https://github.com/hanssv/otp/**compare/erlang:maint...add_**
init_to_lists<https://github.com/hanssv/otp/compare/erlang:maint...add_init_to_lists>
https://github.com/hanssv/otp/**compare/erlang:maint...add_**
init_to_lists.patch<https://github.com/hanssv/otp/compare/erlang:maint...add_init_to_lists.patch>
______________________________**_________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/**listinfo/erlang-patches<http://erlang.org/mailman/listinfo/erlang-patches>
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
unknown
2013-04-26 09:33:16 UTC
Permalink
You are absolutely right about the 'badarg', it is better to have a
consistent failure!

However on performance, the suggested implementation is somewhat
surprisingly the best option (I admit, I did measure before writing the
patch ;-) ) For lists up to 3000 elements, it is on average ~x1.8 faster
than a (tail-)recursive implementation!

So a better version would probably be:
init([]) -> error(badarg);
init(List = [_ | _]) ->
lists:reverse(tl(lists:reverse(List)));
init(_) -> error(badarg).

/Hans
Post by unknown
I don't think there's any benefit in tail-recursion when you're
rebuilding an entirely new list. Given the limited number of arguments,
the list you're creating by not being tail-recursive is in all points
similar to the one you would have to maintain on the stack through tail
recursions. Maybe a bit larger, but given you don't have to trash it,
you're likely to avoid GC costs by doing it that way.
See http://erlang.2086793.n4.nabble.com/Efficiency-of-a-list-construction-td3538122.html#a3538379
and http://ferd.ca/erlang-s-tail-recursion-is-not-a-silver-bullet.html
for more information.
What I would worry about in my implementation is adding a clause
of 'init([]) -> error(badarg)' to be consequent in failures with the rest
of the lists module, and not get a 'function_clause' error there when
someone passes in an empty list.
Post by unknown
What about non-tail-recursiveness, though?
Post by unknown
init([_]) -> [];
init([H|T]) -> [H|init(T)].
As this would avoid re-building the list twice, once on each reversal.
Regards,
Fred.
Post by unknown
Hi,
Yesterday I implemented, for the umpteenth time, the init-function. (I
guess being taught Haskell at one point could be blamed partly for the
coding style requiring this function...) It is a trivial function that I
think should be part of the standard lists module. This patch adds the
function, tests in lists_SUITE, and documentation of the function.
The implementation is trivial: reverse(tl(reverse(List))).
If I've missed some religious reason for not having this function feel
free to drop the patch ;-)
Cheers,
Hans
git fetch git://github.com/hanssv/otp.**git<http://github.com/hanssv/otp.git>add_init_to_lists
https://github.com/hanssv/otp/**compare/erlang:maint...add_**
init_to_lists<https://github.com/hanssv/otp/compare/erlang:maint...add_init_to_lists>
https://github.com/hanssv/otp/**compare/erlang:maint...add_**
init_to_lists.patch<https://github.com/hanssv/otp/compare/erlang:maint...add_init_to_lists.patch>
______________________________**_________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/**listinfo/erlang-patches<http://erlang.org/mailman/listinfo/erlang-patches>
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
unknown
2013-04-26 13:41:56 UTC
Permalink
Ah yeah, the version that reverses twice is more likely to be fast due
to the fact that lists:reverse/1 calls lists:reverse/2, which is now a
NIF. Thus the traversal and building is gonna be made in C rather than
in Erlang. Testing with a 'homemade' lists:reverse/2 tends to bring
things back to the more expected N vs. 2N for traversals.

Regards,
Fred.
Post by unknown
You are absolutely right about the 'badarg', it is better to have a
consistent failure!
However on performance, the suggested implementation is somewhat
surprisingly the best option (I admit, I did measure before writing
the patch ;-) ) For lists up to 3000 elements, it is on average
~x1.8 faster than a (tail-)recursive implementation!
init([]) -> error(badarg);
init(List = [_ | _]) ->
lists:reverse(tl(lists:reverse(List)));
init(_) -> error(badarg).
/Hans
Post by unknown
I don't think there's any benefit in tail-recursion when you're
rebuilding an entirely new list. Given the limited number of arguments,
the list you're creating by not being tail-recursive is in all points
similar to the one you would have to maintain on the stack through tail
recursions. Maybe a bit larger, but given you don't have to trash it,
you're likely to avoid GC costs by doing it that way.
See http://erlang.2086793.n4.nabble.com/Efficiency-of-a-list-construction-td3538122.html#a3538379
and http://ferd.ca/erlang-s-tail-recursion-is-not-a-silver-bullet.html
for more information.
What I would worry about in my implementation is adding a clause
of 'init([]) -> error(badarg)' to be consequent in failures with the rest
of the lists module, and not get a 'function_clause' error there when
someone passes in an empty list.
Post by unknown
What about non-tail-recursiveness, though?
Post by unknown
init([_]) -> [];
init([H|T]) -> [H|init(T)].
As this would avoid re-building the list twice, once on each reversal.
Regards,
Fred.
Post by unknown
Hi,
Yesterday I implemented, for the umpteenth time, the init-function. (I
guess being taught Haskell at one point could be blamed partly for the
coding style requiring this function...) It is a trivial function that I
think should be part of the standard lists module. This patch adds the
function, tests in lists_SUITE, and documentation of the function.
The implementation is trivial: reverse(tl(reverse(List))).
If I've missed some religious reason for not having this function feel
free to drop the patch ;-)
Cheers,
Hans
git fetch git://github.com/hanssv/otp.**git<http://github.com/hanssv/otp.git>add_init_to_lists
https://github.com/hanssv/otp/**compare/erlang:maint...add_**
init_to_lists<https://github.com/hanssv/otp/compare/erlang:maint...add_init_to_lists>
https://github.com/hanssv/otp/**compare/erlang:maint...add_**
init_to_lists.patch<https://github.com/hanssv/otp/compare/erlang:maint...add_init_to_lists.patch>
______________________________**_________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/**listinfo/erlang-patches<http://erlang.org/mailman/listinfo/erlang-patches>
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
unknown
2013-04-26 14:17:25 UTC
Permalink
The name of this function seems to be misleading though. Since init/1
usually refers to initialization of something (e.g. gen behaviors),
perhaps a better choice of the name would be: drop_tail/1.
Post by unknown
Ah yeah, the version that reverses twice is more likely to be fast due
to the fact that lists:reverse/1 calls lists:reverse/2, which is now a
NIF. Thus the traversal and building is gonna be made in C rather than
in Erlang. Testing with a 'homemade' lists:reverse/2 tends to bring
things back to the more expected N vs. 2N for traversals.
Regards,
Fred.
Post by unknown
You are absolutely right about the 'badarg', it is better to have a
consistent failure!
However on performance, the suggested implementation is somewhat
surprisingly the best option (I admit, I did measure before writing
the patch ;-) ) For lists up to 3000 elements, it is on average
~x1.8 faster than a (tail-)recursive implementation!
init([]) -> error(badarg);
init(List = [_ | _]) ->
lists:reverse(tl(lists:reverse(List)));
init(_) -> error(badarg).
/Hans
Post by unknown
I don't think there's any benefit in tail-recursion when you're
rebuilding an entirely new list. Given the limited number of arguments,
the list you're creating by not being tail-recursive is in all points
similar to the one you would have to maintain on the stack through tail
recursions. Maybe a bit larger, but given you don't have to trash it,
you're likely to avoid GC costs by doing it that way.
See http://erlang.2086793.n4.nabble.com/Efficiency-of-a-list-construction-td3538122.html#a3538379
and http://ferd.ca/erlang-s-tail-recursion-is-not-a-silver-bullet.html
for more information.
What I would worry about in my implementation is adding a clause
of 'init([]) -> error(badarg)' to be consequent in failures with the rest
of the lists module, and not get a 'function_clause' error there when
someone passes in an empty list.
Post by unknown
What about non-tail-recursiveness, though?
Post by unknown
init([_]) -> [];
init([H|T]) -> [H|init(T)].
As this would avoid re-building the list twice, once on each reversal.
Regards,
Fred.
Post by unknown
Hi,
Yesterday I implemented, for the umpteenth time, the init-function. (I
guess being taught Haskell at one point could be blamed partly for the
coding style requiring this function...) It is a trivial function that I
think should be part of the standard lists module. This patch adds the
function, tests in lists_SUITE, and documentation of the function.
The implementation is trivial: reverse(tl(reverse(List))).
If I've missed some religious reason for not having this function feel
free to drop the patch ;-)
Cheers,
Hans
git fetch git://github.com/hanssv/otp.**git<http://github.com/hanssv/otp.git>add_init_to_lists
https://github.com/hanssv/otp/**compare/erlang:maint...add_**
init_to_lists<https://github.com/hanssv/otp/compare/erlang:maint...add_init_to_lists>
https://github.com/hanssv/otp/**compare/erlang:maint...add_**
init_to_lists.patch<https://github.com/hanssv/otp/compare/erlang:maint...add_init_to_lists.patch>
______________________________**_________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/**listinfo/erlang-patches<http://erlang.org/mailman/listinfo/erlang-patches>
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
unknown
2013-04-26 15:46:27 UTC
Permalink
Apologies, the recommended name should be lists:drop_last/1 (rather than
what I wrote in the email below).
Post by unknown
The name of this function seems to be misleading though. Since init/1
usually refers to initialization of something (e.g. gen behaviors),
perhaps a better choice of the name would be: drop_tail/1.
Post by unknown
Ah yeah, the version that reverses twice is more likely to be fast due
to the fact that lists:reverse/1 calls lists:reverse/2, which is now a
NIF. Thus the traversal and building is gonna be made in C rather than
in Erlang. Testing with a 'homemade' lists:reverse/2 tends to bring
things back to the more expected N vs. 2N for traversals.
Regards,
Fred.
Post by unknown
You are absolutely right about the 'badarg', it is better to have a
consistent failure!
However on performance, the suggested implementation is somewhat
surprisingly the best option (I admit, I did measure before writing
the patch ;-) ) For lists up to 3000 elements, it is on average
~x1.8 faster than a (tail-)recursive implementation!
init([]) -> error(badarg);
init(List = [_ | _]) ->
lists:reverse(tl(lists:reverse(List)));
init(_) -> error(badarg).
/Hans
Post by unknown
I don't think there's any benefit in tail-recursion when you're
rebuilding an entirely new list. Given the limited number of arguments,
the list you're creating by not being tail-recursive is in all points
similar to the one you would have to maintain on the stack through tail
recursions. Maybe a bit larger, but given you don't have to trash it,
you're likely to avoid GC costs by doing it that way.
See http://erlang.2086793.n4.nabble.com/Efficiency-of-a-list-construction-td3538122.html#a3538379
and http://ferd.ca/erlang-s-tail-recursion-is-not-a-silver-bullet.html
for more information.
What I would worry about in my implementation is adding a clause
of 'init([]) -> error(badarg)' to be consequent in failures with the rest
of the lists module, and not get a 'function_clause' error there when
someone passes in an empty list.
Post by unknown
What about non-tail-recursiveness, though?
Post by unknown
init([_]) -> [];
init([H|T]) -> [H|init(T)].
As this would avoid re-building the list twice, once on each reversal.
Regards,
Fred.
Post by unknown
Hi,
Yesterday I implemented, for the umpteenth time, the init-function. (I
guess being taught Haskell at one point could be blamed partly for the
coding style requiring this function...) It is a trivial function that I
think should be part of the standard lists module. This patch adds the
function, tests in lists_SUITE, and documentation of the function.
The implementation is trivial: reverse(tl(reverse(List))).
If I've missed some religious reason for not having this function feel
free to drop the patch ;-)
Cheers,
Hans
git fetch git://github.com/hanssv/otp.**git<http://github.com/hanssv/otp.git>add_init_to_lists
https://github.com/hanssv/otp/**compare/erlang:maint...add_**
init_to_lists<https://github.com/hanssv/otp/compare/erlang:maint...add_init_to_lists>
https://github.com/hanssv/otp/**compare/erlang:maint...add_**
init_to_lists.patch<https://github.com/hanssv/otp/compare/erlang:maint...add_init_to_lists.patch>
______________________________**_________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/**listinfo/erlang-patches<http://erlang.org/mailman/listinfo/erlang-patches>
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
unknown
2013-04-25 16:05:30 UTC
Permalink
Hmm... if add new functions into lists, think about this one too:

%% --------------------------------------------
%% @spec lists_first(Pred,List) -> {Element, List}
%%
%% @doc Pick first element from List, for which Pred return true.
%% @end ---------------------------------------
lists_first(_Pred,[]) ->
undefined;
lists_first(Pred,[Element|Rest]) ->
case Pred(Element) of
true -> Element;
_ -> lists_first(Pred, Rest)
end.

%% --------------------------------------------
%% @spec lists_nth(Pred,N,List) -> {Element, List}
%%
%% @doc Pick Nth element from List, for which Pred return true.
%% @end ---------------------------------------
lists_nth(_Pred,_N,[]) ->
undefined;
lists_nth(Pred,N,[Element|Rest]) ->
case Pred(Element) of
true -> case N of
0 -> Element;
_ -> lists_nth(Pred, N-1, Rest)
end;
_ -> lists_nth(Pred, N, Rest)
end.

also have tired of copying in several projects.
Post by unknown
init([_]) -> [];
init([H|T]) -> [H|init(T)].
As this would avoid re-building the list twice, once on each reversal.
Regards,
Fred.
Post by unknown
Hi,
Yesterday I implemented, for the umpteenth time, the init-function. (I
guess being taught Haskell at one point could be blamed partly for the
coding style requiring this function...) It is a trivial function that I
think should be part of the standard lists module. This patch adds the
function, tests in lists_SUITE, and documentation of the function.
The implementation is trivial: reverse(tl(reverse(List))).
If I've missed some religious reason for not having this function feel
free to drop the patch ;-)
Cheers,
Hans
git fetch
git://github.com/hanssv/otp.**git<http://github.com/hanssv/otp.git>add_init_to_lists
https://github.com/hanssv/otp/**compare/erlang:maint...add_**init_to_lists<https://github.com/hanssv/otp/compare/erlang:maint...add_init_to_lists>
https://github.com/hanssv/otp/**compare/erlang:maint...add_**
init_to_lists.patch<https://github.com/hanssv/otp/compare/erlang:maint...add_init_to_lists.patch>
______________________________**_________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/**listinfo/erlang-patches<http://erlang.org/mailman/listinfo/erlang-patches>
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
--
Regards,
Anton Fedorov
Call2ru service
E-Mail: datacompboy
Jabber: datacompboy
Skype: datacompboy
ICQ: 272-35-262
Mobile: +7-913-925-7974 [SMS 24h, Call 05:00-19:00 MSKT (GMT+3)]
unknown
2013-04-25 17:17:44 UTC
Permalink
lists_first can easily be implemented by using dropwhile and hd. Which is
how I would use it if I would ever need it in a project.
Post by unknown
%% --------------------------------------------
%%
lists_first(_Pred,[]) ->
undefined;
lists_first(Pred,[Element|Rest]) ->
case Pred(Element) of
true -> Element;
_ -> lists_first(Pred, Rest)
end.
%% --------------------------------------------
%%
lists_nth(_Pred,_N,[]) ->
undefined;
lists_nth(Pred,N,[Element|Rest]) ->
case Pred(Element) of
true -> case N of
0 -> Element;
_ -> lists_nth(Pred, N-1, Rest)
end;
_ -> lists_nth(Pred, N, Rest)
end.
also have tired of copying in several projects.
Post by unknown
Sounds to me like it would have been better implemented as something
init([_]) -> [];
init([H|T]) -> [H|init(T)].
As this would avoid re-building the list twice, once on each reversal.
Regards,
Fred.
On Thu, Apr 25, 2013 at 11:12 AM, Hans Svensson <hanssv>
Post by unknown
Hi,
Yesterday I implemented, for the umpteenth time, the init-function. (I
guess being taught Haskell at one point could be blamed partly for the
coding style requiring this function...) It is a trivial function that I
think should be part of the standard lists module. This patch adds the
function, tests in lists_SUITE, and documentation of the function.
The implementation is trivial: reverse(tl(reverse(List))).
If I've missed some religious reason for not having this function feel
free to drop the patch ;-)
Cheers,
Hans
git fetch
git://github.com/hanssv/otp.**git<http://github.com/hanssv/otp.git
add_init_to_lists
https://github.com/hanssv/otp/**compare/erlang:maint...add_**init_to_lists
<https://github.com/hanssv/otp/compare/erlang:maint...add_init_to_lists>
Post by unknown
Post by unknown
https://github.com/hanssv/otp/**compare/erlang:maint...add_**
init_to_lists.patch<
https://github.com/hanssv/otp/compare/erlang:maint...add_init_to_lists.patch
Post by unknown
Post by unknown
______________________________**_________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/**listinfo/erlang-patches<
http://erlang.org/mailman/listinfo/erlang-patches>
Post by unknown
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
--
Regards,
Anton Fedorov
Call2ru service
E-Mail: datacompboy
Jabber: datacompboy
Skype: datacompboy
ICQ: 272-35-262
Mobile: +7-913-925-7974 [SMS 24h, Call 05:00-19:00 MSKT (GMT+3)]
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-patches/attachments/20130425/29a2dc7a/attachment-0001.html>
unknown
2013-04-28 02:57:16 UTC
Permalink
But it creates more garbage so it will cause the collector to run more often, which costs.

Robert

----- Original Message -----
From: "Fred Hebert" <mononcqc>
Ah yeah, the version that reverses twice is more likely to be fast
due
to the fact that lists:reverse/1 calls lists:reverse/2, which is now
a
NIF. Thus the traversal and building is gonna be made in C rather
than
in Erlang. Testing with a 'homemade' lists:reverse/2 tends to bring
things back to the more expected N vs. 2N for traversals.
Regards,
Fred.
Post by unknown
You are absolutely right about the 'badarg', it is better to have a
consistent failure!
However on performance, the suggested implementation is somewhat
surprisingly the best option (I admit, I did measure before writing
the patch ;-) ) For lists up to 3000 elements, it is on average
~x1.8 faster than a (tail-)recursive implementation!
init([]) -> error(badarg);
init(List = [_ | _]) ->
lists:reverse(tl(lists:reverse(List)));
init(_) -> error(badarg).
/Hans
Post by unknown
I don't think there's any benefit in tail-recursion when you're
rebuilding an entirely new list. Given the limited number of
arguments,
the list you're creating by not being tail-recursive is in all
points
similar to the one you would have to maintain on the stack through
tail
recursions. Maybe a bit larger, but given you don't have to trash
it,
you're likely to avoid GC costs by doing it that way.
See
http://erlang.2086793.n4.nabble.com/Efficiency-of-a-list-construction-td3538122.html#a3538379
and
http://ferd.ca/erlang-s-tail-recursion-is-not-a-silver-bullet.html
for more information.
What I would worry about in my implementation is adding a clause
of 'init([]) -> error(badarg)' to be consequent in failures with
the rest
of the lists module, and not get a 'function_clause' error there
when
someone passes in an empty list.
Post by unknown
What about non-tail-recursiveness, though?
On Thu, Apr 25, 2013 at 8:54 AM, Fred Hebert <mononcqc>
Post by unknown
Sounds to me like it would have been better implemented as
init([_]) -> [];
init([H|T]) -> [H|init(T)].
As this would avoid re-building the list twice, once on each
reversal.
Regards,
Fred.
On Thu, Apr 25, 2013 at 11:12 AM, Hans Svensson
Post by unknown
Hi,
Yesterday I implemented, for the umpteenth time, the
init-function. (I
guess being taught Haskell at one point could be blamed partly
for the
coding style requiring this function...) It is a trivial
function that I
think should be part of the standard lists module. This patch
adds the
function, tests in lists_SUITE, and documentation of the
function.
The implementation is trivial: reverse(tl(reverse(List))).
If I've missed some religious reason for not having this
function feel
free to drop the patch ;-)
Cheers,
Hans
git fetch
git://github.com/hanssv/otp.**git<http://github.com/hanssv/otp.git>add_init_to_lists
https://github.com/hanssv/otp/**compare/erlang:maint...add_**
init_to_lists<https://github.com/hanssv/otp/compare/erlang:maint...add_init_to_lists>
https://github.com/hanssv/otp/**compare/erlang:maint...add_**
init_to_lists.patch<https://github.com/hanssv/otp/compare/erlang:maint...add_init_to_lists.patch>
______________________________**_________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/**listinfo/erlang-patches<http://erlang.org/mailman/listinfo/erlang-patches>
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
unknown
2013-04-29 07:24:02 UTC
Permalink
Post by unknown
git fetch git://github.com/hanssv/otp.git add_init_to_lists
Fetched, it is currently located in the 'pu' branch.
A review process has started.
Thanks,
--
BR Fredrik Gustafsson
Erlang OTP Team
unknown
2013-04-30 10:05:29 UTC
Permalink
We haven't yet made any decision regarding this patch, but we have had some
discussions in the team and we are not totally convinced about the general
need for this function. Thus we would appreciate some input from the list.

So - disregarding the name and the implementation for a second - is this
functionality a good addition to the lists module? Is it often needed?

If so, would it be even better to do a more general version which removes
the N last elements from the list?

Hans, could you also possibly describe some of your use cases?

Regards
siri


2013/4/29 Fredrik <fredrik>
Post by unknown
Post by unknown
git fetch git://github.com/hanssv/otp.**git<http://github.com/hanssv/otp.git>add_init_to_lists
Fetched, it is currently located in the 'pu' branch.
A review process has started.
Thanks,
--
BR Fredrik Gustafsson
Erlang OTP Team
______________________________**_________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/**listinfo/erlang-patches<http://erlang.org/mailman/listinfo/erlang-patches>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-patches/attachments/20130430/eeb9ddea/attachment.html>
unknown
2013-04-30 13:32:22 UTC
Permalink
I would use lists:sublist(L, 1, length(L) - 1) for this. I wouldn't
have given it a second thought.

Presumably there's a concern about performance -- why else would we
need yet-another-function?

Here's a simple benchmark program that people can experiment with (or improve):

https://github.com/gar1t/erlang-bench/blob/master/drop-last.escript

It includes the original implementation, Fred's, and what I would use (sublist).

Personally, I don't see a problem that warrants a new function in the
lists module.
Post by unknown
We haven't yet made any decision regarding this patch, but we have had some
discussions in the team and we are not totally convinced about the general
need for this function. Thus we would appreciate some input from the list.
So - disregarding the name and the implementation for a second - is this
functionality a good addition to the lists module? Is it often needed?
If so, would it be even better to do a more general version which removes
the N last elements from the list?
Hans, could you also possibly describe some of your use cases?
Regards
siri
2013/4/29 Fredrik <fredrik>
Post by unknown
Post by unknown
git fetch git://github.com/hanssv/otp.git add_init_to_lists
Fetched, it is currently located in the 'pu' branch.
A review process has started.
Thanks,
--
BR Fredrik Gustafsson
Erlang OTP Team
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
unknown
2013-05-02 07:00:11 UTC
Permalink
You should consider compiling the code before measuring, there is a
difference in speed...
Also, if you'd done that you would have spotted the error in your
recursive implementation...

test_sc.erl:66: Warning: this clause cannot match because a previous
clause at line 65 always matches

Your recursive implementation throws away the whole list immediately,
which is fast but wrong...

Fixing the recursive implementation and re-running with escript (after
changing the sizes of the tests into something smaller) I got
reverse_reverse:small_list: 251
reverse_reverse:big_list: 34
recurse:small_list: 6752
recurse:big_list: 7295
sublist:small_list: 295
sublist:big_list: 69

Which shows the severe performance penalty involved for not compiling
the code... Compiling it yields (with your original test sizes):
reverse_reverse:small_list: 347
reverse_reverse:big_list: 3133
recurse:small_list: 411
recurse:big_list: 4036
sublist:small_list: 635
sublist:big_list: 6175

However, the typical lists on which I'd use init/drop_last, would have
length < 20

Cheers,
Hans
Post by unknown
I would use lists:sublist(L, 1, length(L) - 1) for this. I wouldn't
have given it a second thought.
Presumably there's a concern about performance -- why else would we
need yet-another-function?
https://github.com/gar1t/erlang-bench/blob/master/drop-last.escript
It includes the original implementation, Fred's, and what I would use (sublist).
Personally, I don't see a problem that warrants a new function in the
lists module.
Post by unknown
We haven't yet made any decision regarding this patch, but we have had some
discussions in the team and we are not totally convinced about the general
need for this function. Thus we would appreciate some input from the list.
So - disregarding the name and the implementation for a second - is this
functionality a good addition to the lists module? Is it often needed?
If so, would it be even better to do a more general version which removes
the N last elements from the list?
Hans, could you also possibly describe some of your use cases?
Regards
siri
2013/4/29 Fredrik <fredrik>
Post by unknown
Post by unknown
git fetch git://github.com/hanssv/otp.git add_init_to_lists
Fetched, it is currently located in the 'pu' branch.
A review process has started.
Thanks,
--
BR Fredrik Gustafsson
Erlang OTP Team
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
unknown
2013-05-02 11:57:25 UTC
Permalink
If I understand correctly, the reason to add this function is not
performance. So the discussion about whether to add it or not should
verse around whether it makes sense to have that functionality in the
standard library. Once decided it makes sense, then the discussion
about performance is relevant, but not before.

Also, when discussing whether this function is useful or not, I don't
find particularly constructive talking about higher level use cases
than plainly "getting the last N elements of a list". lists is a very
generic purpose library, we cannot play the game here of assessing all
possible uses of it. Programs may be using lists efficiently but have
an infrequent corner use where it is ok to access them inefficiently
instead of complicating the whole implementation, or maybe is a
prototype, or maybe is useful while debugging in the shell, etc.

For me the important questions, once knowing that at least someone has
a need for this, are:
* Is it generic or couples lists with external application logic?
* Does it clutter the api?
* Does it make sense along with other functions in the api?
* Does it encourage any particularly dangerous use pattern?

IMO, the proposed function with two arguments passes that filter, but
I cannot judge whether the effort of implementing and maintaining it
pays off for OTP.
unknown
2013-05-02 12:32:08 UTC
Permalink
Post by unknown
If I understand correctly, the reason to add this function is not
performance. So the discussion about whether to add it or not should
verse around whether it makes sense to have that functionality in the
standard library. Once decided it makes sense, then the discussion
about performance is relevant, but not before.
Also, when discussing whether this function is useful or not, I don't
find particularly constructive talking about higher level use cases
than plainly "getting the last N elements of a list". lists is a very
generic purpose library, we cannot play the game here of assessing all
possible uses of it. Programs may be using lists efficiently but have
an infrequent corner use where it is ok to access them inefficiently
instead of complicating the whole implementation, or maybe is a
prototype, or maybe is useful while debugging in the shell, etc.
For me the important questions, once knowing that at least someone has
* Is it generic or couples lists with external application logic?
* Does it clutter the api?
* Does it make sense along with other functions in the api?
* Does it encourage any particularly dangerous use pattern?
These are arguments for *why not* to add a function. I think for a
module that's as central as lists, the argument must be *why must*.
Post by unknown
IMO, the proposed function with two arguments passes that filter, but
I cannot judge whether the effort of implementing and maintaining it
pays off for OTP.
I'd love to hear from someone why we need the semantic sugar of
drop_last or drop_nth_last on top of sublist.

Garrett
unknown
2013-05-02 13:07:38 UTC
Permalink
Post by unknown
You should consider compiling the code before measuring, there is a
difference in speed...
Also, if you'd done that you would have spotted the error in your recursive
implementation...
Indeed!
Post by unknown
test_sc.erl:66: Warning: this clause cannot match because a previous clause
at line 65 always matches
Your recursive implementation throws away the whole list immediately, which
is fast but wrong...
One must make certain sacrifices for speed ;)
Post by unknown
Fixing the recursive implementation and re-running with escript (after
changing the sizes of the tests into something smaller) I got
reverse_reverse:small_list: 251
reverse_reverse:big_list: 34
recurse:small_list: 6752
recurse:big_list: 7295
sublist:small_list: 295
sublist:big_list: 69
I nearly blew up my laptop running the correct version.
Post by unknown
Which shows the severe performance penalty involved for not compiling the
reverse_reverse:small_list: 347
reverse_reverse:big_list: 3133
recurse:small_list: 411
recurse:big_list: 4036
sublist:small_list: 635
sublist:big_list: 6175
Thanks for pointing this out!

There's a -mode(compile) attribute you can add to escript files that
will compile them. In addition to getting a more representative
result, it gives you compiler warnings.

It's interesting to me how optimized the recursive algorithm is when compiled!
Post by unknown
However, the typical lists on which I'd use init/drop_last, would have
length < 20
But you *could* use sublist in a pinch :)

And if the semantics were awkward, you *could* write a small function
or macro to name it appropriately.

I know I'm repeating myself, but I think there ought to be a high
standard for adding to core modules -- I just don't see it here.

Thanks very much for pointing out the compilation problem with erlang-bench!

Garrett
Post by unknown
Post by unknown
I would use lists:sublist(L, 1, length(L) - 1) for this. I wouldn't
have given it a second thought.
Presumably there's a concern about performance -- why else would we
need yet-another-function?
https://github.com/gar1t/erlang-bench/blob/master/drop-last.escript
It includes the original implementation, Fred's, and what I would use (sublist).
Personally, I don't see a problem that warrants a new function in the
lists module.
Post by unknown
We haven't yet made any decision regarding this patch, but we have had some
discussions in the team and we are not totally convinced about the general
need for this function. Thus we would appreciate some input from the list.
So - disregarding the name and the implementation for a second - is this
functionality a good addition to the lists module? Is it often needed?
If so, would it be even better to do a more general version which removes
the N last elements from the list?
Hans, could you also possibly describe some of your use cases?
Regards
siri
2013/4/29 Fredrik <fredrik>
Post by unknown
Post by unknown
git fetch git://github.com/hanssv/otp.git add_init_to_lists
Fetched, it is currently located in the 'pu' branch.
A review process has started.
Thanks,
--
BR Fredrik Gustafsson
Erlang OTP Team
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
unknown
2013-05-02 13:27:57 UTC
Permalink
Post by unknown
Post by unknown
You should consider compiling the code before measuring, there is a
difference in speed...
Also, if you'd done that you would have spotted the error in your recursive
implementation...
Indeed!
Post by unknown
test_sc.erl:66: Warning: this clause cannot match because a previous clause
at line 65 always matches
Your recursive implementation throws away the whole list immediately, which
is fast but wrong...
One must make certain sacrifices for speed ;)
Post by unknown
Fixing the recursive implementation and re-running with escript (after
changing the sizes of the tests into something smaller) I got
reverse_reverse:small_list: 251
reverse_reverse:big_list: 34
recurse:small_list: 6752
recurse:big_list: 7295
sublist:small_list: 295
sublist:big_list: 69
I nearly blew up my laptop running the correct version.
Post by unknown
Which shows the severe performance penalty involved for not compiling the
reverse_reverse:small_list: 347
reverse_reverse:big_list: 3133
recurse:small_list: 411
recurse:big_list: 4036
sublist:small_list: 635
sublist:big_list: 6175
Thanks for pointing this out!
There's a -mode(compile) attribute you can add to escript files that
will compile them. In addition to getting a more representative
result, it gives you compiler warnings.
It's interesting to me how optimized the recursive algorithm is when compiled!
Post by unknown
However, the typical lists on which I'd use init/drop_last, would have
length < 20
But you *could* use sublist in a pinch :)
I could, but I'd have to look into the documentation to see, is it
sublist(L, 1, length(L) -1), sublist(1, L, length(L)-1), or sublist(L,
0, length(L)-1). Instead I'd write reverse(tl(reverse(L))) for sure.
Post by unknown
And if the semantics were awkward, you *could* write a small function
or macro to name it appropriately.
I know I'm repeating myself, but I think there ought to be a high
standard for adding to core modules -- I just don't see it here.
I also think there is a symmetry argument to make, we have hd and tl,
but we miss the companion to last!?
Post by unknown
Thanks very much for pointing out the compilation problem with erlang-bench!
No problem, the results were so far from mine that I'd thought there had
to be something fishy going on...

/Hans
Post by unknown
Garrett
Post by unknown
Post by unknown
I would use lists:sublist(L, 1, length(L) - 1) for this. I wouldn't
have given it a second thought.
Presumably there's a concern about performance -- why else would we
need yet-another-function?
https://github.com/gar1t/erlang-bench/blob/master/drop-last.escript
It includes the original implementation, Fred's, and what I would use (sublist).
Personally, I don't see a problem that warrants a new function in the
lists module.
Post by unknown
We haven't yet made any decision regarding this patch, but we have had some
discussions in the team and we are not totally convinced about the general
need for this function. Thus we would appreciate some input from the list.
So - disregarding the name and the implementation for a second - is this
functionality a good addition to the lists module? Is it often needed?
If so, would it be even better to do a more general version which removes
the N last elements from the list?
Hans, could you also possibly describe some of your use cases?
Regards
siri
2013/4/29 Fredrik <fredrik>
Post by unknown
Post by unknown
git fetch git://github.com/hanssv/otp.git add_init_to_lists
Fetched, it is currently located in the 'pu' branch.
A review process has started.
Thanks,
--
BR Fredrik Gustafsson
Erlang OTP Team
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
unknown
2013-05-17 07:46:18 UTC
Permalink
Post by unknown
Post by unknown
Post by unknown
You should consider compiling the code before measuring, there is a
difference in speed...
Also, if you'd done that you would have spotted the error in your recursive
implementation...
Indeed!
Post by unknown
test_sc.erl:66: Warning: this clause cannot match because a previous clause
at line 65 always matches
Your recursive implementation throws away the whole list
immediately, which
is fast but wrong...
One must make certain sacrifices for speed ;)
Post by unknown
Fixing the recursive implementation and re-running with escript (after
changing the sizes of the tests into something smaller) I got
reverse_reverse:small_list: 251
reverse_reverse:big_list: 34
recurse:small_list: 6752
recurse:big_list: 7295
sublist:small_list: 295
sublist:big_list: 69
I nearly blew up my laptop running the correct version.
Post by unknown
Which shows the severe performance penalty involved for not
compiling the
reverse_reverse:small_list: 347
reverse_reverse:big_list: 3133
recurse:small_list: 411
recurse:big_list: 4036
sublist:small_list: 635
sublist:big_list: 6175
Thanks for pointing this out!
There's a -mode(compile) attribute you can add to escript files that
will compile them. In addition to getting a more representative
result, it gives you compiler warnings.
It's interesting to me how optimized the recursive algorithm is when compiled!
Post by unknown
However, the typical lists on which I'd use init/drop_last, would have
length < 20
But you *could* use sublist in a pinch :)
I could, but I'd have to look into the documentation to see, is it
sublist(L, 1, length(L) -1), sublist(1, L, length(L)-1), or sublist(L,
0, length(L)-1). Instead I'd write reverse(tl(reverse(L))) for sure.
Post by unknown
And if the semantics were awkward, you *could* write a small function
or macro to name it appropriately.
I know I'm repeating myself, but I think there ought to be a high
standard for adding to core modules -- I just don't see it here.
I also think there is a symmetry argument to make, we have hd and tl,
but we miss the companion to last!?
Post by unknown
Thanks very much for pointing out the compilation problem with erlang-bench!
No problem, the results were so far from mine that I'd thought there
had to be something fishy going on...
/Hans
Post by unknown
Garrett
Post by unknown
Post by unknown
I would use lists:sublist(L, 1, length(L) - 1) for this. I wouldn't
have given it a second thought.
Presumably there's a concern about performance -- why else would we
need yet-another-function?
https://github.com/gar1t/erlang-bench/blob/master/drop-last.escript
It includes the original implementation, Fred's, and what I would use (sublist).
Personally, I don't see a problem that warrants a new function in the
lists module.
On Tue, Apr 30, 2013 at 5:05 AM, Siri Hansen <erlangsiri>
Post by unknown
We haven't yet made any decision regarding this patch, but we have
had
some
discussions in the team and we are not totally convinced about the general
need for this function. Thus we would appreciate some input from the list.
So - disregarding the name and the implementation for a second - is this
functionality a good addition to the lists module? Is it often needed?
If so, would it be even better to do a more general version which removes
the N last elements from the list?
Hans, could you also possibly describe some of your use cases?
Regards
siri
2013/4/29 Fredrik <fredrik>
Post by unknown
Post by unknown
git fetch git://github.com/hanssv/otp.git add_init_to_lists
Fetched, it is currently located in the 'pu' branch.
A review process has started.
Thanks,
--
BR Fredrik Gustafsson
Erlang OTP Team
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
Hello Hans,
I've got some feedback on your patch after review:
We have decided to reject this patch as we don't see a general need for
the new function.

Thanks for showing interest in contributing!
--
BR Fredrik Gustafsson
Erlang OTP Team

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-patches/attachments/20130517/adbeff99/attachment-0001.html>
unknown
2013-05-21 20:01:01 UTC
Permalink
Post by unknown
Hello Hans,
We have decided to reject this patch as we don't see a general need for
the new function.
Thanks for showing interest in contributing!
--
BR Fredrik Gustafsson
Erlang OTP Team
That is sad news, and we find it a bit strange since *you* (as in the
OTP team) yourself seems use this particular function/pattern quite
frequently. We did a quick search through the OTP code base and found
quite a few places where this particular function is either implemented
recursively and used, or just uses reverse(tl(reverse(List)))). Also
interesting to see is the different names used: first, butlast, but_last
and remove_last_element.

Code implementing the "init"-function:
compiler
v3_core:first/1
v3_kernel:first/1
dialyzer
dialyzer_contracts:but_last/1
dialyzer_gui:butlast/1
hipe
hipe_icode_type:butlast/1
orber
orber_interceptors:remove_last_element/1

Direct uses of reverse(tl(reverse(L))):
sasl
in systools_make:smart_guess/3
wx_gen
in wx_gen:erl_skip_opt2/4
ssh
in ssh_sftpd

Any further comments on this, it is really not a "new" function it is a
missing function ;-)

Cheers,

Hans
unknown
2014-01-16 10:26:02 UTC
Permalink
Hi Hans!

After many and long discussions we have now decided to re-open this patch
and approve it with some comments:

1. we would like the name of the function to be 'droplast'.
2. we want the simple recursive implementation with no special handling of
bad arguments, i.e. we think it is ok with a function_clause error for
arguments that are not non-empty proper lists.

Would you mind doing these adjustments in the patch?

Best Regards
/siri


2013/5/21 Hans Svensson <hanssv>
Post by unknown
Hello Hans,
Post by unknown
We have decided to reject this patch as we don't see a general need for
the new function.
Thanks for showing interest in contributing!
--
BR Fredrik Gustafsson
Erlang OTP Team
That is sad news, and we find it a bit strange since *you* (as in the OTP
team) yourself seems use this particular function/pattern quite frequently.
We did a quick search through the OTP code base and found quite a few
places where this particular function is either implemented recursively and
used, or just uses reverse(tl(reverse(List)))). Also interesting to see is
the different names used: first, butlast, but_last and remove_last_element.
compiler
v3_core:first/1
v3_kernel:first/1
dialyzer
dialyzer_contracts:but_last/1
dialyzer_gui:butlast/1
hipe
hipe_icode_type:butlast/1
orber
orber_interceptors:remove_last_element/1
sasl
in systools_make:smart_guess/3
wx_gen
in wx_gen:erl_skip_opt2/4
ssh
in ssh_sftpd
Any further comments on this, it is really not a "new" function it is a
missing function ;-)
Cheers,
Hans
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-patches/attachments/20140116/134e862d/attachment.html>
unknown
2014-01-16 13:54:55 UTC
Permalink
Shouldn't be called liat/1 instead? Just joking.

Robert

----- Original Message -----
From: "Siri Hansen" <erlangsiri>
To: "Hans Svensson" <hanssv>
Cc: "erlang-patches" <erlang-patches>
Sent: Thursday, 16 January, 2014 11:26:02 AM
Subject: Re: [erlang-patches] Add lists:init/1 - got tired of implementing it
Hi Hans!
After many and long discussions we have now decided to re-open this patch and
1. we would like the name of the function to be 'droplast'.
2. we want the simple recursive implementation with no special handling of
bad arguments, i.e. we think it is ok with a function_clause error for
arguments that are not non-empty proper lists.
Would you mind doing these adjustments in the patch?
Best Regards
/siri
2013/5/21 Hans Svensson < hanssv >
Post by unknown
Post by unknown
Hello Hans,
We have decided to reject this patch as we don't see a general need for
the new function.
Thanks for showing interest in contributing!
--
BR Fredrik Gustafsson
Erlang OTP Team
That is sad news, and we find it a bit strange since *you* (as in the OTP
team) yourself seems use this particular function/pattern quite frequently.
We did a quick search through the OTP code base and found quite a few
places
where this particular function is either implemented recursively and used,
or just uses reverse(tl(reverse(List)))). Also interesting to see is the
different names used: first, butlast, but_last and remove_last_element.
compiler
v3_core:first/1
v3_kernel:first/1
dialyzer
dialyzer_contracts:but_last/1
dialyzer_gui:butlast/1
hipe
hipe_icode_type:butlast/1
orber
orber_interceptors:remove_ last_element/1
sasl
in systools_make:smart_guess/3
wx_gen
in wx_gen:erl_skip_opt2/4
ssh
in ssh_sftpd
Any further comments on this, it is really not a "new" function it is a
missing function ;-)
Cheers,
Hans
______________________________ _________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/ listinfo/erlang-patches
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-patches/attachments/20140116/1a656dc3/attachment.html>
unknown
2014-01-16 22:03:22 UTC
Permalink
Or chop/1 to be compatible with Perl. ;-)

/H?kan

On Thu, Jan 16, 2014 at 2:54 PM, Robert Virding
Post by unknown
Shouldn't be called liat/1 instead? Just joking.
Robert
________________________________
From: "Siri Hansen" <erlangsiri>
To: "Hans Svensson" <hanssv>
Cc: "erlang-patches" <erlang-patches>
Sent: Thursday, 16 January, 2014 11:26:02 AM
Subject: Re: [erlang-patches] Add lists:init/1 - got tired of implementing it
Hi Hans!
After many and long discussions we have now decided to re-open this patch
1. we would like the name of the function to be 'droplast'.
2. we want the simple recursive implementation with no special handling of
bad arguments, i.e. we think it is ok with a function_clause error for
arguments that are not non-empty proper lists.
Would you mind doing these adjustments in the patch?
Best Regards
/siri
2013/5/21 Hans Svensson <hanssv>
Post by unknown
Post by unknown
Hello Hans,
We have decided to reject this patch as we don't see a general need for
the new function.
Thanks for showing interest in contributing!
--
BR Fredrik Gustafsson
Erlang OTP Team
That is sad news, and we find it a bit strange since *you* (as in the OTP
team) yourself seems use this particular function/pattern quite frequently.
We did a quick search through the OTP code base and found quite a few places
where this particular function is either implemented recursively and used,
or just uses reverse(tl(reverse(List)))). Also interesting to see is the
different names used: first, butlast, but_last and remove_last_element.
compiler
v3_core:first/1
v3_kernel:first/1
dialyzer
dialyzer_contracts:but_last/1
dialyzer_gui:butlast/1
hipe
hipe_icode_type:butlast/1
orber
orber_interceptors:remove_last_element/1
sasl
in systools_make:smart_guess/3
wx_gen
in wx_gen:erl_skip_opt2/4
ssh
in ssh_sftpd
Any further comments on this, it is really not a "new" function it is a
missing function ;-)
Cheers,
Hans
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
unknown
2014-01-17 09:44:18 UTC
Permalink
Post by unknown
Shouldn't be called liat/1 instead? Just joking.
Hey! That was my idea!
/ Raimo
Post by unknown
Robert
----- Original Message -----
From: "Siri Hansen" <erlangsiri>
To: "Hans Svensson" <hanssv>
Cc: "erlang-patches" <erlang-patches>
Sent: Thursday, 16 January, 2014 11:26:02 AM
Subject: Re: [erlang-patches] Add lists:init/1 - got tired of implementing it
Hi Hans!
After many and long discussions we have now decided to re-open this patch and
1. we would like the name of the function to be 'droplast'.
2. we want the simple recursive implementation with no special handling of
bad arguments, i.e. we think it is ok with a function_clause error for
arguments that are not non-empty proper lists.
Would you mind doing these adjustments in the patch?
Best Regards
/siri
2013/5/21 Hans Svensson < hanssv >
Post by unknown
Post by unknown
Hello Hans,
We have decided to reject this patch as we don't see a general need for
the new function.
Thanks for showing interest in contributing!
--
BR Fredrik Gustafsson
Erlang OTP Team
That is sad news, and we find it a bit strange since *you* (as in the OTP
team) yourself seems use this particular function/pattern quite frequently.
We did a quick search through the OTP code base and found quite a few
places
where this particular function is either implemented recursively and used,
or just uses reverse(tl(reverse(List)))). Also interesting to see is the
different names used: first, butlast, but_last and remove_last_element.
compiler
v3_core:first/1
v3_kernel:first/1
dialyzer
dialyzer_contracts:but_last/1
dialyzer_gui:butlast/1
hipe
hipe_icode_type:butlast/1
orber
orber_interceptors:remove_ last_element/1
sasl
in systools_make:smart_guess/3
wx_gen
in wx_gen:erl_skip_opt2/4
ssh
in ssh_sftpd
Any further comments on this, it is really not a "new" function it is a
missing function ;-)
Cheers,
Hans
______________________________ _________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/ listinfo/erlang-patches
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
--
/ Raimo Niskanen, Erlang/OTP, Ericsson AB
unknown
2014-01-19 18:15:52 UTC
Permalink
Great! I'll fix that! I happened to re-implement this function again the
other day, and thought about how sad it was that the function wasn't
there ;-)

Would you like me to actually use the function (in the places mentioned
below) as well, our would you prefer that to be a separate patch?

/Hans
Post by unknown
Hi Hans!
After many and long discussions we have now decided to re-open this
1. we would like the name of the function to be 'droplast'.
2. we want the simple recursive implementation with no special handling
of bad arguments, i.e. we think it is ok with a function_clause error
for arguments that are not non-empty proper lists.
Would you mind doing these adjustments in the patch?
Best Regards
/siri
2013/5/21 Hans Svensson <hanssv <mailto:hanssv>>
Hello Hans,
We have decided to reject this patch as we don't see a general need for
the new function.
Thanks for showing interest in contributing!
--
BR Fredrik Gustafsson
Erlang OTP Team
That is sad news, and we find it a bit strange since *you* (as in
the OTP team) yourself seems use this particular function/pattern
quite frequently. We did a quick search through the OTP code base
and found quite a few places where this particular function is
either implemented recursively and used, or just uses
reverse(tl(reverse(List)))). Also interesting to see is the
different names used: first, butlast, but_last and remove_last_element.
compiler
v3_core:first/1
v3_kernel:first/1
dialyzer
dialyzer_contracts:but_last/1
dialyzer_gui:butlast/1
hipe
hipe_icode_type:butlast/1
orber
orber_interceptors:remove___last_element/1
sasl
in systools_make:smart_guess/3
wx_gen
in wx_gen:erl_skip_opt2/4
ssh
in ssh_sftpd
Any further comments on this, it is really not a "new" function it
is a missing function ;-)
Cheers,
Hans
_________________________________________________
erlang-patches mailing list
erlang-patches <mailto:erlang-patches>
http://erlang.org/mailman/__listinfo/erlang-patches
<http://erlang.org/mailman/listinfo/erlang-patches>
unknown
2014-01-19 19:25:33 UTC
Permalink
Separate patch with separate commits one for each application, please.
Post by unknown
Great! I'll fix that! I happened to re-implement this function again the
other day, and thought about how sad it was that the function wasn't there
;-)
Would you like me to actually use the function (in the places mentioned
below) as well, our would you prefer that to be a separate patch?
/Hans
Post by unknown
Hi Hans!
After many and long discussions we have now decided to re-open this
1. we would like the name of the function to be 'droplast'.
2. we want the simple recursive implementation with no special handling
of bad arguments, i.e. we think it is ok with a function_clause error
for arguments that are not non-empty proper lists.
Would you mind doing these adjustments in the patch?
Best Regards
/siri
2013/5/21 Hans Svensson <hanssv <mailto:hanssv>>
Hello Hans,
We have decided to reject this patch as we don't see a general need for
the new function.
Thanks for showing interest in contributing!
--
BR Fredrik Gustafsson
Erlang OTP Team
That is sad news, and we find it a bit strange since *you* (as in
the OTP team) yourself seems use this particular function/pattern
quite frequently. We did a quick search through the OTP code base
and found quite a few places where this particular function is
either implemented recursively and used, or just uses
reverse(tl(reverse(List)))). Also interesting to see is the
different names used: first, butlast, but_last and
remove_last_element.
compiler
v3_core:first/1
v3_kernel:first/1
dialyzer
dialyzer_contracts:but_last/1
dialyzer_gui:butlast/1
hipe
hipe_icode_type:butlast/1
orber
orber_interceptors:remove___last_element/1
sasl
in systools_make:smart_guess/3
wx_gen
in wx_gen:erl_skip_opt2/4
ssh
in ssh_sftpd
Any further comments on this, it is really not a "new" function it
is a missing function ;-)
Cheers,
Hans
_________________________________________________
erlang-patches mailing list
erlang-patches <mailto:erlang-patches>
http://erlang.org/mailman/__listinfo/erlang-patches
<http://erlang.org/mailman/listinfo/erlang-patches>
_______________________________________________
erlang-patches mailing list
erlang-patches
http://erlang.org/mailman/listinfo/erlang-patches
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-patches/attachments/20140119/81e27bc5/attachment.html>
unknown
2014-01-22 22:14:23 UTC
Permalink
Finally got around to do the fixes. Screwed up my git branch, so the
lists:droplast/1 is now in a differently named branch:

git fetch git://github.com/hanssv/otp.git add_droplast_to_lists

https://github.com/hanssv/otp/compare/erlang:maint...add_droplast_to_lists
https://github.com/hanssv/otp/compare/erlang:maint...add_droplast_to_lists.patch


A separate patch with usage will follow as soon as I can find the time
for it!

Cheers,

Hans
Post by unknown
Hi Hans!
After many and long discussions we have now decided to re-open this
1. we would like the name of the function to be 'droplast'.
2. we want the simple recursive implementation with no special handling
of bad arguments, i.e. we think it is ok with a function_clause error
for arguments that are not non-empty proper lists.
Would you mind doing these adjustments in the patch?
Best Regards
/siri
2013/5/21 Hans Svensson <hanssv <mailto:hanssv>>
Hello Hans,
We have decided to reject this patch as we don't see a general need for
the new function.
Thanks for showing interest in contributing!
--
BR Fredrik Gustafsson
Erlang OTP Team
That is sad news, and we find it a bit strange since *you* (as in
the OTP team) yourself seems use this particular function/pattern
quite frequently. We did a quick search through the OTP code base
and found quite a few places where this particular function is
either implemented recursively and used, or just uses
reverse(tl(reverse(List)))). Also interesting to see is the
different names used: first, butlast, but_last and remove_last_element.
compiler
v3_core:first/1
v3_kernel:first/1
dialyzer
dialyzer_contracts:but_last/1
dialyzer_gui:butlast/1
hipe
hipe_icode_type:butlast/1
orber
orber_interceptors:remove___last_element/1
sasl
in systools_make:smart_guess/3
wx_gen
in wx_gen:erl_skip_opt2/4
ssh
in ssh_sftpd
Any further comments on this, it is really not a "new" function it
is a missing function ;-)
Cheers,
Hans
_________________________________________________
erlang-patches mailing list
erlang-patches <mailto:erlang-patches>
http://erlang.org/mailman/__listinfo/erlang-patches
<http://erlang.org/mailman/listinfo/erlang-patches>
unknown
2014-01-23 09:50:56 UTC
Permalink
And a few usages of this function introduced as well. Note, HiPE uses
its own utiity function hipe_bb:butlast/1 which could/should be replaced
by droplast as well. But that change looked a bit too invasive so I left
it as an exercise ;-)

I made this branch on top of the branch with lists:droplast/1, I hope I
got it right!

git fetch git://github.com/hanssv/otp.git using_lists_droplast

https://github.com/hanssv/otp/compare/add_droplast_to_lists...using_lists_droplast
https://github.com/hanssv/otp/compare/add_droplast_to_lists...using_lists_droplast.patch

Cheers,

/Hans
Post by unknown
Finally got around to do the fixes. Screwed up my git branch, so the
git fetch git://github.com/hanssv/otp.git add_droplast_to_lists
https://github.com/hanssv/otp/compare/erlang:maint...add_droplast_to_lists
https://github.com/hanssv/otp/compare/erlang:maint...add_droplast_to_lists.patch
A separate patch with usage will follow as soon as I can find the time
for it!
Cheers,
Hans
Post by unknown
Hi Hans!
After many and long discussions we have now decided to re-open this
1. we would like the name of the function to be 'droplast'.
2. we want the simple recursive implementation with no special handling
of bad arguments, i.e. we think it is ok with a function_clause error
for arguments that are not non-empty proper lists.
Would you mind doing these adjustments in the patch?
Best Regards
/siri
2013/5/21 Hans Svensson <hanssv <mailto:hanssv>>
Hello Hans,
We have decided to reject this patch as we don't see a general need for
the new function.
Thanks for showing interest in contributing!
--
BR Fredrik Gustafsson
Erlang OTP Team
That is sad news, and we find it a bit strange since *you* (as in
the OTP team) yourself seems use this particular function/pattern
quite frequently. We did a quick search through the OTP code base
and found quite a few places where this particular function is
either implemented recursively and used, or just uses
reverse(tl(reverse(List)))). Also interesting to see is the
different names used: first, butlast, but_last and
remove_last_element.
compiler
v3_core:first/1
v3_kernel:first/1
dialyzer
dialyzer_contracts:but_last/1
dialyzer_gui:butlast/1
hipe
hipe_icode_type:butlast/1
orber
orber_interceptors:remove___last_element/1
sasl
in systools_make:smart_guess/3
wx_gen
in wx_gen:erl_skip_opt2/4
ssh
in ssh_sftpd
Any further comments on this, it is really not a "new" function it
is a missing function ;-)
Cheers,
Hans
_________________________________________________
erlang-patches mailing list
erlang-patches <mailto:erlang-patches>
http://erlang.org/mailman/__listinfo/erlang-patches
<http://erlang.org/mailman/listinfo/erlang-patches>
unknown
2013-04-30 17:08:45 UTC
Permalink
Post by unknown
We haven't yet made any decision regarding this patch, but we have had some
discussions in the team and we are not totally convinced about the general
need for this function. Thus we would appreciate some input from the list.
So - disregarding the name and the implementation for a second - is this
functionality a good addition to the lists module? Is it often needed?
Personally: no, not that I recall. My first thought upon seeing it (leaving
naming aside) was that somebody was using a plain list where they really
needed a queue(3) (or some more appropriate data structure, don't know
what the actual use case is).

BR,
-- Jachym
unknown
2013-05-02 06:08:28 UTC
Permalink
Hi,

The most typical use case, for me, is when using either filename:split
or string :tokens to create a list of elements where the last element is
not needed. I.e. this is in some sense a generalization of
filename:dirname/1 (which I bet has something like this in its
implementation...)
I have also seen this exact use is in lib/ssh/src/ssh_sftpd.erl in otp ;-)

Also, when handling a failing test case, which consists of a list of
commands, it is useful to treat the successful commands (init(Commands))
differently from the failing command (last(Commands)).

I have personally never missed the 'remove N last elements'-function.

Cheers,

Hans
Post by unknown
We haven't yet made any decision regarding this patch, but we have had
some discussions in the team and we are not totally convinced about
the general need for this function. Thus we would appreciate some
input from the list.
So - disregarding the name and the implementation for a second - is
this functionality a good addition to the lists module? Is it often
needed?
If so, would it be even better to do a more general version which
removes the N last elements from the list?
Hans, could you also possibly describe some of your use cases?
Regards
siri
2013/4/29 Fredrik <fredrik <mailto:fredrik>>
git fetch git://github.com/hanssv/otp.git
<http://github.com/hanssv/otp.git> add_init_to_lists
Fetched, it is currently located in the 'pu' branch.
A review process has started.
Thanks,
--
BR Fredrik Gustafsson
Erlang OTP Team
_______________________________________________
erlang-patches mailing list
erlang-patches <mailto:erlang-patches>
http://erlang.org/mailman/listinfo/erlang-patches
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-patches/attachments/20130502/5a76de55/attachment.html>
Loading...