-
-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: Should we import-gate flatMap? #110
Comments
To clarify what kind of comments I'm hoping for:
Also to clarify the proposal on a technical level:
|
I'm in favor of hiding it behind an import statement for exactly the reasons mentioned in the above (my) discord quote. And also because of what @raquo said:
Also, I did a quick check and went through some of my projects. For the one mentioned on discord I already noticed that 90% of the flatMaps were not needed. I also checked two other projects. In one of them, ~~80% percent of flatMaps were wrong, in the other about ~~70%. I also noticed that flatMaps (and of course for-comprehensions) were much less frequent than I thought. Needing an import would not affect most of the files even in the scalajs section of the projects. Also, one of those projects is already in production and is used by quite a few people. Which highlights one of my fears: It mostly works. But you sometimes get messages from people saying something didn't work when they used it. And often, it has nothing to do with the software, like they are using a browser from 2010 or have some weird security restrictions on their network or something. But some of them might have stumbled upon a real bug in our code caused by using flatMaps where they should not be used. For example, I have found code like this: for {
value <- node.map(_.head.value)
spec <- node.map(_.head.spec.data)
result <- zipperFromSpec(spec) match {
case None => invalidSpec
case Some(zipper) => doStage(value, spec, zipper, open.signal, commandBus.writer)
}
} yield result this worries me. This seems like it would work like 99% of the time but could sometimes lead to an odd glitch which makes Summary
|
A couple of random thoughts:
Gating those could be an "easy" decision? Random idea: we could import-gate the In akka streams they use Maybe we even deprecate (and then remove) (this will probably also help prevent incorrect for-comps) |
Good idea to rename |
I used I really like yurique's idea. It is more explicit, allows for smooth migration and prevents the for-comp usage. |
Just like phfroidmont, I used
and I encountered diamond glitch case while coming up with that. I do think we should rename |
Aight, this is what I implemented so far:
|
With Airstream observables,
flatMap
has very predictable behaviour when used as intended, but can cause unexpected behaviour when it's incorrectly used as a replacement forcombineWith
. (See https://github.com/raquo/Airstream/#flattening-observables). The problem only occurs when you run into FRP glitches – basically if your flatMap's inner and outer observables "emit at the same time" (have a mutual and synchronous dependency). Which on one hand is good because the scope of the problem is limited, but on the other hand is bad because you can get used to incorrectly usingflatMap
with no issues until suddenly flatMap just does not seem to work right in one case, and if you don't know better, that feels like a bug.It's also worth noting that Scala's for-comprehensions syntax uses
flatMap
behind the scenes, so users might even be using theflatMap
operator without thinking about it. (For this reason, you should not use Scala's for-comprehensions with Airstream observables, they will likely produce undesired output)As suggested on Discord:
Laminar already import-gates
: => Unit
sinks because it can be dangerous if used accidentally. Basically, if you try to use that feature, you'll get a compilation error with a text suggesting you read the section of documentation linked above, which tells you to import a special implicit value to allow such syntax.However,
flatMap
is an established feature (unit sinks were import-gated as soon as they were added), and also probably a more popular feature than unit arrows (even discarding incorrect uses of flatMap), so import-gating it might cause more annoyance than it's worth.On the other hand, preventing users from getting into predictable WTF situations is pretty high on my list of design goals for Laminar & Airstream, so I need to consider various solutions for this. I do like relying on
implicitNotFound
messages (similar to unit sinks) because they tell you exactly what you need to know, and you can "dismiss" the error with a single import, which can be easily done either as-needed with one keystroke (in IntelliJ at least), or automatically as part of the Scala file template in the IDE.One could say that this issue just needs better documentation instead, but it's already explained in the very first paragraph in the "flattening observables" documentation section linked above, and I think the reason this is not enough is because people generally don't expect to need documentation just to use
flatMap
, so they don't look it up prior to use, so I'm not sure that more documentation would actually help.Thoughts and comments are welcome!
The text was updated successfully, but these errors were encountered: