Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/davidgtonge/query-predicate
Generates predicate functions from Mongo queries
https://github.com/davidgtonge/query-predicate
Last synced: 9 days ago
JSON representation
Generates predicate functions from Mongo queries
- Host: GitHub
- URL: https://github.com/davidgtonge/query-predicate
- Owner: davidgtonge
- License: mit
- Created: 2016-04-16T17:52:16.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2022-11-10T20:22:04.000Z (about 2 years ago)
- Last Synced: 2024-08-09T12:20:23.505Z (3 months ago)
- Language: JavaScript
- Size: 271 KB
- Stars: 4
- Watchers: 5
- Forks: 0
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
Query-Predicate
================Re-write of underscore-query using ES6 and Ramda in an (extreme) point-free style.
This module exports a single `createPredicate` function. This function takes
a mongo-like query and returns a predicate function. This function can then be
used with `R.filter` or `R.find`, etc.The module parses a wide variety of mongo queries - please see the tests for
examples.Documentation will be added shortly, but in the meantime check the Documentation
for the query operators for [underscore-query](https://github.com/davidgtonge/underscore-query/blob/master/README.md)### Why Point Free
This is an experiment in how much of a non-trivial program can be written in a
point-free manner. I wrote it partly to explore the `ramda` api and partly
as a challenge.Currently there are only 4 function declarations.
- 3 are needed to allow recursion. While I probably could re-write the
functions to use a y-combinator, I've not yet got round to it. The place that
the recursion is used would make those particular functions a lot harder to
reason about
- 1 is needed to throw errorsI think when used well by people who are familiar with functional apis (such as
Ramda), the style is very expressive. At a simple level a procedural for loop
could be used for `map` or `filter` or `reduce`. By using `map` rather than
a for loop, the intent of my program is easier to understand.Here is an example of the journey from procedural to point free
#### Simple Procedural
```
function fn(input) {
var output = []
for (i = 0; i < input.length; i++) {
output.push(input[i].key)
}
return output
}
```#### Using Native Map
```
function fn(input) {
return input.map(function(item) {
return item.key
})
}
```#### Using FP Style Map
```
function fn(input){
return map(function(item) {
return item.key
}, input)
}
```#### Making Point free - part 1 (i.e. no arguments)
This works
```
var fn = R.map(function(item) {
return item.key
})
```#### Making Point free - part 2 - Using R.prop
```
var fn = R.map(R.prop("key"))
```#### Using R.pluck
```
var fn = R.pluck("key")
```### Where doesn't it work
Some functions become a lot more verbose and less clear. For example:
```
function $mod(value, attr){
return attr % value[0] === value[1]
}```
becomes:```
const $mod = R.converge(R.identical, [
R.converge(R.modulo, [R.nthArg(1), R.compose(R.head, R.nthArg(0))]),
R.compose(R.last, R.nthArg(0))
])
```