Create gen/let for syntax sugar and to address fmap/bind confusion
Description
Problem Statement
fmap/bind confusion
Users who are not big fans of monads may find the names of and distinction between fmap and bind to be confusing. A combination of the two can exist, where users can return either a value or a generator and the system chooses to use fmap or bind automatically. The downside of this approach is it is ambiguous (i.e., a user cannot use it to generate a generator, though this is admittedly uncommon), and it offends people who like thinking about the precise types of functions (see this criticism in particular regarding a similar behavior in jQuery). However, neither of these are very serious restrictions, since falling back to fmap and bind is always an option.
syntax sugar
Writing complex generators can be very syntactically convoluted, with heavy nesting and confusing structure especially caused by the opposite argument order of fmap and bind. In the same way that clojure.core/let provides a flatter (especially when multiple clauses are present) syntax for something that can technically be accomplished using fn, a macro could flatten the syntax of generators that make a lot of use of bind and fmap while providing the same functionality.
Prior Art
This feature supposedly exists in the erlang quickcheck.
Another attempt at solving the same problem is test.chuck's for macro.
Proposal
A macro in the generators namespace called let, which uses bind for multiple clauses, and whose body is processed with bind or fmap depending on whether it is a generator.
Examples:
Feature Comparison
gen/let and test.chuck's for differ in a couple independent ways, so it might be helpful to be explicit about what the different options are here. I also included Erlang's let, based on how I imagine it works.
Feature | Erlang's let | gen/let | test.chuck/for |
---|---|---|---|
Multiple clauses | ✓ | ✓ | |
Subsequent clauses handled with bind | N/A | ✓ | ✓ |
Body uses bind if it's a generator | ✓ | ✓ | |
Supports filtering | ✓ | ||
Supports binding intermediate values | ✓ | ||
Supports parallel generators (via tuple) | ✓ |
Environment
Activity
Added gen/let on master
Assignee
Reporter
Labels
Approval
Patch
Priority
