diff options
author | Lukas Rytz <lukas.rytz@epfl.ch> | 2010-09-01 14:17:56 +0000 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@epfl.ch> | 2010-09-01 14:17:56 +0000 |
commit | cc81e9fea64083aaf26cdf6eae1fc3510e3aedaf (patch) | |
tree | 0fd36af9c6508462b361abdbd84f05bac5418b12 | |
parent | d7cc24bf7857ffe9e8dd51e2ac7f6254013c03b6 (diff) | |
download | scala-cc81e9fea64083aaf26cdf6eae1fc3510e3aedaf.tar.gz scala-cc81e9fea64083aaf26cdf6eae1fc3510e3aedaf.tar.bz2 scala-cc81e9fea64083aaf26cdf6eae1fc3510e3aedaf.zip |
Merged revisions 22473,22711-22713 via svnmerge...
Merged revisions 22473,22711-22713 via svnmerge from
https://lampsvn.epfl.ch/svn-repos/scala/scala/trunk
........
r22473 | extempore | 2010-07-02 18:26:05 +0200 (Fri, 02 Jul 2010) | 1 line
Option gets an empty factory like the collections. Closes #3414, no
review. ........ r22711 | rytz | 2010-08-09 15:37:04 +0200 (Mon, 09 Aug
2010) | 1 line
close #3709. no review.
........
r22712 | rytz | 2010-08-09 15:37:07 +0200 (Mon, 09 Aug 2010) | 1 line
close #7226. Apply trees are never considered stable (why were they?
applications to field getters are Select trees, not Apply). review by
odersky. ........ r22713 | rytz | 2010-08-09 15:37:11 +0200 (Mon, 09 Aug
2010) | 1 line
update doc of option. close #3737.
........
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/TreeInfo.scala | 2 | ||||
-rw-r--r-- | src/library/scala/Option.scala | 169 | ||||
-rw-r--r-- | src/library/scala/collection/mutable/ResizableArray.scala | 2 | ||||
-rw-r--r-- | test/files/run/t3726.check | 2 | ||||
-rw-r--r-- | test/files/run/t3726.scala | 8 |
5 files changed, 134 insertions, 49 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala index f21b1b20ff..3c77a9e4d3 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala @@ -85,8 +85,6 @@ abstract class TreeInfo { tree.symbol.isStable && isPureExpr(qual) case TypeApply(fn, _) => isPureExpr(fn) - case Apply(fn, List()) => - isPureExpr(fn) case Typed(expr, _) => isPureExpr(expr) case Block(stats, expr) => diff --git a/src/library/scala/Option.scala b/src/library/scala/Option.scala index 8992024353..bd15c31609 100644 --- a/src/library/scala/Option.scala +++ b/src/library/scala/Option.scala @@ -6,91 +6,151 @@ ** |/ ** \* */ - - package scala -object Option -{ +object Option { /** An implicit conversion that converts an option to an iterable value */ implicit def option2Iterable[A](xo: Option[A]): Iterable[A] = xo.toList - /** An Option factory which creates Some(value) if the argument is not null, + /** An Option factory which creates Some(x) if the argument is not null, * and None if it is null. * * @param x the value * @return Some(value) if value != null, None if value == null */ def apply[A](x: A): Option[A] = if (x == null) None else Some(x) + + /** An Option factory which returns $none in a manner consistent with + * the collections hierarchy. + */ + def empty[A] : Option[A] = None } -/** This class represents optional values. Instances of <code>Option</code> - * are either instances of case class <code>Some</code> or it is case - * object <code>None</code>. +/** Represents optional values. Instances of `Option` + * are either an instance of $some or the object $none. + * + * The most idiomatic way to use an $option instance + * is to treat it as a collection or monad and + * use `map`,`flatMap`, `filter`, + * or `foreach`: + * + * {{{ + * val name:Option[String] = request.getParameter("name") + * val upper = name map { _.trim } filter { _.length != 0 } map { _.toUpperCase } + * println(upper.getOrElse("")) + * }}} + * + * Note that this is equivalent to {{{ + * val upper = for { + * name <- request.getParameter("name") + * trimmed <- Some(name.trim) + * upper <- Some(trimmed.toUpperCase) if trimmed.length != 0 + * } yield upper + * println(upper.getOrElse("")) + * }}} + * + * Because of how for comprehension works, if $none is returned + * from `request.getParameter`, the entire expression results in + * $none + * + * This allows for sophisticated chaining of $option values without + * having to check for the existence of a value. + * + * A less-idiomatic way to use $option values is via pattern matching: {{{ + * val nameMaybe = request.getParameter("name") + * nameMaybe match { + * case Some(name) => { + * println(name.trim.toUppercase) + * } + * case None => { + * println("No name value") + * } + * } + * }}} * * @author Martin Odersky * @author Matthias Zenger * @version 1.1, 16/01/2007 + * @define none `None` + * @define some [[scala.Some]] + * @define option [[scala.Option]] + * @define p `p` + * @define f `f` */ sealed abstract class Option[+A] extends Product { self => - /** True if the option is the <code>None</code> value, false otherwise. + /** Returns true if the option is $none, false otherwise. */ def isEmpty: Boolean - /** True if the option is a <code>Some</code>(...) false otherwise. + /** Returns true if the option is an instance of $some, false otherwise. */ def isDefined: Boolean = !isEmpty - /** get the value of this option. + /** Returns the option's value. * @note The option must be nonEmpty. * @throws Predef.NoSuchElementException if the option is empty. */ def get: A - /** If the option is nonempty return its value, - * otherwise return the result of evaluating a default expression. + /** Returns the option's value if the option is nonempty, otherwise + * return the result of evaluating `default`. * * @param default the default expression. */ def getOrElse[B >: A](default: => B): B = if (isEmpty) default else this.get - /** The option's value if it is nonempty, or <code>null</code> if it is empty. - * The use of null of course is discouraged, but code written to use Options - * often must interface with code which expects and returns nulls. + /** Returns the option's value if it is nonempty, + * or `null` if it is empty. + * Although the use of null is discouraged, code written to use + * $option must often interface with code that expects and returns nulls. + * @example {{{ + * val initalText: Option[String] = getInitialText + * val textField = new JComponent(initalText.orNull,20) + * }}} */ def orNull[A1 >: A](implicit ev: Null <:< A1): A1 = this getOrElse null - /** If the option is nonempty, return a function applied to its value, - * wrapped in a Some i.e. <code>Some(f(this.get))</code>. - * Otherwise return <code>None</code>. + /** Returns a $some containing the result of applying $f to this $option's + * value if this $option is nonempty. + * Otherwise return $none. + * + * @note This is similar to `flatMap` except here, + * $f does not need to wrap its result in an $option. * * @param f the function to apply + * @see flatMap + * @see foreach */ def map[B](f: A => B): Option[B] = if (isEmpty) None else Some(f(this.get)) - /** If the option is nonempty, return a function applied to its value. - * Otherwise return None. + /** Returns the result of applying $f to this $option's value if + * this $option is nonempty. + * Returns $none if this $option is empty. + * Slightly different from `map` in that $f is expected to + * return an $option (which could be $none). + * * @param f the function to apply + * @see map + * @see foreach */ def flatMap[B](f: A => Option[B]): Option[B] = if (isEmpty) None else f(this.get) - /** If the option is nonempty and the given predicate <code>p</code> - * yields <code>false</code> on its value, return <code>None</code>. - * Otherwise return the option value itself. + /** Returns this $option if it is nonempty '''and''' applying the predicate $p to + * this $option's value returns true. Otherwise, return $none. * * @param p the predicate used for testing. */ def filter(p: A => Boolean): Option[A] = if (isEmpty || p(this.get)) this else None - /** Necessary to keep Option from being implicitly converted to - * Iterable in for comprehensions. + /** Necessary to keep $option from being implicitly converted to + * [[scala.collection.Iterable]] in `for` comprehensions. */ def withFilter(p: A => Boolean): WithFilter = new WithFilter(p) @@ -105,66 +165,83 @@ sealed abstract class Option[+A] extends Product { def withFilter(q: A => Boolean): WithFilter = new WithFilter(x => p(x) && q(x)) } - /** If the option is nonempty, p(value), otherwise false. + /** Returns true if this option is nonempty '''and''' the predicate + * $p returns true when applied to this $option's value. + * Otherwise, returns false. * * @param p the predicate to test */ def exists(p: A => Boolean): Boolean = !isEmpty && p(this.get) - /** Apply the given procedure <code>f</code> to the option's value, - * if it is nonempty. Do nothing if it is empty. + /** Apply the given procedure $f to the option's value, + * if it is nonempty. Otherwise, do nothing. * * @param f the procedure to apply. + * @see map + * @see flatMap */ def foreach[U](f: A => U) { if (!isEmpty) f(this.get) } - /** If the given partial function <code>pf</code> is defined for the - * option's value, apply it to the value. Otherwise, None. + /** Returns a $some containing the result of + * applying `pf` to this $option's contained + * value, '''if''' this option is + * nonempty '''and''' `pf` is defined for that value. + * Returns $none otherwise. * * @param pf the partial function. + * @return the result of applying `pf` to this $option's + * value (if possible), or $none. */ def collect[B](pf: PartialFunction[A, B]): Option[B] = if (!isEmpty && pf.isDefinedAt(this.get)) Some(pf(this.get)) else None - /** If the option is nonempty return it, - * otherwise return the result of evaluating an alternative expression. - * @param alternative the alternative expression. + /** Returns this $option if it is nonempty, + * otherwise return the result of evaluating `alternative`. + * @param alternative the alternative expression. */ def orElse[B >: A](alternative: => Option[B]): Option[B] = if (isEmpty) alternative else this - /** An singleton iterator returning the option's value if it is nonempty - * or the empty iterator if the option is empty. + /** Returns a singleton iterator returning the $option's value + * if it is nonempty, or an empty iterator if the option is empty. */ def iterator: Iterator[A] = if (isEmpty) Iterator.empty else Iterator.single(this.get) - /** A singleton list containing the option's value if it is nonempty - * or the empty list if the option is empty. + /** Returns a singleton list containing the $option's value + * if it is nonempty, or the empty list if the $option is empty. */ def toList: List[A] = if (isEmpty) List() else List(this.get) - /** An <code>Either</code> that is a <code>Left</code> with the given argument - * <code>left</code> if this is empty, or a <code>Right</code> if this is nonempty with the - * option's value. + /** Returns a [[scala.Left]] containing the given + * argument `left` if this $option is empty, or + * a [[scala.Right]] containing this $option's value if + * this is nonempty. + * + * @param left the expression to evaluate and return if this is empty + * @see toLeft */ def toRight[X](left: => X) = if (isEmpty) Left(left) else Right(this.get) - /** An <code>Either</code> that is a <code>Right</code> with the given argument - * <code>right</code> if this is empty, or a <code>Left</code> if this is nonempty with the - * option's value. + /** Returns a [[scala.Right]] containing the given + * argument `right` if this is empty, or + * a [[scala.Left]] containing this $option's value + * if this $option is nonempty. + * + * @param right the expression to evaluate and return if this is empty + * @see toRight */ def toLeft[X](right: => X) = if (isEmpty) Right(right) else Left(this.get) } -/** Class <code>Some[A]</code> represents existing values of type - * <code>A</code>. +/** Class `Some[A]` represents existing values of type + * `A`. * * @author Martin Odersky * @version 1.0, 16/07/2003 diff --git a/src/library/scala/collection/mutable/ResizableArray.scala b/src/library/scala/collection/mutable/ResizableArray.scala index 96ac7800ab..9cc19cd8e2 100644 --- a/src/library/scala/collection/mutable/ResizableArray.scala +++ b/src/library/scala/collection/mutable/ResizableArray.scala @@ -30,7 +30,7 @@ trait ResizableArray[A] extends IndexedSeq[A] override def companion: GenericCompanion[ResizableArray] = ResizableArray protected def initialSize: Int = 16 - protected var array: Array[AnyRef] = new Array[AnyRef](initialSize max 1) + protected var array: Array[AnyRef] = new Array[AnyRef](math.max(initialSize, 1)) protected var size0: Int = 0 diff --git a/test/files/run/t3726.check b/test/files/run/t3726.check new file mode 100644 index 0000000000..7a5775bf34 --- /dev/null +++ b/test/files/run/t3726.check @@ -0,0 +1,2 @@ +hi there +5
\ No newline at end of file diff --git a/test/files/run/t3726.scala b/test/files/run/t3726.scala new file mode 100644 index 0000000000..5ceed5416e --- /dev/null +++ b/test/files/run/t3726.scala @@ -0,0 +1,8 @@ +object Test extends Application { + def test(f: () => Int) = { + val x = f() + 5 + } + + println(test(() => { println("hi there"); 0 })) +} |