assert-rs / predicates-rs

Boolean-valued predicate functions in Rust
docs.rs/predicates
Apache License 2.0
171 stars 29 forks source link

Internal DSL for Predicates? #19

Open epage opened 6 years ago

epage commented 6 years ago

iirc Rust's logical operators force a return type, preventing using them in a DSL (pred && pred).

What about the bitwise operators (pred & pred)? Should this be done to make the API "more ergonomic"?

What about not-ing? And if our choice in operator for not-ing is at a weird precedence level compare to the others, which should we prefer?

nastevens commented 6 years ago

Yeah unfortunately pred && pred isn't possible because it requires a bool be returned immediately. Currently && doesn't appear to be overloadable. I came from C++ where operator overloading got grossly misused, so I don't really like the idea of "close enough" operators. & is not the same as && in my mind, so I would be opposed to using it to desugar to and().

not()/! on the other hand could be really useful because the ordering is currently weird. Whereas pred1.and(pred2) and pred1 && pred2 read in the same order, pred1.and(pred2.not()) introduces the weird trailing not(). The sugared version pred1.and(!pred2) reads so much nicer and just feels natural.

epage commented 6 years ago

Not seeing a good way to provide a single implementation of Not. Instead we need to provide an implementation per predicate. Probably best to wait for #18 to get in.

I assume a not function should still exist in some form. We could keep the existing one but I worry about weird corner cases of the Not trait being in scope causing compiler errors for our users. That leaves just moving not to be predicate::not or finding an alternative name.

luser commented 6 years ago

I was going to open an issue about not, but sounds like you've already got ideas there. Having it as a method on a predicate makes them very awkward to read. It'd be way nicer to be able to say predicate::not(...).

asomers commented 5 years ago

It would be easy to do this with a proc macro. You could write something like this:

pred!{predicate::gt(5) && predicate::lt(10)}

However, it would require the proc_macro_hygiene feature, which is not yet stable.

matthiasbeyer commented 2 years ago

When I clicked on this issue I thought this was about having a parser for a DSL that can be parsed into a Predicate. So that a user can specify some predicate "less_than(5).and(greater_than(0))" in, for example, a configuration file, and the software can then parse this into a BoxPredicate (for example) and apply it to some stream of data. Just as an example.

Or does such a thing already exist somewhere and I just missed it?

epage commented 2 years ago

I've clarified the title to be about an internal dsl. I am not aware of an external dsl.