Bluespec to Open Source Its Hardware Description Language
bluespec.com2 pointsby chas0 comments
let (Sum total_size) = foldMap (\x -> Sum (size x)) xs
Check if any size is greater than 5: let (Any over_threshold) = foldMap (\x -> Any ((size x) > 5)) xs
Do both in one pass: let (Sum total_size, Any over_threshold) = foldMap (\x -> (Sum (size x), Any ((size x) > 5))) xs
Get the first entry with a size greater than 5: let (First over_threshold) = foldMap (\x -> First (if (size x) > 5 then Just x else Nothing)) xs
Get all entries with a size greater than 5: let over_threshold = foldMap (\x -> if (size x) > 5 then [x] else []) xs
Since all of these operations are associative, we can completely change the data structure or run the operations in parallel or concurrently and the code will still behave exactly the same. These nice properties mean that when I'm thinking about these sorts of tasks in any language, I think about what monoid or semigroup captures a given operation, rather than any of the mechanics of writing the loop. I find clarifies my thinking a lot. def sum(xs):
if xs == []:
return 0
else:
x = xs.pop(0)
return x + sum(xs)
This sort of reduction operation is very broadly useful, so it has been abstracted in frameworks like MapReduce as well as library functions like functools.reduce (https://docs.python.org/3/library/functools.html#functools.r...). Recursion schemes build on explicit reduce functions by being strongly typed (which, in addition to reducing bugs, enables a something like a super-powered visitor pattern), very orthogonal (which reduce redundancy and code duplication as a user of the abstraction), and very general (which let you solve a lot of problems with the same small set of programming tools without needing to remember special cases). In particular, the way that they look at data structures lets you interleave the recursion across nested data structures in a way that would be a huge pain in the butt with e.g. Python's __iter__ interface. There are some other nifty things that the approach brings to the table as well, but I think those are the major wins from the perspective of someone not already interested in strongly-typed functional programming.
[ my public key: https://keybase.io/chas; my proof: https://keybase.io/chas/sigs/3e4ZitlD0tm8a9ZVzI7rkK5G03snHd2qvx2ABwqOtHI ]