Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I've done the same by being lazy, mainly treating it as a better Java and only learning new stuff when necessary or obviously beneficial. I want to write good programs, not fancy code.

My advice:

- Options, immutability, pattern matching, and list comprehensions are all awesome and better than the default Javaesque way

- Scala concurrency abstractions all better than Java, but concurrency is still hard. Proceed with caution

-- Except parallel collections. Use those liberally

- No Scalaz or any other FP-crusader stuff ever

- Macros and implicits should be rejected by default in code review. Amazing justifications required

- Enforce coding rules with linters. This applies for any language, but especially important for dynamic and non-straightjacket languages



OK, here's my question then. You're embracing Option type and yet presumably avoiding monads, applicatives, and functors (avoiding "FP-crusader stuff"), right?

So what happens when you are dealing with multiple option types, like you two optional ints you need to add together? Or you have an optional field in an optional object? This happens all the time in code that heavily uses Option types.

So do you match on every one, and nest match expressions inside match expressions inside match expressions? That can get very, very messy and even confusing.


For comprehensions should alleviate the examples you have given with regards to readability.

Although yes there are other more complex instances in which nested matches might come up. Generally I would think to handle them by creating a function that contains the next layer of matching instead of trying to come up with an uber function. Adds a bit more verbosity perhaps but I find it is fairly easy to follow and show intent.


My question was poorly phrased, since if you're using Option types, you're obviously already using monads, applicatives, and functors.

What I should have asked was: if you're using monads such as Option, then how do you use them effectively without using integral tools such as flatMap?

And you've answered: you can use for comprehensions. I primarily have used Haskell and OCaml, so I sometimes forget about Scala's very nice for comprehensions, which I agree is a great solution. But note that for comprehensions are just syntactic sugar for `flatMap`.

I agree that if you do use Option types in Scala, for comprehensions are a very elegant way to interact with them.

But I'll end with a question. If you're already using option types with for comprehensions, why not also throw in other useful monads like bifunctor IO, which is a great way to deal with async code? I understand the dislike for the tendency in the FP Scala community to use custom sigils, but I do think most people who are using options and for comprehensions would also be comfortable and happy using other useful monads with for comprehensions.


> but I do think most people who are using options and for comprehensions would also be comfortable and happy using other useful monads with for comprehensions.

You seem to vastly underestimate the gap there is between using a for comprehension and understanding what a bifunctor is.

Nothing wrong with that: once you gain a certain advanced knowledge, it's often very hard to put yourself in the shoes of someone who hasn't gained that knowledge, and even harder to explain it to them in terms that they will understand.

Which is why we have so many unhelpful monad tutorials.


> concurrency is still hard. Proceed with caution

> No Scalaz or any other FP-crusader stuff ever

That stuff which some people might consider FP-crusader vanity is something which can make concurrency manageable, maybe even joy.

I encourage you to open your mind, at least for a bit, and have a look at ZIO or Monix.

> Enforce coding rules with linters

Absolutely! Scalafmt and Scalafix for the win!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: