{"_id":"58f5cac2616bbb1b00d54abc","project":"5612c2a00fbdb60d00e4c7d1","githubsync":"","user":"5612c290c0731b0d00625078","version":{"_id":"5612c2a00fbdb60d00e4c7d4","__v":7,"project":"5612c2a00fbdb60d00e4c7d1","createdAt":"2015-10-05T18:34:08.611Z","releaseDate":"2015-10-05T18:34:08.611Z","categories":["5612c2a10fbdb60d00e4c7d5","58e6b64bc397de1b00173c09","58e6b68eb1eece19008b81fe","58e6b6d185ec873100be9734","58f5e5c2616bbb1b00d54c15","58f5eaa74c413f19007a2858","58f767a79c723f19004e1ca9"],"is_deprecated":false,"is_hidden":false,"is_beta":true,"is_stable":true,"codename":"","version_clean":"0.0.1","version":"0.0.1"},"__v":0,"parentDoc":null,"category":{"_id":"58e6b68eb1eece19008b81fe","project":"5612c2a00fbdb60d00e4c7d1","version":"5612c2a00fbdb60d00e4c7d4","__v":0,"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2017-04-06T21:43:42.570Z","from_sync":false,"order":1,"slug":"api","title":"Lasp"},"updates":[],"next":{"pages":[],"description":""},"createdAt":"2017-04-18T08:13:54.542Z","link_external":false,"link_url":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":6,"body":"We explore the functional operations provided by Lasp.  Each of these functions takes, as input, a single source collection and creates a single output collection.  The output will be maintained as the input is modified, and these operators can be chained arbitrarily.  \n[block:api-header]\n{\n  \"title\": \"Map Operation\"\n}\n[/block]\nFirst, declare a source set.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"> {ok, {SourceId, _, _, _}} = lasp:declare({<<\\\"source\\\">>, state_orset}, state_orset).\\n{ok,{{<<\\\"source\\\">>,state_orset},\\n     state_orset,\\n     [{clock,[{<<170,227,142,126,63,64,19,227,195,66,39,125,58,\\n                 195,75,134,148,109,168,...>>,\\n               1}]}],\\n     {state_orset,[]}}}\",\n      \"language\": \"erlang\"\n    }\n  ]\n}\n[/block]\nThen, declare a destination set.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"> {ok, {DestinationId, _, _, _}} = lasp:declare({<<\\\"destination\\\">>, state_orset}, state_orset).\\n{ok,{{<<\\\"destination\\\">>,state_orset},\\n     state_orset,\\n     [{clock,[{<<170,227,142,126,63,64,19,227,195,66,39,125,58,\\n                 195,75,134,148,109,168,...>>,\\n               1}]}],\\n     {state_orset,[]}}}\",\n      \"language\": \"erlang\"\n    }\n  ]\n}\n[/block]\nLet's map the values from one set into the other, and double the elements.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"> lasp:map(SourceId, fun(X) -> X * 2 end, DestinationId).\\nok\",\n      \"language\": \"erlang\"\n    }\n  ]\n}\n[/block]\nNow, we can add an element to the first set and see the results of the transformation in the destination set!\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"> lasp:update(SourceId, {add, 1}, self()).               \\n{ok,{{<<\\\"source\\\">>,state_orset},\\n     state_orset,\\n     [{clock,[{<<170,227,142,126,63,64,19,227,195,66,39,125,58,\\n                 195,75,134,148,109,168,...>>,\\n               2}]}],\\n     {state_orset,[{1,\\n                    [{<<124,101,224,70,103,26,222,240,141,97,96,128,120,143,\\n                        228,148,...>>,\\n                      true}]}]}}}\\n> lasp:query(DestinationId).\\n{ok,{set,1,16,16,8,80,48,\\n         {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},\\n         {{[],[],[],[],[],[],[2],[],[],[],[],[],[],[],[],[]}}}}\\n> {ok, Result} = lasp:query(DestinationId), sets:to_list(Result).\\n[2]\",\n      \"language\": \"erlang\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"title\": \"Filter Operation\"\n}\n[/block]\nNow, assuming we still have the source set declared from the section above, we can apply a filter directly to it.\n\nFirst, let's declare somewhere to store the results.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"> {ok, {FilteredId, _, _, _}} = lasp:declare({<<\\\"filtered\\\">>, state_orset}, state_orset).      \\n{ok,{{<<\\\"filtered\\\">>,state_orset},\\n     state_orset,\\n     [{clock,[{<<170,227,142,126,63,64,19,227,195,66,39,125,58,\\n                 195,75,134,148,109,168,...>>,\\n               1}]}],\\n     {state_orset,[]}}}\",\n      \"language\": \"erlang\"\n    }\n  ]\n}\n[/block]\nNow, let's apply a filter that only allows even elements through.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"> lasp:filter(SourceId, fun(X) -> X rem 2 == 0 end, FilteredId). \\nok\",\n      \"language\": \"erlang\"\n    }\n  ]\n}\n[/block]\nSince the source set only has `1` in it, the filtered set should be empty!\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"> {ok, Result1} = lasp:query(FilteredId), sets:to_list(Result1).\\n[]\",\n      \"language\": \"erlang\"\n    }\n  ]\n}\n[/block]\nBut, if we add an element to the set that's even, we should see the output in the filtered set.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"> lasp:update(SourceId, {add, 2}, self()).                                    {ok,{{<<\\\"source\\\">>,state_orset},\\n     state_orset,\\n     [{clock,[{<<170,227,142,126,63,64,19,227,195,66,39,125,58,\\n                 195,75,134,148,109,168,...>>,\\n               3}]}],\\n     {state_orset,[{1,\\n                    [{<<124,101,224,70,103,26,222,240,141,97,96,128,120,143,\\n                        228,148,...>>,\\n                      true}]},\\n                   {2,\\n                    [{<<82,188,56,236,83,244,32,79,114,44,4,33,148,226,184,...>>,\\n                      true}]}]}}}\\n                                                                                  \\n> {ok, Result2} = lasp:query(FilteredId), sets:to_list(Result2).\\n[2]                                                                                \",\n      \"language\": \"erlang\"\n    }\n  ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"warning\",\n  \"title\": \"Fold Operation\",\n  \"body\": \"We avoid discussion of the fold operation here, as it's currently being revised and the interface i the prototype is less than desirable at the current moment.\"\n}\n[/block]","excerpt":"How you can transform, combine and operate with sets in a functional way.","slug":"functional-combinators","type":"basic","title":"Functional Operations"}

Functional Operations

How you can transform, combine and operate with sets in a functional way.

We explore the functional operations provided by Lasp. Each of these functions takes, as input, a single source collection and creates a single output collection. The output will be maintained as the input is modified, and these operators can be chained arbitrarily. [block:api-header] { "title": "Map Operation" } [/block] First, declare a source set. [block:code] { "codes": [ { "code": "> {ok, {SourceId, _, _, _}} = lasp:declare({<<\"source\">>, state_orset}, state_orset).\n{ok,{{<<\"source\">>,state_orset},\n state_orset,\n [{clock,[{<<170,227,142,126,63,64,19,227,195,66,39,125,58,\n 195,75,134,148,109,168,...>>,\n 1}]}],\n {state_orset,[]}}}", "language": "erlang" } ] } [/block] Then, declare a destination set. [block:code] { "codes": [ { "code": "> {ok, {DestinationId, _, _, _}} = lasp:declare({<<\"destination\">>, state_orset}, state_orset).\n{ok,{{<<\"destination\">>,state_orset},\n state_orset,\n [{clock,[{<<170,227,142,126,63,64,19,227,195,66,39,125,58,\n 195,75,134,148,109,168,...>>,\n 1}]}],\n {state_orset,[]}}}", "language": "erlang" } ] } [/block] Let's map the values from one set into the other, and double the elements. [block:code] { "codes": [ { "code": "> lasp:map(SourceId, fun(X) -> X * 2 end, DestinationId).\nok", "language": "erlang" } ] } [/block] Now, we can add an element to the first set and see the results of the transformation in the destination set! [block:code] { "codes": [ { "code": "> lasp:update(SourceId, {add, 1}, self()). \n{ok,{{<<\"source\">>,state_orset},\n state_orset,\n [{clock,[{<<170,227,142,126,63,64,19,227,195,66,39,125,58,\n 195,75,134,148,109,168,...>>,\n 2}]}],\n {state_orset,[{1,\n [{<<124,101,224,70,103,26,222,240,141,97,96,128,120,143,\n 228,148,...>>,\n true}]}]}}}\n> lasp:query(DestinationId).\n{ok,{set,1,16,16,8,80,48,\n {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},\n {{[],[],[],[],[],[],[2],[],[],[],[],[],[],[],[],[]}}}}\n> {ok, Result} = lasp:query(DestinationId), sets:to_list(Result).\n[2]", "language": "erlang" } ] } [/block] [block:api-header] { "title": "Filter Operation" } [/block] Now, assuming we still have the source set declared from the section above, we can apply a filter directly to it. First, let's declare somewhere to store the results. [block:code] { "codes": [ { "code": "> {ok, {FilteredId, _, _, _}} = lasp:declare({<<\"filtered\">>, state_orset}, state_orset). \n{ok,{{<<\"filtered\">>,state_orset},\n state_orset,\n [{clock,[{<<170,227,142,126,63,64,19,227,195,66,39,125,58,\n 195,75,134,148,109,168,...>>,\n 1}]}],\n {state_orset,[]}}}", "language": "erlang" } ] } [/block] Now, let's apply a filter that only allows even elements through. [block:code] { "codes": [ { "code": "> lasp:filter(SourceId, fun(X) -> X rem 2 == 0 end, FilteredId). \nok", "language": "erlang" } ] } [/block] Since the source set only has `1` in it, the filtered set should be empty! [block:code] { "codes": [ { "code": "> {ok, Result1} = lasp:query(FilteredId), sets:to_list(Result1).\n[]", "language": "erlang" } ] } [/block] But, if we add an element to the set that's even, we should see the output in the filtered set. [block:code] { "codes": [ { "code": "> lasp:update(SourceId, {add, 2}, self()). {ok,{{<<\"source\">>,state_orset},\n state_orset,\n [{clock,[{<<170,227,142,126,63,64,19,227,195,66,39,125,58,\n 195,75,134,148,109,168,...>>,\n 3}]}],\n {state_orset,[{1,\n [{<<124,101,224,70,103,26,222,240,141,97,96,128,120,143,\n 228,148,...>>,\n true}]},\n {2,\n [{<<82,188,56,236,83,244,32,79,114,44,4,33,148,226,184,...>>,\n true}]}]}}}\n \n> {ok, Result2} = lasp:query(FilteredId), sets:to_list(Result2).\n[2] ", "language": "erlang" } ] } [/block] [block:callout] { "type": "warning", "title": "Fold Operation", "body": "We avoid discussion of the fold operation here, as it's currently being revised and the interface i the prototype is less than desirable at the current moment." } [/block]