{"action":"created","issue":{"url":"https://api.github.com/repos/elm-community/lazy-list/issues/8","repository_url":"https://api.github.com/repos/elm-community/lazy-list","labels_url":"https://api.github.com/repos/elm-community/lazy-list/issues/8/labels{/name}","comments_url":"https://api.github.com/repos/elm-community/lazy-list/issues/8/comments","events_url":"https://api.github.com/repos/elm-community/lazy-list/issues/8/events","html_url":"https://github.com/elm-community/lazy-list/pull/8","id":209348124,"number":8,"title":"Fix lazy list library module","user":{"login":"GordonBGood","id":10696269,"avatar_url":"https://avatars1.githubusercontent.com/u/10696269?v=4","gravatar_id":"","url":"https://api.github.com/users/GordonBGood","html_url":"https://github.com/GordonBGood","followers_url":"https://api.github.com/users/GordonBGood/followers","following_url":"https://api.github.com/users/GordonBGood/following{/other_user}","gists_url":"https://api.github.com/users/GordonBGood/gists{/gist_id}","starred_url":"https://api.github.com/users/GordonBGood/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GordonBGood/subscriptions","organizations_url":"https://api.github.com/users/GordonBGood/orgs","repos_url":"https://api.github.com/users/GordonBGood/repos","events_url":"https://api.github.com/users/GordonBGood/events{/privacy}","received_events_url":"https://api.github.com/users/GordonBGood/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":8,"created_at":"2017-02-22T04:16:47Z","updated_at":"2017-11-15T22:13:33Z","closed_at":null,"author_association":"NONE","pull_request":{"url":"https://api.github.com/repos/elm-community/lazy-list/pulls/8","html_url":"https://github.com/elm-community/lazy-list/pull/8","diff_url":"https://github.com/elm-community/lazy-list/pull/8.diff","patch_url":"https://github.com/elm-community/lazy-list/pull/8.patch"},"body":"There is one API braking change that is necessary to avoid possible excessive memory consumption:  `number` was a constant that captured an infinite lazy list of all the counting numbers; however, as a constant it can never release the head of the list for garbage collection, so memory used is proportional to the amount of the lazy list that is forced/evaluated.  Thus, if one evaluates a large portion of the infinite list, memory consumption goes toward infinity - essentially a memory leak that lasts until the program is closed.  By making `number()' a zero-arity function, proper use of the function can allow for garbage collection of the head of the list as consumed.\r\n\r\nIn addition, I provide a `naturals()` function which is just the above function with the integer zero per-pended.\r\n\r\nEssentially there are three major parts to the pull request, as follows:\r\n\r\n**Part 1:**  fix all functions so that there are no stack overflows for infinity lazy lists when not necessary by the nature of the function.  These changes follow a general pattern of breaking infinite loops by injection of a deferred (lazy) calculation **before** a function is called that would force evaluation of its arguments.  Changed functions include the following:  `take`, `takeWhile`, `drop`, `dropWhile`, `keepIf`, `dropIf`, all the `map`s, `filterMap`, and `indexedMap`. the to/from `List`/`Array` functions were completely reworked to avoid building stack by not treating non-lazy lists as if they were lazy and rather using a helper accumulator argument to accumulate the new list, then getting an array from the produced list if that is the returned value; these are much more performant ways of doing these conversions.\r\n\r\n**Part 2:**  Add the complete API of the non-lazy `List` library module so that they behave in an equivalent way.  The added functions from `List` include the following: `filter` as a synonym for `keepIf`, `concat` as a synonym for `flatten`, `partition`, `unzip`, `concatMap`, `indexedMap`, `maximum`, `minimum`, `all`, `any`, `scanl`, `append`, `flatten`, `sort`, `sortBy`, and `sortWith`.\r\n\r\n**Part 3:**  Add functions that extend the `List' API for useful things such as following:\r\n\r\n1. `range` can now step downwards if the end value is lower than the start value.\r\n1. The `range` capability is extended by a `rangeStep` function that can be supplied with a step argument so that it can step by a given integer amount; this step must be of the correct sign for increasing/decreasing ranges else an empty lazy list results.\r\n1. In an equivalent way, `openRange` and `openRangeStep` functions are provided that don't take an end limit to produce infinite lazy lists.\r\n1. `nth` finds the nth element of a list if it exists, returning `empty` if this exceeds the length of the list.\r\n1. `indexOf` is the converse of `nth`, returning the integer index of the found member element, if found, and -1 if not found.\r\n1. `indexBy` does the same as the above but uses a predicate to find the first member element that passes the predicate.\r\n\r\nWhere appropriate, all functions use internal help functions to use \"closures\" (Elm's current closures aren't true closures as they depend on the captured free bindings to be immutable, which isn't true for Tail Call Optimized - TCO'd - loops where the internal loop variables are mutable) to reduce the number of passed arguments.  These functions include the following:  `iterate`, `rangeStep`, `openRangeStep`, `member`, `all`, `any`, `indexOf`, `indexBy`, `take`, `takeWhile`, `drop`, `dropWhile`, `intersperse`, `interleave`, `keepIf`, `dropIf`, `unique`, `reduce`, `append`, `flatten`, `scanl`, `maximum`, `minimum`, `numbers()`, all the `map`s, all the `product`s, `partition`, `unzip`, `filterMap`, `indexedMap`, and to/from list/array,\r\n\r\nIn the interests of speed, `foldr` has been changed from using an `Array` (O(n log n) performance) to using a reversed `List` (O(n) performance, but at the cost of increase memory use by almost a factor of two).\r\n\r\nAs well, the documentation examples were re-worked, and the documentation organization was changed to seem logical (to me).\r\n\r\nIn particular, examples are added to the `cons` documentation for code patterns to avoid in the use of `cons`/`Cons` that cause stack overflow.\r\n\r\nAs well, the documentation contains warnings where evaluation of an infinite list by a function would cause an overflow due to the nature of the function such as `length`.\r\n\r\nFinally, I added the infix operator `(!!!)` for `nth`.\r\n\r\nThe library now includes the `tests` folder:  unit tests implemented as a basic HTML page, which include three sections, critical tests where further testing wouldn't mean anything if they fail, ordinary tests, and finally some basic benchmarks using some of the more time-consuming operations.\r\n\r\nAs per my mandate, I have used no Native JavaScript (other than to get the current time in the \"tests\"), but the sorting functions should really call JavaScript directly in order to avoid having to go through `List` (to/from) so as to save some time, but especially to save at least half the memory consumed."},"comment":{"url":"https://api.github.com/repos/elm-community/lazy-list/issues/comments/344746329","html_url":"https://github.com/elm-community/lazy-list/pull/8#issuecomment-344746329","issue_url":"https://api.github.com/repos/elm-community/lazy-list/issues/8","id":344746329,"user":{"login":"GordonBGood","id":10696269,"avatar_url":"https://avatars1.githubusercontent.com/u/10696269?v=4","gravatar_id":"","url":"https://api.github.com/users/GordonBGood","html_url":"https://github.com/GordonBGood","followers_url":"https://api.github.com/users/GordonBGood/followers","following_url":"https://api.github.com/users/GordonBGood/following{/other_user}","gists_url":"https://api.github.com/users/GordonBGood/gists{/gist_id}","starred_url":"https://api.github.com/users/GordonBGood/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GordonBGood/subscriptions","organizations_url":"https://api.github.com/users/GordonBGood/orgs","repos_url":"https://api.github.com/users/GordonBGood/repos","events_url":"https://api.github.com/users/GordonBGood/events{/privacy}","received_events_url":"https://api.github.com/users/GordonBGood/received_events","type":"User","site_admin":false},"created_at":"2017-11-15T22:13:33Z","updated_at":"2017-11-15T22:13:33Z","author_association":"NONE","body":"What do you mean it (the linked version) no longer memoizes; it still is\ncomposed of Lazy elements which still memoize. My PR does the same, thus\navoiding the use of additional raw JavaScript code (other than as used by\nLazy).\n\nBy choosing the linked eeue56 version, you are going back to a very limited\nnon-general-purpose version that likely has the same limitations as to use\nwith infinite lists as my extensive PR here fixes. If that is the version\nthat is the way forward for Elm 0.19, I can apply my PR to that version.\n\nI also note that there is a circular reference in tests in that this\nlibrary is to be used by tests, but tests is a dependency, which only works\nhere because the currents tests is dependent on this version not the eeua56\nversion.\n\n\nOn Nov 14, 2017 18:37, \"Noah\" <notifications@github.com> wrote:\n\n> This package is going to be depreciated with 0.19. There is an\n> alternative, which you can find here: https://github.com/eeue56/elm-\n> lazy-list\n>\n> The main difference is that it no longer memoizes, only delays evaluation\n> until needed.\n>\n> —\n> You are receiving this because you authored the thread.\n> Reply to this email directly, view it on GitHub\n> <https://github.com/elm-community/lazy-list/pull/8#issuecomment-344232211>,\n> or mute the thread\n> <https://github.com/notifications/unsubscribe-auth/AKM2TctcWOw8XfKnf4uQeK2OnBCdeQQzks5s2XttgaJpZM4MIMFO>\n> .\n>\n"}}
{"actor":{"display_login":"GordonBGood"}}