3 ms·
Map and filter are extremely simple, far simpler than a for-loop. They can only do two things: transform items in a collection, and remove items from a collecti
by jolux 5y ago
Map and filter are extremely simple, far simpler than a for-loop. They can only do two things: transform items in a collection, and remove items from a collection. After mapping you know for sure that a collection will still have the same number of elements. After filtering you know that all the elements remaining still have the same type. For-loops can do anything. It’s a question of what you’re most familiar with and used to.
- throwaway894345 5y agoI’m not comparing for loops in general with map or filter, but rather the specific for loop boilerplate to implement map and filter. Moreover, the complexity of map/filter isn’t internal, but rather decomposing or breaking down one’s problem into map/filter/etc expressions. Often for loops are clearer, especially since you can frequently collapse a map and filter into a single for loop without thinking in map/filter/etc primitives. This is especially true when you need to abort the chain early (e.g., due to errors)—Rust’s FromIterator provides a clever solution to this problem, but it’s much harder to wrap one’s head around than a simple for loop with an early return branch.
- jolux 5y agoI find that decomposing iteration into map and filter expressions typically clarifies my understanding of the problem and makes the resulting code more general too, and I just disagree that for-loops are clearer. Combining a map and filter into one loop body tends to create specific, imperative code that doesn’t need to be specific or imperative. For one, loops require mutation to have the same effect as filter and map, and as soon as you’re maintaining state, things get confusing. My usage of higher order functions instead of for-loops is an expression of my belief that programmers should always use the least powerful construct they can to solve a problem. In general though I think the functions used in map and filter should be total. Most languages are not expressive enough to handle errors fluidly in long chains like that, you can do it with monads but apparently everyone hates those except me.
- throwaway894345 5y ago> I find that decomposing iteration into map and filter expressions typically clarifies my understanding of the problem and makes the resulting code more general too, and I just disagree that for-loops are clearer. Agree to disagree I guess. > Combining a map and filter into one loop body tends to create specific, imperative code that doesn’t need to be specific or imperative. For one, loops require mutation to have the same effect as filter and map, and as soon as you’re maintaining state, things get confusing. I agree that immutable, declarative code is easier to reason about in general than mutable, imperative code, but it's not a binary proposition. I posit the cost of managing the tiny bit of very-local mutable state for a for loop is a lower cost than trying to model a problem in terms of map and filter. While I can appreciate the elegance in "immutable always", I think it's too puritanical for real world software development, especially in these cases which are simply expressed as for loops. Note that languages like Python have strong support for immutable expressions and `for` loops, and it seems very common (even idiomatic) to use imperative `for` loops for anything more complicated than the simplest list comprehensions. > In general though I think the functions used in map and filter should be total. Most languages are not expressive enough to handle errors fluidly in long chains like that, you can do it with monads but apparently everyone hates those except me. I think it's just that monads tend to allow for very abstract code at the expense of understandability, and the abstraction that monads facilitate is often well in excess of what a given problem requires. If you're writing code to maximize abstraction (which is a lot of fun), monads (and map/filter/etc) are great, but if you're trying to work with a team to build software to solve real problems, you probably care a lot more about readability than gratuitous abstraction and the monad (/map/filter/reduce/etc) juice frequently isn't worth the squeeze.
- jolux 5y agoPython’s FP capabilities are severely constrained by not supporting multi-line lambdas or composition operators (pipe, sequence, etc). It is not a good language for functional programming at all. The community norms explicitly push you away from using FP in it because of how limited it is. We use it for wrangling large data sets and tend to hate every minute of it. My workplace uses Elixir exclusively in production for our backend services, so we’re all functional programmers and we do not find that map, filter, and reduce make things harder to read, quite the opposite. Breaking up loops does not introduce cognitive overhead, it makes every step in the chain more explicit. You can call this personal preference but there’s nothing concrete in your belief that for-loops are more readable or easier for teams of programmers to maintain, many people disagree.