From 0c31819eba434d932b1fefc8a5e67cdf7ab5c019 Mon Sep 17 00:00:00 2001 From: Nathan Marz Date: Fri, 11 Sep 2015 19:42:30 -0400 Subject: [PATCH] add documentation on late-bound parameterization --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index 4bf48b7..c0bbaf9 100644 --- a/README.md +++ b/README.md @@ -153,6 +153,27 @@ Finally, you can make `select` and `transform` work much faster by precompiling Depending on the details of the selector and the data being transformed, precompiling can sometimes provide more than a 10x speedup. +You can even precompile selectors that require parameters! For example, `keypath` can be used to navigate into a map by any arbitrary key, such as numbers, strings, or your own types. One way to use `keypath` would be to parameterize it at the time you use it, like so: + +```clojure +(defn foo [data k] + (select [(keypath k) ALL odd?] data)) +``` + +Without precompilation this code will execute significantly slower. But it seems like it requires precompilation because the selector path is dependent on an argument to the function. Specter gets around this by allowing you to precompile and bind the parameters to the selector later, like so: + +```clojure +(def foo-path (comp-paths keypath ALL odd?)) +(defn foo [data k] + (compiled-select (foo-path k) data)) +``` + +This code will execute extremely efficiently. + +When `comp-paths` is used on selectors that require parameters, the result of `comp-paths` will require parameters equal to the sum of the number of parameters required by each selector. It expects to receive those parameters in the order in which the selectors were declared. This feature, called "late-bound parameterization", also works on selectors which themselves take in selector paths, such as `selected?`, `filterer`, and `transformed`. + +To learn how to define your own selectors that can take advantage of late-bound parameterization, take a look at how Specter's built-in selectors [are implemented](https://github.com/nathanmarz/specter/blob/0.7.0/src/com/rpl/specter.cljc#L199). + Some more examples: Decrement every value in a map: