{"action":"created","issue":{"url":"https://api.github.com/repos/lspector/Clojush/issues/147","labels_url":"https://api.github.com/repos/lspector/Clojush/issues/147/labels{/name}","comments_url":"https://api.github.com/repos/lspector/Clojush/issues/147/comments","events_url":"https://api.github.com/repos/lspector/Clojush/issues/147/events","html_url":"https://github.com/lspector/Clojush/issues/147","id":94837671,"number":147,"title":"Add Higher-Order Function Instructions","user":{"login":"thelmuth","id":197060,"avatar_url":"https://avatars.githubusercontent.com/u/197060?v=3","gravatar_id":"","url":"https://api.github.com/users/thelmuth","html_url":"https://github.com/thelmuth","followers_url":"https://api.github.com/users/thelmuth/followers","following_url":"https://api.github.com/users/thelmuth/following{/other_user}","gists_url":"https://api.github.com/users/thelmuth/gists{/gist_id}","starred_url":"https://api.github.com/users/thelmuth/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/thelmuth/subscriptions","organizations_url":"https://api.github.com/users/thelmuth/orgs","repos_url":"https://api.github.com/users/thelmuth/repos","events_url":"https://api.github.com/users/thelmuth/events{/privacy}","received_events_url":"https://api.github.com/users/thelmuth/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":7,"created_at":"2015-07-13T23:57:40Z","updated_at":"2015-07-14T11:39:34Z","closed_at":null,"body":"It would be cool to have higher-order function instructions like map, reduce, and filter in Clojush. Maybe they'd only be defined on the array-like types (string, vector_integer, vector_boolean, etc.), or maybe they'd somehow be defined on other stacks as well.\r\n\r\nThe details are vague, and there are some non-trivial things to figure out, but if anyone wants to take this on it would be cool!"},"comment":{"url":"https://api.github.com/repos/lspector/Clojush/issues/comments/121211226","html_url":"https://github.com/lspector/Clojush/issues/147#issuecomment-121211226","issue_url":"https://api.github.com/repos/lspector/Clojush/issues/147","id":121211226,"user":{"login":"Vaguery","id":81171,"avatar_url":"https://avatars.githubusercontent.com/u/81171?v=3","gravatar_id":"","url":"https://api.github.com/users/Vaguery","html_url":"https://github.com/Vaguery","followers_url":"https://api.github.com/users/Vaguery/followers","following_url":"https://api.github.com/users/Vaguery/following{/other_user}","gists_url":"https://api.github.com/users/Vaguery/gists{/gist_id}","starred_url":"https://api.github.com/users/Vaguery/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Vaguery/subscriptions","organizations_url":"https://api.github.com/users/Vaguery/orgs","repos_url":"https://api.github.com/users/Vaguery/repos","events_url":"https://api.github.com/users/Vaguery/events{/privacy}","received_events_url":"https://api.github.com/users/Vaguery/received_events","type":"User","site_admin":false},"created_at":"2015-07-14T11:39:34Z","updated_at":"2015-07-14T11:39:34Z","body":"My idea right now is to bring over something like the `:enumerator` type I built in one of the other languages. It is a direct extension of the forms you are used to with `exec_do_etc` and `code_do`etc`, and so it's completely reentrant and iterative in the same way.\r\n\r\nBriefly: am `enumerator` contains one immutable sequence (I will start with `vectors` here) and an associated persistent \"pointer state\". As with `code` there is no need that the sequence be single-typed, and one `enumerator` may contain a `vector_integer` and another a `vector_string` or a `string` item.\r\n\r\nWhen created, the `enumerator`'s pointer is set to `0`.\r\n\r\nA standard library of pull the top `enumerator` from that stack and push the following to `exec`:\r\n- `enumerator_first` produces \r\n  - the `enumerator`, with its pointer set to 0\r\n  - a copy of the item at position 0 in the `enumerator`\r\n- `enumerator_last` produces \r\n  - the `enumerator`, with its pointer set to the last index\r\n  - a copy of the item at position -1 in the `enumerator`\r\n- `enumerator_forward` produces \r\n  - the `enumerator`, with its pointer incremented by 1; if the pointer exceeds the length of the sequence, the `enumerator` is consumed without output\r\n- `enumerator_back` produces \r\n  - the `enumerator`, with its pointer reduced by 1; if the counter was already 0, the `enumerator` is consumed without output\r\n- `enumerator_next` produces \r\n  - the `enumerator`, with its pointer incremented by 1; if the pointer exceeds the length of the sequence, the `enumerator` is consumed without output\r\n  - a copy of the item in the sequence at the new position\r\n- `enumerator_prev` produces \r\n  - the `enumerator`, with its counter reduced by 1; if the counter was already 0, the `enumerator` is consumed without output\r\n  - a copy of the item in the sequence at the new position\r\n- `enumerator_history` produces \r\n  - the `enumerator`\r\n  - a sequence (of the same type as its internal sequence) containing all the items from positions 0 to the pointer \r\n- `enumerator_remaining` produces \r\n  - the `enumerator`\r\n  - a sequence (of the same type as its internal sequence) containing all the items from just after the pointer to the end\r\n- `enumerator_apply` produces (with a `code` argument)\r\n  - the `enumerator`\r\n  - `code_quote`\r\n  - the `code` item\r\n  - a copy of the item at the pointer position\r\n  - the `code` item\r\n- `enumerator_map` produces (with a `code` argument)\r\n  - the `enumerator`, with the pointer advanced\r\n  - `code_quote`\r\n  - the `code` item\r\n  - a copy of the item at the pointer position\r\n  - the `code` item\r\n- `enumerator_moveto` produces (with an `integer` argument)\r\n  - the `enumerator`, with the pointer set to the absolute position indicated by the `int` modulo the sequence length\r\n- `enumerator_move` produces (with an `integer` argument)\r\n  - the `enumerator`, with the pointer moved relative by a number of steps determined by the `int`; if the pointer leaves the sequence from either end, the `enumerator` disappears.\r\n- `enumerator_pos` produces\r\n  - the `enumerator`\r\n  - the pointer value as an `integer`\r\n- `enumerator_break` produces\r\n  - the sequence\r\n  - the pointer value as an `integer`\r\n- `[sequence]_to_enumerator` creates a new `enumerator` from the indicated sequence\r\n- the usual suspects: `enumerator_dup`, `enumerator_pop` and so forth\r\n\r\nNote: in most of the implementations I've worked on where the goal was _extending_ Push, I did _not_ want anything reaching into the associated sequence and changing it. In `duck` things are more _fluid_, and as I recall the stack-affecting messages like `:dup` and `:pop` can be received by an `Enumerator` instance as well, so all kinds of madness happens.\r\n\r\nAnyway, @lspector, there is no more than one additional copy of the sequence ever, and so I think the computational implications of this approach are in keeping with the Push philosophy at least as much as `code_do_times` and so forth are."}}