This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Why is there no implicit any2Option?

6 replies
Richard Wallace
Joined: 2009-07-14,
User offline. Last seen 42 years 45 weeks ago.

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

Tony Morris 2
Joined: 2009-03-20,
User offline. Last seen 42 years 45 weeks ago.
Re: Why is there no implicit any2Option?

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
>
>

Maxime Lévesque
Joined: 2009-08-18,
User offline. Last seen 42 years 45 weeks ago.
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

Kevin Wright
Joined: 2009-06-09,
User offline. Last seen 49 weeks 3 days ago.
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


Tony Morris 2
Joined: 2009-03-20,
User offline. Last seen 42 years 45 weeks ago.
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
>
>

ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
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>

  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 ?

Tony Morris 2
Joined: 2009-03-20,
User offline. Last seen 42 years 45 weeks ago.
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 ?
>
>

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland