score:2
using pattern matching for a simple isempty check is an abuse of pattern matching imho
if you do just want an isempty
check, isempty
/isdefined
is perfectly fine. but in your case you also want to get the value. and using pattern matching for this is not abuse; it's precisely the basic use-case. using get
allows to very easily make errors like forgetting to check isdefined
or making the wrong check:
if(someoption.isempty){
val value = someoption.get
//some lines of code
} else{
//some other lines
}
hopefully testing would catch it, but there's no reason to settle for "hopefully".
combinators (map
and friends) are better than get
for the same reason pattern matching is: they don't allow you to make this kind of mistake. choosing between pattern matching and combinators is a different question. generally combinators are preferred because they are more composable (as yuval's answer explains). if you want to do something covered by a single combinator, i'd generally choose them; if you need a combination like map ... getorelse
, or a fold
with multi-line branches, it depends on the specific case.
score:1
it seems similar to you in case of option
but just consider the case of future
. you will not be able to interact with the future's value after going out of future
monad.
import scala.concurrent.executioncontext.implicits.global
import scala.concurrent.promise
import scala.util.{success, try}
// create a promise which we will complete after sometime
val promise = promise[string]();
// now lets consider the future contained in this promise
val future = promise.future;
val byget = if (!future.value.isempty) {
val valtry = future.value.get
valtry match {
case success(v) => v + " :: added"
case _ => "default :: added"
}
} else "default :: added"
val bymap = future.map(s => s + " :: added")
// promise was completed now
promise.complete(try("promise"))
//now lets print both values
println(byget)
// default :: added
println(bymap)
// success(promise :: added)
score:8
is there any objective advantages, or is it just personal preference?
i think there's a thin line between objective advantages and personal preference. you cannot make one believe there is an absolute truth to either one.
the biggest advantage one gains from using the monadic nature of scala constructs is composition. the ability to chain operations together without having to "worry" about the internal value is powerful, not only with option[t]
, but also working with future[t]
, try[t]
, either[a, b]
and going back and forth between them (also see monad transformers).
let's try and see how using predefined methods on option[t]
can help with control flow. for example, consider a case where you have an option[int]
which you want to multiply only if it's greater than a value, otherwise return -1. in the imperative approach, we get:
val option: option[int] = generateoptionvalue
var res: int = if (option.isdefined) {
val value = option.get
if (value > 40) value * 2 else -1
} else -1
using collections style method on option
, an equivalent would look like:
val result: int = option
.filter(_ > 40)
.map(_ * 2)
.getorelse(-1)
let's now consider a case for composition. let's say we have an operation which might throw an exception. additionaly, this operation may or may not yield a value. if it returns a value, we want to query a database with that value, otherwise, return an empty string.
a look at the imperative approach with a try-catch
block:
var result: string = _
try {
val mayberesult = dangerousmethod()
if (mayberesult.isdefined) {
result = querydatabase(mayberesult.get)
} else result = ""
}
catch {
case nonfatal(e) => result = ""
}
now let's consider using scala.util.try
along with an option[string]
and composing both together:
val result: string = try(dangerousmethod())
.tooption
.flatten
.map(querydatabase)
.getorelse("")
i think this eventually boils down to which one can help you create clear control flow of your operations. getting used to working with option[t].map
rather than option[t].get
will make your code safer.
to wrap up, i don't believe there's a single truth. i do believe that composition can lead to beautiful, readable, side effect deferring safe code and i'm all for it. i think the best way to show other people what you feel is by giving them examples as we just saw, and letting them feel for themselves the power they can leverage with these sets of tools.
Source: stackoverflow.com
Related Query
- What is the advantage of using Option.map over Option.isEmpty and Option.get?
- what is the advantage of ListSet or ListMap over Set and Map in Scala
- In Apache spark, what is the difference between using mapPartitions and combine use of broadcast variable and map
- Why does displaying the kind of Option and Map using :kind work, but not for Function1?
- How to get the first and third word using map function in Spark
- What is the advantage of using $"col" over "col" in spark data frames
- What is the advantage of using abstract classes instead of traits?
- What are the relationships between Any, AnyVal, AnyRef, Object and how do they map when used in Java code?
- What are the pros of using traits over abstract classes?
- In Scala Akka futures, what is the difference between map and flatMap?
- What parts of the Java ecosystem and language should a developer learn to get the most out of Scala?
- What is the proper way to remove elements from a scala mutable map using a predicate
- What is the benefit of using Futures over parallel collections in scala?
- What are the key differences between Java 8's Optional, Scala's Option and Haskell's Maybe?
- What is the advantage of using scala pattern matching instead of java switch case?
- In Scala, what is the difference between using the `_` and using a named identifier?
- Eclipse is using too much memory and what is the best configuration?
- What is the best way to implement a request/response protocol using akka and scala?
- Using Option all over the place feels a bit awkward. Am I doing something wrong?
- What are the performance and maintenance considerations of using Scala's structural types?
- What is the difference between using the return statement and defaulting to return the last value?
- What is the difference between using df.as[T] and df.asInstanceOf[Dataset[T]]?
- What is the actual class (not abstract and not trait) for Map and Set?
- What is the best way to get the last inserted auto-generated ID using slick?
- What does the Scala interpreter (REPL) print exactly (demonstration with Map and HashMap)?
- How to use the traverse TypeClass to accumulate state based on the elements and then map over the state and elements?
- Implementing the map function using only foldRight, foldLeft and unfold in Scala
- I want to separate the back-end and front-end, and make them comunicate using HTTP msgs. What technologies could help me accomplish that?
- What is the advantage of Free monads over plain old traits with IO monads?
- What is the advantage of Option/Maybe Monad over Functor?
More Query from same tag
- configure ant for scala
- Converting Java code to Scala code
- Elementary graphics in java/scala
- Actor-based distributed concurrency libraries for Ocaml and other languages
- Can I use a block when defining a Scala anonymous function?
- I want to separate the back-end and front-end, and make them comunicate using HTTP msgs. What technologies could help me accomplish that?
- In Play Scala Call a controller method from another method
- Different use case for akka cluster aware router & akka cluster sharding?
- Shapeless flatmap HList with Option yielding HList
- Getting UnsupportedClassVersionError while running Scala jar file using spark2-submit in Cloudera VM
- Why are these assignments to java.lang.Exception type safe?
- Validation Only With Play Json
- Scala Standalone WS with Authentication
- How to generate html test report for junit in sbt?
- Return the corresponding integer
- What is best way to wrap blocking Try[T] in Future[T] in Scala?
- Crashed with 'j.l.NullPointerException' when i try to run karate-gatling test reports
- Encoding/Decode shapeless records with circe
- is it possible in scala/Akka to read the .xls file and .xlsx as a chunk?
- How to make a string into another in a column
- Futures Derived From Contents of Collection
- Can views be used with parallel collections?
- Scala Spec2 Mockito: Argument matchers with complex types
- Scala parallel unordered iterator
- union on tables with the different number of columns in scala
- maven cannot create archetype org.fusesource.scalate.tooling:scalate-archetype-jersey
- How to modify the default value for a GenMap in Scala?
- Trimming strings in Scala
- Caused by: java.lang.NoClassDefFoundError: org/sonar/plugins/surefire/api/AbstractSurefireParser
- How to call a scala method from build.gradle file