{"action":"created","issue":{"url":"https://api.github.com/repos/dlang/phobos/issues/5154","repository_url":"https://api.github.com/repos/dlang/phobos","labels_url":"https://api.github.com/repos/dlang/phobos/issues/5154/labels{/name}","comments_url":"https://api.github.com/repos/dlang/phobos/issues/5154/comments","events_url":"https://api.github.com/repos/dlang/phobos/issues/5154/events","html_url":"https://github.com/dlang/phobos/pull/5154","id":208743912,"number":5154,"title":"Added std.range.orElse which provides a default value for empty ranges","user":{"login":"wilzbach","id":4370550,"avatar_url":"https://avatars.githubusercontent.com/u/4370550?v=3","gravatar_id":"","url":"https://api.github.com/users/wilzbach","html_url":"https://github.com/wilzbach","followers_url":"https://api.github.com/users/wilzbach/followers","following_url":"https://api.github.com/users/wilzbach/following{/other_user}","gists_url":"https://api.github.com/users/wilzbach/gists{/gist_id}","starred_url":"https://api.github.com/users/wilzbach/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wilzbach/subscriptions","organizations_url":"https://api.github.com/users/wilzbach/orgs","repos_url":"https://api.github.com/users/wilzbach/repos","events_url":"https://api.github.com/users/wilzbach/events{/privacy}","received_events_url":"https://api.github.com/users/wilzbach/received_events","type":"User","site_admin":false},"labels":[{"id":117785235,"url":"https://api.github.com/repos/dlang/phobos/labels/needs%20decision","name":"needs decision","color":"009800","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2017-02-19T20:29:25Z","updated_at":"2017-02-21T16:08:05Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/dlang/phobos/pulls/5154","html_url":"https://github.com/dlang/phobos/pull/5154","diff_url":"https://github.com/dlang/phobos/pull/5154.diff","patch_url":"https://github.com/dlang/phobos/pull/5154.patch"},"body":"As mentioned on #5153 if an API method could potentially return an \"undefined response (aka `null`), there are a couple of strategies:\r\n\r\nMethod | Uses in Phobos\r\n--------|---------\r\nreturn [Nullable](https://dlang.org/phobos/std_typecons.html#.Nullable) | no precedent in Phobos (?)\r\nuse `enforce` (aka exceptions) | generally disliked, because exceptions allocate (and everybody wants to be `@nogc` nowadays\r\nadd an overload with a `seed` | [`std.algorithm.iteration.maxElement`](https://dlang.org/phobos/std_algorithm_searching.html#.maxElement)\r\n\r\nAs the third way seems to be the current strategy (e.g. `fold`, `reduce`, ...), it creates a lot of \"redundant\" code. Here I propose to add a `seed(<range>, <defaultValue>)` method that can be combined with any range method to solve this problem. The gist is very simple:\r\n\r\n```d\r\nimport std.range : iota;\r\nassert(0.iota(10).seed(42).front == 0);\r\nassert(0.iota.seed(42).front == 42);\r\n```\r\n\r\nThe simplest way to add such a `orElse` method would be to combine `choose` and `only` like this:\r\n\r\n```d\r\nauto orElse(Range, RangeElementType = ElementType!Range)(Range r, RangeElementType fallback)\r\nif (isInputRange!(Unqual!(Range)) &&\r\n    !is(CommonType!(ElementType!Range, RangeElementType) == void))\r\n{\r\n    import std.range : choose, only;\r\n    return choose(!r.empty, r, only(seed));\r\n}\r\n```\r\n\r\nHowever this has a couple of problems:\r\n\r\n- no custom type - e.g. `static if (!hasDefaultValue!Range) enforce(!r.empty)`\r\n- `choose` doesn't work in CTFE ([#14660](https://issues.dlang.org/show_bug.cgi?id=14660))\r\n- not fully `@safe` (it uses `union` and `void[]`)\r\n- doesn't work with ranges of `const` elements\r\n- hasn't all `opSlice` overloads (e.g. `InfiniteRanges`)\r\n- no `toString` for user convenience as that's generic\r\n\r\nWhile most of these points are solvable with e.g. `template mixins`, I am not sure about all of them and hence this PR contains its an implementation of a `OrElseRange`.\r\n\r\nDestroy this idea!\r\n\r\nedit: renamed from `seed` to `orElse`"},"comment":{"url":"https://api.github.com/repos/dlang/phobos/issues/comments/281389652","html_url":"https://github.com/dlang/phobos/pull/5154#issuecomment-281389652","issue_url":"https://api.github.com/repos/dlang/phobos/issues/5154","id":281389652,"user":{"login":"DmitryOlshansky","id":281770,"avatar_url":"https://avatars.githubusercontent.com/u/281770?v=3","gravatar_id":"","url":"https://api.github.com/users/DmitryOlshansky","html_url":"https://github.com/DmitryOlshansky","followers_url":"https://api.github.com/users/DmitryOlshansky/followers","following_url":"https://api.github.com/users/DmitryOlshansky/following{/other_user}","gists_url":"https://api.github.com/users/DmitryOlshansky/gists{/gist_id}","starred_url":"https://api.github.com/users/DmitryOlshansky/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DmitryOlshansky/subscriptions","organizations_url":"https://api.github.com/users/DmitryOlshansky/orgs","repos_url":"https://api.github.com/users/DmitryOlshansky/repos","events_url":"https://api.github.com/users/DmitryOlshansky/events{/privacy}","received_events_url":"https://api.github.com/users/DmitryOlshansky/received_events","type":"User","site_admin":false},"created_at":"2017-02-21T16:08:05Z","updated_at":"2017-02-21T16:08:05Z","body":"> I really like the name orElse!\r\n\r\nShamelessly stolen from Scala Option ;)\r\nNow imagine if we make Nullable follow range interface this all can tick together very nicely."}}
{"actor":{"display_login":"DmitryOlshansky"}}