- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Why is there no implicit any2Option?
Fri, 2009-12-11, 06:43
I just defined a case class with 6 attributes, 4 of which are optional.
case class Link(
val href: URI,
val rel: String,
val mediaType: Option[String] = None,
val title: Option[String] = None,
val hreflang: Option[String] = None,
val length: Option[Long] = None
)
I occurred to me that creating one of these things could be
considerably easier if you could use
Link(myUri, "alternate", "application/json", "Cool data", "en", "5000")
rather than the much lengthier
Link(myUri, "alternate", Some("application/json"), Some("Cool
data"), Some("en"), Some(5000))
I'm also of the opinion that the Some()s in the second case don't add
much to the readability of the code, though others will probably
disagree - and I'm happy to be convinced otherwise as well :)
So, why is there no implicit any2Option?
Thanks,
Rich
Sat, 2009-12-12, 22:07
#2
Re: Why is there no implicit any2Option?
I actually agree, it seems like adding :
implicit def any2Some[T](v : T): Option[T] = Some(v)
to Predef
would make things less verbose.. I wonder why it isn't there,
are there any side effects that I am not forseeing ?
Cheers
On Fri, Dec 11, 2009 at 12:42 AM, Richard Wallace <rwallace@thewallacepack.net> wrote:
I just defined a case class with 6 attributes, 4 of which are optional.
case class Link(
val href: URI,
val rel: String,
val mediaType: Option[String] = None,
val title: Option[String] = None,
val hreflang: Option[String] = None,
val length: Option[Long] = None
)
I occurred to me that creating one of these things could be
considerably easier if you could use
Link(myUri, "alternate", "application/json", "Cool data", "en", "5000")
rather than the much lengthier
Link(myUri, "alternate", Some("application/json"), Some("Cool
data"), Some("en"), Some(5000))
I'm also of the opinion that the Some()s in the second case don't add
much to the readability of the code, though others will probably
disagree - and I'm happy to be convinced otherwise as well :)
So, why is there no implicit any2Option?
Thanks,
Rich
Sat, 2009-12-12, 22:17
#3
Re: Why is there no implicit any2Option?
2009/12/12 Maxime Lévesque <maxime.levesque@gmail.com>
I actually agree, it seems like adding :
implicit def any2Some[T](v : T): Option[T] = Some(v)
to Predef
One catch though, how should null behave?As specified, you'd end up with Some(null) and thus regain all the risks of NPEs
You could also translate null to None, but this is also fraught with risk as there are some scenarios when Some(null) as a perfectly acceptable value.
The definition is short enough that you can just decide on a case-by-case basis and easily implement it in your own code.
would make things less verbose.. I wonder why it isn't there,
are there any side effects that I am not forseeing ?
Cheers
On Fri, Dec 11, 2009 at 12:42 AM, Richard Wallace <rwallace@thewallacepack.net> wrote:
I just defined a case class with 6 attributes, 4 of which are optional.
case class Link(
val href: URI,
val rel: String,
val mediaType: Option[String] = None,
val title: Option[String] = None,
val hreflang: Option[String] = None,
val length: Option[Long] = None
)
I occurred to me that creating one of these things could be
considerably easier if you could use
Link(myUri, "alternate", "application/json", "Cool data", "en", "5000")
rather than the much lengthier
Link(myUri, "alternate", Some("application/json"), Some("Cool
data"), Some("en"), Some(5000))
I'm also of the opinion that the Some()s in the second case don't add
much to the readability of the code, though others will probably
disagree - and I'm happy to be convinced otherwise as well :)
So, why is there no implicit any2Option?
Thanks,
Rich
Sat, 2009-12-12, 22:27
#4
Re: Why is there no implicit any2Option?
Yes, making things less verbose is itself not a virtue. There are many
possibilities that make things less verbose yet we deliberately choose
not to entertain them. This is an example.
Having both a value and having a maximum-length-one list containing that
value are distinct concepts and the type system *explicitly* denotes
that. This is a good thing. It is noted however, that both "a value"
(Identity) and Option are pointed functors. Specifically:
trait PointedFunctor[F[_]] {
def fmap[A, B](a: F[A], f: A => B): F[B]
def pure[A](a: A): F[A]
}
case class Identity[+A](a: A) // A list with length-one-and-only-one
Then there exist implementations (try it if you like):
new PointedFunctor[Identity]
new PointedFunctor[Option]
This fact is perhaps causing the intuition that it is a good idea for
them to be interchanged, overlooking that each structure has very
distinct properties (from the top of my head, Identity is a
contra-variant functor, while Option is not). "Cutting down on
characters" is not particularly valuable. Cutting down on redundant
characters perhaps, but putting a value into a pointed functor is
certainly not redundant.
I hope this helps.
Maxime Lévesque wrote:
>
> I actually agree, it seems like adding :
>
> implicit def any2Some[T](v : T): Option[T] = Some(v)
>
> to Predef
>
> would make things less verbose.. I wonder why it isn't there,
> are there any side effects that I am not forseeing ?
>
>
> Cheers
>
>
> On Fri, Dec 11, 2009 at 12:42 AM, Richard Wallace
> > wrote:
>
> I just defined a case class with 6 attributes, 4 of which are
> optional.
>
> case class Link(
> val href: URI,
> val rel: String,
> val mediaType: Option[String] = None,
> val title: Option[String] = None,
> val hreflang: Option[String] = None,
> val length: Option[Long] = None
> )
>
> I occurred to me that creating one of these things could be
> considerably easier if you could use
>
> Link(myUri, "alternate", "application/json", "Cool data", "en",
> "5000")
>
> rather than the much lengthier
>
> Link(myUri, "alternate", Some("application/json"), Some("Cool
> data"), Some("en"), Some(5000))
>
> I'm also of the opinion that the Some()s in the second case don't add
> much to the readability of the code, though others will probably
> disagree - and I'm happy to be convinced otherwise as well :)
>
> So, why is there no implicit any2Option?
>
> Thanks,
> Rich
>
>
Sat, 2009-12-12, 22:37
#5
Re: Why is there no implicit any2Option?
An implicit Option wrapper would conflict with rich wrappers for some classes (e.g. RichString and Option both define foreach, so "This".foreach(...) becomes ambiguous).
Also, if one is trying to write high-performance code, the fewer subtle ways one might create objects out of primitives, the better. (You want to do it on purpose only.)
See Tony's message for a pattern that avoids needing to create options when creating objects with immutable values.
Another possibility, if you're using objects with mutable innards, is to write custom setters so that you get options but set values:
class OptionalOption {
private var sOpt:Option[String] = None
def s = sOpt
def s_=(s0:String) { sOpt = Some(s0) }
}
scala> val oo = new OptionalOption
oo: OptionalOption = OptionalOption@5971c3
scala> oo.s
res12: Option[String] = None
scala> oo.s = "Hi!"
scala> oo.s
res13: Option[String] = Some(Hi!)
If you want to get slightly cleverer, the setter can intercept null and set None in its place.
--Rex
2009/12/12 Maxime Lévesque <maxime.levesque@gmail.com>
Also, if one is trying to write high-performance code, the fewer subtle ways one might create objects out of primitives, the better. (You want to do it on purpose only.)
See Tony's message for a pattern that avoids needing to create options when creating objects with immutable values.
Another possibility, if you're using objects with mutable innards, is to write custom setters so that you get options but set values:
class OptionalOption {
private var sOpt:Option[String] = None
def s = sOpt
def s_=(s0:String) { sOpt = Some(s0) }
}
scala> val oo = new OptionalOption
oo: OptionalOption = OptionalOption@5971c3
scala> oo.s
res12: Option[String] = None
scala> oo.s = "Hi!"
scala> oo.s
res13: Option[String] = Some(Hi!)
If you want to get slightly cleverer, the setter can intercept null and set None in its place.
--Rex
2009/12/12 Maxime Lévesque <maxime.levesque@gmail.com>
I actually agree, it seems like adding :
implicit def any2Some[T](v : T): Option[T] = Some(v)
to Predef
would make things less verbose.. I wonder why it isn't there,
are there any side effects that I am not forseeing ?
Sat, 2009-12-12, 22:37
#6
Re: Why is there no implicit any2Option?
FWIW, here's how an example of using a pointed functor in Scalaz5 (trunk):
scala> val j: List[Int] = 7 η
j: List[Int] = List(7)
scala> val k: Option[Int] = 7 η
k: Option[Int] = Some(7)
scala> val l: Identity[Int] = 7 η
l: scalaz.Identity[Int] = 7
scala> val m: Stream[Int] = 7 η
m: Stream[Int] = Stream(7, ?)
Rex Kerr wrote:
> An implicit Option wrapper would conflict with rich wrappers for some
> classes (e.g. RichString and Option both define foreach, so
> "This".foreach(...) becomes ambiguous).
>
> Also, if one is trying to write high-performance code, the fewer
> subtle ways one might create objects out of primitives, the better.
> (You want to do it on purpose only.)
>
> See Tony's message for a pattern that avoids needing to create options
> when creating objects with immutable values.
>
> Another possibility, if you're using objects with mutable innards, is
> to write custom setters so that you get options but set values:
>
> class OptionalOption {
> private var sOpt:Option[String] = None
> def s = sOpt
> def s_=(s0:String) { sOpt = Some(s0) }
> }
>
> scala> val oo = new OptionalOption
> oo: OptionalOption = OptionalOption@5971c3
>
> scala> oo.s
> res12: Option[String] = None
>
> scala> oo.s = "Hi!"
>
> scala> oo.s
> res13: Option[String] = Some(Hi!)
>
> If you want to get slightly cleverer, the setter can intercept null
> and set None in its place.
>
> --Rex
>
> 2009/12/12 Maxime Lévesque >
>
>
> I actually agree, it seems like adding :
>
> implicit def any2Some[T](v : T): Option[T] = Some(v)
>
> to Predef
>
> would make things less verbose.. I wonder why it isn't there,
> are there any side effects that I am not forseeing ?
>
>
Introducing the abstract algebraic data type. Please excuse the noise.
import java.net.URI
sealed trait Link {
val href: URI
val rel: String
val mediaType: Option[String]
val title: Option[String]
val hreflang: Option[String]
val length: Option[Long]
}
object Link {
def link(h: URI, r: String, mt: Option[String] = None, t:
Option[String] = None, hl: Option[String] = None, l: Option[Long] =
None): Link = new Link {
val href = h
val rel = r
val mediaType = mt
val title = t
val hreflang = hl
val length = l
}
def link(h: URI, r: String, mt: String, t: String, hl: String, l:
Long): Link = link(h, r, Some(mt), Some(t), Some(hl), Some(l))
}
object K {
import Link._
val myURI: URI = null // todo
val a = link(myURI, "alternate", "application/json", "Cool data",
"en", 5000L)
val b = link(myURI, "alternate")
val c = link(myURI, "alternate", hl = Some("en"))
}
// Scala code runner version 2.8.0.r20024-b20091207020224 -- Copyright
2002-2009, LAMP/EPFL
Richard Wallace wrote:
> I just defined a case class with 6 attributes, 4 of which are optional.
>
> case class Link(
> val href: URI,
> val rel: String,
> val mediaType: Option[String] = None,
> val title: Option[String] = None,
> val hreflang: Option[String] = None,
> val length: Option[Long] = None
> )
>
> I occurred to me that creating one of these things could be
> considerably easier if you could use
>
> Link(myUri, "alternate", "application/json", "Cool data", "en", "5000")
>
> rather than the much lengthier
>
> Link(myUri, "alternate", Some("application/json"), Some("Cool
> data"), Some("en"), Some(5000))
>
> I'm also of the opinion that the Some()s in the second case don't add
> much to the readability of the code, though others will probably
> disagree - and I'm happy to be convinced otherwise as well :)
>
> So, why is there no implicit any2Option?
>
> Thanks,
> Rich
>
>