|
Following on from some recent discussion on the design of Option and in my ongoing search to understand Scala, I have a fundamental question.
Why does the method "get" exist in the Option class? Here is the abbreviated code from scala/Option.scala. sealed abstract class Option[+A] extends Product { def get: A } final case class Some[+A](x: A) extends Option[A] { def get = x } case object None extends Option[Nothing] { def get = throw new NoSuchElementException("None.get") } For reasons of type safety, shouldn't "get" only exist in Some? Or is this just another way of replacing "x.getOrElse(default)" with "try { x.get } catch { default }"? Regards, Sean |
|
that would force you to cast option to some and every time you now do
{know that op is defined} op.get would turn into {know that op is defined} op.asInstanceOf[Some[MyType]].get with no benefit because if {know that op is defined} is wrong, you'll just replace nosuchelement by a classcast. -------- Original-Nachricht -------- > Datum: Fri, 13 Aug 2010 12:30:40 +0200 > Von: Sean Leather <[hidden email]> > An: Scala Users Lists <[hidden email]> > Betreff: [scala-user] Why have method "get" in Option? > Following on from some recent discussion on the design of Option and in my > ongoing search to understand Scala, I have a fundamental question. > > Why does the method "get" exist in the Option class? Here is the > abbreviated > code from scala/Option.scala. > > sealed abstract class Option[+A] extends Product { > def get: A > } > > final case class Some[+A](x: A) extends Option[A] { > def get = x > } > > case object None extends Option[Nothing] { > def get = throw new NoSuchElementException("None.get") > } > > For reasons of type safety, shouldn't "get" only exist in Some? Or is this > just another way of replacing "x.getOrElse(default)" with "try { x.get } > catch { default }"? > > Regards, > Sean -- GMX DSL SOMMER-SPECIAL: Surf & Phone Flat 16.000 für nur 19,99 ¿/mtl.!* http://portal.gmx.net/de/go/dsl |
|
In reply to this post by Sean Leather
Hi Sean,
Your question can be generalised to, "why have partial functions?" The answer is not because they are preferred, but because they are necessary according to Turing's undecidability. Some languages do away with turing-completeness in favour of totality (that is, no partial functions). Examples are Coq and Agda. This is related to the mistakes in the original article. Sean Leather wrote: > Following on from some recent discussion on the design of Option and > in my ongoing search to understand Scala, I have a fundamental question. > > Why does the method "get" exist in the Option class? Here is the > abbreviated code from scala/Option.scala. > > sealed abstract class Option[+A] extends Product { > def get: A > } > > final case class Some[+A](x: A) extends Option[A] { > def get = x > } > > case object None extends Option[Nothing] { > def get = throw new NoSuchElementException("None.get") > } > > For reasons of type safety, shouldn't "get" only exist in Some? Or is > this just another way of replacing "x.getOrElse(default)" with "try { > x.get } catch { default }"? > > Regards, > Sean -- Tony Morris http://tmorris.net/ |
|
In reply to this post by HamsterofDeath
no, the question is valid. basically you should be able to get completely around with 'foreach', 'map' and 'getOrElse', thus 'get' is a really poor method that introduces potential runtime errors which would be impossible without this method. and thus, if you consider 'get' being not there, also the question of why not all the methods are in the subclasses of None and Some is totally accurate. i think that would have been cleaner (besides slightly faster) than the if( ....isDefined ) all over the Option class. the argumentation of "Algebraic data types" versus "Class hierarchies" misses the point IMO. Option is already sealed, so there can be only the two subclasses None and Some.
best, -sciss- Am 13.08.2010 um 12:30 schrieb Dennis Haupt: > that would force you to cast option to some and every time you now do > {know that op is defined} op.get > would turn into > {know that op is defined} op.asInstanceOf[Some[MyType]].get > > with no benefit because if {know that op is defined} is wrong, you'll just replace nosuchelement by a classcast. > > > -------- Original-Nachricht -------- >> Datum: Fri, 13 Aug 2010 12:30:40 +0200 >> Von: Sean Leather <[hidden email]> >> An: Scala Users Lists <[hidden email]> >> Betreff: [scala-user] Why have method "get" in Option? > >> Following on from some recent discussion on the design of Option and in my >> ongoing search to understand Scala, I have a fundamental question. >> >> Why does the method "get" exist in the Option class? Here is the >> abbreviated >> code from scala/Option.scala. >> >> sealed abstract class Option[+A] extends Product { >> def get: A >> } >> >> final case class Some[+A](x: A) extends Option[A] { >> def get = x >> } >> >> case object None extends Option[Nothing] { >> def get = throw new NoSuchElementException("None.get") >> } >> >> For reasons of type safety, shouldn't "get" only exist in Some? Or is this >> just another way of replacing "x.getOrElse(default)" with "try { x.get } >> catch { default }"? >> >> Regards, >> Sean > > -- > GMX DSL SOMMER-SPECIAL: Surf & Phone Flat 16.000 für nur 19,99 ¿/mtl.!* > http://portal.gmx.net/de/go/dsl |
|
In reply to this post by HamsterofDeath
No, it wouldn't force you to cast, because you can use pattern matching instead of casting:
val opt: Option[X] = ... opt match { case Some(x) => println(x)
case None => println("None") } (Note, you don't even have to call 'get', pattern matching gets the value out of the Option for you).
Jesper 2010/8/13 Dennis Haupt <[hidden email]> that would force you to cast option to some and every time you now do -- Jesper de Jong [hidden email] |
|
That is correct, but it was not the question. To use the method get you
would have to cast to Some.
I think the get method is only useful in cases where you are 100% sure that you have a Some to make the whole thing more concise. Whenever you are unsure use pattern matching or getOrElse. Dan Jesper de Jong schrieb: No, it wouldn't force you to cast, because you can use pattern matching instead of casting: |
|
In reply to this post by Sean Leather
Thanks for the response. There are quite a few replies here, and I'm certain I don't understand most. As a result, I will try to clarify my question. Why does the method "get" exist in the Option class? The point of this question is that the method "get" is by definition unsafe. By unsafe, I mean that it will likely lead a programmer who uses it into error. Why is it unsafe? Let's review the code: sealed abstract class Option[+A] extends Product { def get: A } Since "get" is defined in the class Option, there is an implication that each subclass will override it and return some A value. Looking at each inheritor, we see that Some overrides and results in a value, but None throws an exception. Since there are only two subclasses and half of them are exceptional cases, I'd say it's pretty clear that "get" will lead somebody into error. Thus, it is unsafe. For reasons of type safety, shouldn't "get" only exist in Some? Or is this just another way of replacing "x.getOrElse(default)" with "try { x.get } catch { default }"? I'm suggesting that "get" not be defined in Option but rather in Some. That provides one way to get the value out of Some. But how do you get the value out of an Option? Again, I'm new to Scala but I already see multiple ways:
Of course, this is not to say that a method equivalent to "get" can't still be written outside of Option. def fromSome(opt: Option[A]) = opt match { case Some(x) => x case None => throw new NoSuchElementException("fromSome") } However, by putting "Option.get" (and even "orNull" and possibly others) in the standard library, it encourages programmers to use unsafe methods by making it easy. I get the impression that such unsafe methods are generally included in the Scala libraries. So, I suppose my real question should be: Why are unsafe methods included in the standard libraries? Regards, Sean |
|
In reply to this post by Sc iss
On Fri, Aug 13, 2010 at 6:38 AM, Sciss <[hidden email]> wrote: no, the question is valid. basically you should be able to get completely around with 'foreach', 'map' and 'getOrElse', thus 'get' is a really poor method that introduces potential runtime errors which would be impossible without this method. In the cases I use 'get' without checking I *want* a runtime error. It means I made a wrong assumption in my code and it better fail fast. |
|
In reply to this post by Sean Leather
But get is not any more unsafe than dereferencing any non-final (e.g. val) reference. As I've said in one of the other Option threads - it's not Options / nullabilities fault that we have NoSuchElementException / NPE:s, it's bad assumptions. Bad assumptions don't go away because you take away get. You could just aswell do foreach on an Option not accounting for the fact that in your particular use-case you also need to handle the None-case. Bad assumption.
Structure the code in such a way that there are no assumptions that cannot be 100% trusted.
On Fri, Aug 13, 2010 at 2:37 PM, Sean Leather <[hidden email]> wrote:
|
|
In reply to this post by Sean Leather
On Fri, Aug 13, 2010 at 6:30 AM, Sean Leather <[hidden email]> wrote: Following on from some recent discussion on the design of Option and in my ongoing search to understand Scala, I have a fundamental question. It exists so you can do things like this: // Example 1: You know it will succeed, why check again? def f(o: Option[Int]) = o map (i => i + i*i) f(Some(7)).get // Example 2: Usually don't need the value, why pattern-match? def g(o: Option[Int], rare_condition: Boolean) { if (o.isDefined) { println("All sorts of stuff happens here") if (rare_condition) println( o.get ) println("More stuff happens here") } else { println("Various stuff here") } } // Example 3: We're prototyping here--let's not error-check every case yet def h(command_line_argument: Option[String]) { println("User asked for: " + command_line_argument.get) } The coder's job is know when get is the appropriate method, and when they should use something else. --Rex |
|
In reply to this post by Jesper de Jong
that just hides the cast, and it's even longer than using a cast or getOrElse directly.
i still vote for a simple "get" -------- Original-Nachricht -------- > Datum: Fri, 13 Aug 2010 13:46:27 +0200 > Von: Jesper de Jong <[hidden email]> > An: scala-user <[hidden email]> > Betreff: Re: [scala-user] Why have method "get" in Option? > No, it wouldn't force you to cast, because you can use pattern matching > instead of casting: > > val opt: Option[X] = ... > > opt match { > case Some(x) => println(x) > case None => println("None") > } > > (Note, you don't even have to call 'get', pattern matching gets the value > out of the Option for you). > > Jesper > > 2010/8/13 Dennis Haupt <[hidden email]> > > > that would force you to cast option to some and every time you now do > > {know that op is defined} op.get > > would turn into > > {know that op is defined} op.asInstanceOf[Some[MyType]].get > > > > with no benefit because if {know that op is defined} is wrong, you'll > just > > replace nosuchelement by a classcast. > > > > > > -------- Original-Nachricht -------- > > > Datum: Fri, 13 Aug 2010 12:30:40 +0200 > > > Von: Sean Leather <[hidden email]> > > > An: Scala Users Lists <[hidden email]> > > > Betreff: [scala-user] Why have method "get" in Option? > > > > > Following on from some recent discussion on the design of Option and > in > > my > > > ongoing search to understand Scala, I have a fundamental question. > > > > > > Why does the method "get" exist in the Option class? Here is the > > > abbreviated > > > code from scala/Option.scala. > > > > > > sealed abstract class Option[+A] extends Product { > > > def get: A > > > } > > > > > > final case class Some[+A](x: A) extends Option[A] { > > > def get = x > > > } > > > > > > case object None extends Option[Nothing] { > > > def get = throw new NoSuchElementException("None.get") > > > } > > > > > > For reasons of type safety, shouldn't "get" only exist in Some? Or is > > this > > > just another way of replacing "x.getOrElse(default)" with "try { x.get > } > > > catch { default }"? > > > > > > Regards, > > > Sean > > > > -- > > GMX DSL SOMMER-SPECIAL: Surf & Phone Flat 16.000 für nur 19,99 > ¿/mtl.!* > > http://portal.gmx.net/de/go/dsl > > > > > > -- > Jesper de Jong > [hidden email] -- GMX DSL SOMMER-SPECIAL: Surf & Phone Flat 16.000 für nur 19,99 ¿/mtl.!* http://portal.gmx.net/de/go/dsl |
|
I think that the presence of 'get' in Option (rather than Some) is
unfortunate as well. It defeats the purpose of using Option in the first place, and as such I never use it. With respect to the example: // Example 1: You know it will succeed, why check again? def f(o: Option[Int]) = o map (i => i + i*i) f(Some(7)).get I thought that there might be a solution to this in a definition like: scala> def f[T <: Option[Int]](o: T): T = o.map(i => i + i*i) <console>:5: error: type mismatch; found : Option[Int] required: T but it appears that the type of map does not specialize adequately (at least with this construction.) I was surprised when I went to the scaladoc to find that Option doesn't extend from TraversableLike. This seems very odd to me - it means that this kind of construction fails too: scala> for (v <- Some(2); v2 <- List(4, 5, 6)) yield v * v2 <console>:6: error: type mismatch; found : List[Int] required: Option[?] for (v <- Some(2); v2 <- List(4, 5, 6)) yield v * v2 ^ Yuck! Why is Option a second-class citizen??? Kris On Fri, Aug 13, 2010 at 8:34 AM, Dennis Haupt <[hidden email]> wrote: > that just hides the cast, and it's even longer than using a cast or getOrElse directly. > > i still vote for a simple "get" > > -------- Original-Nachricht -------- >> Datum: Fri, 13 Aug 2010 13:46:27 +0200 >> Von: Jesper de Jong <[hidden email]> >> An: scala-user <[hidden email]> >> Betreff: Re: [scala-user] Why have method "get" in Option? > >> No, it wouldn't force you to cast, because you can use pattern matching >> instead of casting: >> >> val opt: Option[X] = ... >> >> opt match { >> case Some(x) => println(x) >> case None => println("None") >> } >> >> (Note, you don't even have to call 'get', pattern matching gets the value >> out of the Option for you). >> >> Jesper >> >> 2010/8/13 Dennis Haupt <[hidden email]> >> >> > that would force you to cast option to some and every time you now do >> > {know that op is defined} op.get >> > would turn into >> > {know that op is defined} op.asInstanceOf[Some[MyType]].get >> > >> > with no benefit because if {know that op is defined} is wrong, you'll >> just >> > replace nosuchelement by a classcast. >> > >> > >> > -------- Original-Nachricht -------- >> > > Datum: Fri, 13 Aug 2010 12:30:40 +0200 >> > > Von: Sean Leather <[hidden email]> >> > > An: Scala Users Lists <[hidden email]> >> > > Betreff: [scala-user] Why have method "get" in Option? >> > >> > > Following on from some recent discussion on the design of Option and >> in >> > my >> > > ongoing search to understand Scala, I have a fundamental question. >> > > >> > > Why does the method "get" exist in the Option class? Here is the >> > > abbreviated >> > > code from scala/Option.scala. >> > > >> > > sealed abstract class Option[+A] extends Product { >> > > def get: A >> > > } >> > > >> > > final case class Some[+A](x: A) extends Option[A] { >> > > def get = x >> > > } >> > > >> > > case object None extends Option[Nothing] { >> > > def get = throw new NoSuchElementException("None.get") >> > > } >> > > >> > > For reasons of type safety, shouldn't "get" only exist in Some? Or is >> > this >> > > just another way of replacing "x.getOrElse(default)" with "try { x.get >> } >> > > catch { default }"? >> > > >> > > Regards, >> > > Sean >> > >> > -- >> > GMX DSL SOMMER-SPECIAL: Surf & Phone Flat 16.000 für nur 19,99 >> ¿/mtl.!* >> > http://portal.gmx.net/de/go/dsl >> > >> >> >> >> -- >> Jesper de Jong >> [hidden email] > > -- > GMX DSL SOMMER-SPECIAL: Surf & Phone Flat 16.000 für nur 19,99 ¿/mtl.!* > http://portal.gmx.net/de/go/dsl > |
|
On Fri, Aug 13, 2010 at 12:58:14PM -0600, Kris Nuttycombe wrote:
> Yuck! Why is Option a second-class citizen??? The most recent of many trips around that maypole: http://scala-programming-language.1934581.n4.nabble.com/Why-does-Option-not-extend-the-Iterable-trait-td1944949.html There are lengthier ones, but that one is probably enough for you. -- Paul Phillips | Adultery is the application of democracy to love. Caged Spirit | -- H. L. Mencken Empiricist | i pull his palp! |----------* http://www.improving.org/paulp/ *---------- |
|
In reply to this post by Kris Nuttycombe-3
i think you misunderstood the purpose of map on option.
it maps Some(x) to Some(y) and None to None. the mapping function can be applied to any option, no matter if it's some or none. you don't have to check if option is defined. it's not meant to get the value out of a some. and maybe you misunderstood the option itself. i use it as a return type where there might be no valid result. for example, if i call "findPath(from:Position, to:Position), the return type is Option[Path]. if there is a path i get some, if there is none, i get None. now i want to render that path: result.foreach(_.renderOnScreen) no need to check for null. the function is executed if there is a path, otherwise nothing is going to happen. Am 13.08.2010 20:58, schrieb Kris Nuttycombe: > I think that the presence of 'get' in Option (rather than Some) is > unfortunate as well. It defeats the purpose of using Option in the > first place, and as such I never use it. > > With respect to the example: > > // Example 1: You know it will succeed, why check again? > def f(o: Option[Int]) = o map (i => i + i*i) > f(Some(7)).get > > I thought that there might be a solution to this in a definition like: > > scala> def f[T <: Option[Int]](o: T): T = o.map(i => i + i*i) > <console>:5: error: type mismatch; > found : Option[Int] > required: T > > but it appears that the type of map does not specialize adequately (at > least with this construction.) I was surprised when I went to the > scaladoc to find that Option doesn't extend from TraversableLike. This > seems very odd to me - it means that this kind of construction fails > too: > > scala> for (v <- Some(2); v2 <- List(4, 5, 6)) yield v * v2 > <console>:6: error: type mismatch; > found : List[Int] > required: Option[?] > for (v <- Some(2); v2 <- List(4, 5, 6)) yield v * v2 > ^ > > Yuck! Why is Option a second-class citizen??? > > Kris > > > > On Fri, Aug 13, 2010 at 8:34 AM, Dennis Haupt <[hidden email]> wrote: >> that just hides the cast, and it's even longer than using a cast or getOrElse directly. >> >> i still vote for a simple "get" >> >> -------- Original-Nachricht -------- >>> Datum: Fri, 13 Aug 2010 13:46:27 +0200 >>> Von: Jesper de Jong <[hidden email]> >>> An: scala-user <[hidden email]> >>> Betreff: Re: [scala-user] Why have method "get" in Option? >>> No, it wouldn't force you to cast, because you can use pattern matching >>> instead of casting: >>> >>> val opt: Option[X] = ... >>> >>> opt match { >>> case Some(x) => println(x) >>> case None => println("None") >>> } >>> >>> (Note, you don't even have to call 'get', pattern matching gets the value >>> out of the Option for you). >>> >>> Jesper >>> >>> 2010/8/13 Dennis Haupt <[hidden email]> >>> >>>> that would force you to cast option to some and every time you now do >>>> {know that op is defined} op.get >>>> would turn into >>>> {know that op is defined} op.asInstanceOf[Some[MyType]].get >>>> >>>> with no benefit because if {know that op is defined} is wrong, you'll >>> just >>>> replace nosuchelement by a classcast. >>>> >>>> >>>> -------- Original-Nachricht -------- >>>>> Datum: Fri, 13 Aug 2010 12:30:40 +0200 >>>>> Von: Sean Leather <[hidden email]> >>>>> An: Scala Users Lists <[hidden email]> >>>>> Betreff: [scala-user] Why have method "get" in Option? >>>>> Following on from some recent discussion on the design of Option and >>> in >>>> my >>>>> ongoing search to understand Scala, I have a fundamental question. >>>>> >>>>> Why does the method "get" exist in the Option class? Here is the >>>>> abbreviated >>>>> code from scala/Option.scala. >>>>> >>>>> sealed abstract class Option[+A] extends Product { >>>>> def get: A >>>>> } >>>>> >>>>> final case class Some[+A](x: A) extends Option[A] { >>>>> def get = x >>>>> } >>>>> >>>>> case object None extends Option[Nothing] { >>>>> def get = throw new NoSuchElementException("None.get") >>>>> } >>>>> >>>>> For reasons of type safety, shouldn't "get" only exist in Some? Or is >>>> this >>>>> just another way of replacing "x.getOrElse(default)" with "try { x.get >>> } >>>>> catch { default }"? >>>>> >>>>> Regards, >>>>> Sean >>>> -- >>>> GMX DSL SOMMER-SPECIAL: Surf & Phone Flat 16.000 für nur 19,99 >>> ¿/mtl.!* >>>> http://portal.gmx.net/de/go/dsl >>>> >>> >>> >>> -- >>> Jesper de Jong >>> [hidden email] >> -- >> GMX DSL SOMMER-SPECIAL: Surf & Phone Flat 16.000 für nur 19,99 ¿/mtl.!* >> http://portal.gmx.net/de/go/dsl >> |
|
Hah. I understand the purpose of map quite well, thanks. Perhaps you
should look at my question (and the applicability of TraversableLike) a little more closely. If Option were to extend TraversableLike, then it would be possible to "trace" whether an Option instance were a Some or a None through a a call to map, and have a safe implementation of get. But, then, as Paulp's link demonstrates, flatMap would be broken. So it's not a reasonable idea after all. :) Kris On Fri, Aug 13, 2010 at 1:21 PM, HamsterofDeath <[hidden email]> wrote: > i think you misunderstood the purpose of map on option. > it maps Some(x) to Some(y) and None to None. the mapping function can be > applied to any option, no matter if it's some or none. you don't have to > check if option is defined. it's not meant to get the value out of a some. > > and maybe you misunderstood the option itself. i use it as a return type > where there might be no valid result. for example, if i call > "findPath(from:Position, to:Position), the return type is Option[Path]. > if there is a path i get some, if there is none, i get None. > now i want to render that path: > result.foreach(_.renderOnScreen) > no need to check for null. the function is executed if there is a path, > otherwise nothing is going to happen. > > > > > > Am 13.08.2010 20:58, schrieb Kris Nuttycombe: >> I think that the presence of 'get' in Option (rather than Some) is >> unfortunate as well. It defeats the purpose of using Option in the >> first place, and as such I never use it. >> >> With respect to the example: >> >> // Example 1: You know it will succeed, why check again? >> def f(o: Option[Int]) = o map (i => i + i*i) >> f(Some(7)).get >> >> I thought that there might be a solution to this in a definition like: >> >> scala> def f[T <: Option[Int]](o: T): T = o.map(i => i + i*i) >> <console>:5: error: type mismatch; >> found : Option[Int] >> required: T >> >> but it appears that the type of map does not specialize adequately (at >> least with this construction.) I was surprised when I went to the >> scaladoc to find that Option doesn't extend from TraversableLike. This >> seems very odd to me - it means that this kind of construction fails >> too: >> >> scala> for (v <- Some(2); v2 <- List(4, 5, 6)) yield v * v2 >> <console>:6: error: type mismatch; >> found : List[Int] >> required: Option[?] >> for (v <- Some(2); v2 <- List(4, 5, 6)) yield v * v2 >> ^ >> >> Yuck! Why is Option a second-class citizen??? >> >> Kris >> >> >> >> On Fri, Aug 13, 2010 at 8:34 AM, Dennis Haupt <[hidden email]> wrote: >>> that just hides the cast, and it's even longer than using a cast or getOrElse directly. >>> >>> i still vote for a simple "get" >>> >>> -------- Original-Nachricht -------- >>>> Datum: Fri, 13 Aug 2010 13:46:27 +0200 >>>> Von: Jesper de Jong <[hidden email]> >>>> An: scala-user <[hidden email]> >>>> Betreff: Re: [scala-user] Why have method "get" in Option? >>>> No, it wouldn't force you to cast, because you can use pattern matching >>>> instead of casting: >>>> >>>> val opt: Option[X] = ... >>>> >>>> opt match { >>>> case Some(x) => println(x) >>>> case None => println("None") >>>> } >>>> >>>> (Note, you don't even have to call 'get', pattern matching gets the value >>>> out of the Option for you). >>>> >>>> Jesper >>>> >>>> 2010/8/13 Dennis Haupt <[hidden email]> >>>> >>>>> that would force you to cast option to some and every time you now do >>>>> {know that op is defined} op.get >>>>> would turn into >>>>> {know that op is defined} op.asInstanceOf[Some[MyType]].get >>>>> >>>>> with no benefit because if {know that op is defined} is wrong, you'll >>>> just >>>>> replace nosuchelement by a classcast. >>>>> >>>>> >>>>> -------- Original-Nachricht -------- >>>>>> Datum: Fri, 13 Aug 2010 12:30:40 +0200 >>>>>> Von: Sean Leather <[hidden email]> >>>>>> An: Scala Users Lists <[hidden email]> >>>>>> Betreff: [scala-user] Why have method "get" in Option? >>>>>> Following on from some recent discussion on the design of Option and >>>> in >>>>> my >>>>>> ongoing search to understand Scala, I have a fundamental question. >>>>>> >>>>>> Why does the method "get" exist in the Option class? Here is the >>>>>> abbreviated >>>>>> code from scala/Option.scala. >>>>>> >>>>>> sealed abstract class Option[+A] extends Product { >>>>>> def get: A >>>>>> } >>>>>> >>>>>> final case class Some[+A](x: A) extends Option[A] { >>>>>> def get = x >>>>>> } >>>>>> >>>>>> case object None extends Option[Nothing] { >>>>>> def get = throw new NoSuchElementException("None.get") >>>>>> } >>>>>> >>>>>> For reasons of type safety, shouldn't "get" only exist in Some? Or is >>>>> this >>>>>> just another way of replacing "x.getOrElse(default)" with "try { x.get >>>> } >>>>>> catch { default }"? >>>>>> >>>>>> Regards, >>>>>> Sean >>>>> -- >>>>> GMX DSL SOMMER-SPECIAL: Surf & Phone Flat 16.000 für nur 19,99 >>>> ¿/mtl.!* >>>>> http://portal.gmx.net/de/go/dsl >>>>> >>>> >>>> >>>> -- >>>> Jesper de Jong >>>> [hidden email] >>> -- >>> GMX DSL SOMMER-SPECIAL: Surf & Phone Flat 16.000 für nur 19,99 ¿/mtl.!* >>> http://portal.gmx.net/de/go/dsl >>> > > |
|
In reply to this post by HamsterofDeath
No, when you pattern match, there is no cast at all, and no possibility that a ClassCastException will happen (which is why a cast is bad). Pattern matching is not a "hidden cast".
Jesper
2010/8/13 Dennis Haupt <[hidden email]> that just hides the cast, and it's even longer than using a cast or getOrElse directly. -- Jesper de Jong [hidden email] |
|
On Friday August 13 2010, Jesper de Jong wrote:
> No, when you pattern match, there is no cast at all, and no > possibility that a ClassCastException will happen (which is why a > cast is bad). Pattern matching is not a "hidden cast". It is a cast. It's just that the asInstanceOf is reliably conditioned upon a preceding isInstanceOf (their JVM bytecode equivalents, anyway). > Jesper Randall Schulz |
|
In reply to this post by Sean Leather
Sean,
Scala *must* have unsafe methods. It's absolutely necessary. Nothing is solved by moving or removing the get function in this respect. Sean Leather wrote: > Thanks for the response. There are quite a few replies here, and I'm > certain I don't understand most. As a result, I will try to clarify my > question. > > Why does the method "get" exist in the Option class? > > > The point of this question is that the method "get" is by definition > unsafe. By unsafe, I mean that it will likely lead a programmer who > uses it into error. Why is it unsafe? Let's review the code: > > > sealed abstract class Option[+A] extends Product { def get: A } > final case class Some[+A](x: A) extends Option[A] { def get = x } > case object None extends Option[Nothing] { def get = throw new > NoSuchElementException("None.get") } > > > Since "get" is defined in the class Option, there is an implication > that each subclass will override it and return some A value. Looking > at each inheritor, we see that Some overrides and results in a value, > but None throws an exception. Since there are only two subclasses and > half of them are exceptional cases, I'd say it's pretty clear that > "get" will lead somebody into error. Thus, it is unsafe. > > For reasons of type safety, shouldn't "get" only exist in Some? Or > is this just another way of replacing "x.getOrElse(default)" with > "try { x.get } catch { default }"? > > > I'm suggesting that "get" not be defined in Option but rather in Some. > That provides one way to get the value out of Some. But how do you get > the value out of an Option? Again, I'm new to Scala but I already see > multiple ways: > > * getOrElse > * foreach/for > * iterator > * opt match { case Some(x) => ... ; case None => ... } > > And I'm sure there are others. > > Of course, this is not to say that a method equivalent to "get" can't > still be written outside of Option. > > def fromSome(opt: Option[A]) = opt match { > case Some(x) => x > case None => throw new NoSuchElementException("fromSome") > } > > However, by putting "Option.get" (and even "orNull" and possibly > others) in the standard library, it encourages programmers to use > unsafe methods by making it easy. I get the impression that such > unsafe methods are generally included in the Scala libraries. So, I > suppose my real question should be: Why are unsafe methods included in > the standard libraries? > > Regards, > Sean -- Tony Morris http://tmorris.net/ |
|
In reply to this post by Paul Phillips-3
sealed abstract class Opt[+A] extends Iterable[A]
case object Non extends Opt[Nothing] { def iterator: Iterator[Nothing] = Iterator.empty def map[B](f:Nothing => B):Opt[B] = Non def flatMap[B](f:Nothing => Opt[B]):Opt[B] = Non override def filter(p:Nothing => Boolean):Opt[Nothing] = Non } case class Som[+A](a:A) extends Opt[A] { def iterator: Iterator[A] = Iterator.single(a) def map[B](f:A => B):Opt[B] = Som(f(a)) def flatMap[B](f:A => Opt[B]):Opt[B] = f(a) override def filter(p:A => Boolean):Opt[A] = if (p(a)) this else Non } object Opt { def main(args : Array[String]) : Unit = { println(Som(1) flatMap{_:Int => Som(1)}) // Som(1) println(Som(1) flatMap{_:Int => Iterable(1, 2)}) // List(1, 2) println(for { y <- List(1, 2) x:Int <- Som(y) } yield (x, y)) // List((1,1), (2,2)) } } What is wrong with that? Thanks, Sebastien 2010/8/13 Paul Phillips <[hidden email]>
|
|
In reply to this post by Tony Morris
Tony,
Please elaborate on this. I'm not seeing the necessity. Kind regards, Egon. Tony Morris wrote: Sean, Scala *must* have unsafe methods. It's absolutely necessary. Nothing is solved by moving or removing the get function in this respect. Sean Leather wrote: > Thanks for the response. There are quite a few replies here, and I'm > certain I don't understand most. As a result, I will try to clarify my > question. > > Why does the method "get" exist in the Option class? > > > The point of this question is that the method "get" is by definition > unsafe. By unsafe, I mean that it will likely lead a programmer who > uses it into error. Why is it unsafe? Let's review the code: > > > sealed abstract class Option[+A] extends Product { def get: A } > final case class Some[+A](x: A) extends Option[A] { def get = x } > case object None extends Option[Nothing] { def get = throw new > NoSuchElementException("None.get") } > > > Since "get" is defined in the class Option, there is an implication > that each subclass will override it and return some A value. Looking > at each inheritor, we see that Some overrides and results in a value, > but None throws an exception. Since there are only two subclasses and > half of them are exceptional cases, I'd say it's pretty clear that > "get" will lead somebody into error. Thus, it is unsafe. > > For reasons of type safety, shouldn't "get" only exist in Some? Or > is this just another way of replacing "x.getOrElse(default)" with > "try { x.get } catch { default }"? > > > I'm suggesting that "get" not be defined in Option but rather in Some. > That provides one way to get the value out of Some. But how do you get > the value out of an Option? Again, I'm new to Scala but I already see > multiple ways: > > * getOrElse > * foreach/for > * iterator > * opt match { case Some(x) => ... ; case None => ... } > > And I'm sure there are others. > > Of course, this is not to say that a method equivalent to "get" can't > still be written outside of Option. > > def fromSome(opt: Option[A]) = opt match { > case Some(x) => x > case None => throw new NoSuchElementException("fromSome") > } > > However, by putting "Option.get" (and even "orNull" and possibly > others) in the standard library, it encourages programmers to use > unsafe methods by making it easy. I get the impression that such > unsafe methods are generally included in the Scala libraries. So, I > suppose my real question should be: Why are unsafe methods included in > the standard libraries? > > Regards, > Sean -- Tony Morris http://tmorris.net/ |
| Powered by Nabble | See how NAML generates this page |
