Reputation: 198188
Scala code:
for {
user <- users
name <- user.names
letter <- name.letters
} yield letter
Can we consider such "list comprehension" code as "functional programming" style? Since they will be converted to map
and flatMap
functions?
Upvotes: 2
Views: 1121
Reputation: 36491
Yes, it's definitely a functional technique, particularly assuming that all of those members are fields or pure functions. It's just syntactic sugar for 0 or more flatMap
s followed by 1 map
(with if
clauses translated to withFilter
).
Without the yield
at the end, it acts more like the imperative for
, translating to 1 or more foreach
s; foreach
typically being used for executing statements for their side effects.
This article describes the syntax in a bit more detail, this excellent answer talks about it in more depth with some of the monadic theory, and this article describes the actual rules translation explicitly.
Upvotes: 3
Reputation: 137937
Can we consider such "list comprehension" code as "functional programming" style?
Monadic list comprehensions with imperative/generator syntax are a relatively new syntactic and semantic innovation.
The original list comprehensions (e.g. NPL or Miranda) were modelled on set comprehensions, and are clearly a declarative construct, albeit one that is translated to nested functions.
Haskell's list comprehensions function in a similar way.
Monadic comprehensions (compiled into monadic guard and binds) should surely be considered functional if we consider monads to be a functional construct.
Upvotes: 0
Reputation: 6237
The list comprehension construct is found quite often in functional programming languages but it is not distinctive of functional programming. If you think about that also Python, PHP (from version 5.5) and the next version of Javascript (ES6) have similar constructs but that doesn't mean that they are functional.
In the case of scala it is true that your example translate to map and flatMap applications but neither that is enough IMHO to say that it is functional. Consider the case:
for {
i <- 1 until 10
} println(i)
This is still a for comprehension but it is actually doing side-effects as any imperative language (this cycle actually translates to a foreach
invocation).
The bottom-line in my opinion is that Functional Programming is not much about constructs as it is about about style: the real important thing for a piece of code to be in FP style is to be side-effect free (or, as in many cases, to be honest about when side-effects happen).
If you want you can do FP even in Java 7: use anonymous classes as closures, mark everything as final, avoid any mutable state and isolate side-effects into special constructs and you are done. It will be terribly verbose and probably ugly because the language doesn't support the kind of abstractions that help in making this style nice in practice, but it will nevertheless be in functional-style.
Upvotes: 1