elm-community / list-extra

Convenience functions for working with List.
http://package.elm-lang.org/packages/elm-community/list-extra/latest
MIT License
135 stars 59 forks source link

Tail call optimize group while transitively #47

Closed strickinato closed 7 years ago

strickinato commented 7 years ago

After experience stack limiting, I noticed current implementation of groupWhileTransitively doesn't take advantage of tail call optimization.

This PR:

Compare:

Old compiled code:

var _elm_community$list_extra$List_Extra$groupWhileTransitively = F2(
    function (cmp, xs_) {
        var _p13 = xs_;
        if (_p13.ctor === '[]') {
            return {ctor: '[]'};
        } else {
            if (_p13._1.ctor === '[]') {
                return {
                    ctor: '::',
                    _0: {
                        ctor: '::',
                        _0: _p13._0,
                        _1: {ctor: '[]'}
                    },
                    _1: {ctor: '[]'}
                };
            } else {
                var _p15 = _p13._0;
                var _p14 = A2(_elm_community$list_extra$List_Extra$groupWhileTransitively, cmp, _p13._1);
                if (_p14.ctor === '::') {
                    return A2(cmp, _p15, _p13._1._0) ? {
                        ctor: '::',
                        _0: {ctor: '::', _0: _p15, _1: _p14._0},
                        _1: _p14._1
                    } : {
                        ctor: '::',
                        _0: {
                            ctor: '::',
                            _0: _p15,
                            _1: {ctor: '[]'}
                        },
                        _1: _p14
                    };
                } else {
                    return {ctor: '[]'};
                }
            }
        }
    });

New compiled code

var _elm_community$list_extra$List_Extra$groupWhileTransitively = F2(
    function (compare, list) {
        return A4(
            _elm_community$list_extra$List_Extra$groupWhileTransitivelyHelp,
            {ctor: '[]'},
            {ctor: '[]'},
            compare,
            list);
    });
var _elm_community$list_extra$List_Extra$groupWhileTransitivelyHelp = F4(
    function (result, currentGroup, compare, list) {
        groupWhileTransitivelyHelp:
        while (true) {
            var _p13 = list;
            if (_p13.ctor === '[]') {
                return _elm_lang$core$List$reverse(
                    _elm_lang$core$List$isEmpty(currentGroup) ? result : _elm_lang$core$List$reverse(
                        {ctor: '::', _0: currentGroup, _1: result}));
            } else {
                if (_p13._1.ctor === '[]') {
                    return _elm_lang$core$List$reverse(
                        {
                            ctor: '::',
                            _0: _elm_lang$core$List$reverse(
                                {ctor: '::', _0: _p13._0, _1: currentGroup}),
                            _1: result
                        });
                } else {
                    var _p15 = _p13._1;
                    var _p14 = _p13._0;
                    if (A2(compare, _p14, _p13._1._0)) {
                        var _v7 = result,
                            _v8 = {ctor: '::', _0: _p14, _1: currentGroup},
                            _v9 = compare,
                            _v10 = _p15;
                        result = _v7;
                        currentGroup = _v8;
                        compare = _v9;
                        list = _v10;
                        continue groupWhileTransitivelyHelp;
                    } else {
                        var _v11 = {
                            ctor: '::',
                            _0: _elm_lang$core$List$reverse(
                                {ctor: '::', _0: _p14, _1: currentGroup}),
                            _1: result
                        },
                            _v12 = {ctor: '[]'},
                            _v13 = compare,
                            _v14 = _p15;
                        result = _v11;
                        currentGroup = _v12;
                        compare = _v13;
                        list = _v14;
                        continue groupWhileTransitivelyHelp;
                    }
                }
            }
        }
    });