object LazyEvaluation extends AnyFlatSpec with ScalaTutorialSection
- Alphabetic
- By Inheritance
- LazyEvaluation
- ScalaTutorialSection
- Section
- Matchers
- Explicitly
- MatcherWords
- Tolerance
- AnyFlatSpec
- AnyFlatSpecLike
- Documenting
- Alerting
- Notifying
- Informing
- CanVerb
- MustVerb
- ShouldVerb
- TestRegistration
- TestSuite
- Suite
- Serializable
- Assertions
- TripleEquals
- TripleEqualsSupport
- AnyRef
- Any
- Hide All
- Show All
- Public
- Protected
Type Members
- final class AWord extends AnyRef
- Definition Classes
- Matchers
- final class AnWord extends AnyRef
- Definition Classes
- Matchers
- sealed class AnyShouldWrapper[T] extends AnyRef
- Definition Classes
- Matchers
- final class BehaviorWord extends AnyRef
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike
- class CheckingEqualizer[L] extends AnyRef
- Definition Classes
- TripleEqualsSupport
- sealed class Collected extends Serializable
- Attributes
- protected
- Definition Classes
- Matchers
- class DecidedByEquality[A] extends Equality[A]
- Definition Classes
- Explicitly
- class DecidedWord extends AnyRef
- Definition Classes
- Explicitly
- class DeterminedByEquivalence[T] extends Equivalence[T]
- Definition Classes
- Explicitly
- class DeterminedWord extends AnyRef
- Definition Classes
- Explicitly
- class Equalizer[L] extends AnyRef
- Definition Classes
- TripleEqualsSupport
- final class HavePropertyMatcherGenerator extends AnyRef
- Definition Classes
- Matchers
- final class IgnoreVerbString extends AnyRef
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike
- final class IgnoreVerbStringTaggedAs extends AnyRef
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike
- final class IgnoreWord extends AnyRef
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike
- final class InAndIgnoreMethods extends AnyRef
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike
- final class InAndIgnoreMethodsAfterTaggedAs extends AnyRef
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike
- final class ItVerbString extends AnyRef
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike
- final class ItVerbStringTaggedAs extends AnyRef
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike
- final class ItWord extends AnyRef
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike
- final class KeyWord extends AnyRef
- Definition Classes
- Matchers
- trait NoArgTest extends () => Outcome with TestData
- Attributes
- protected
- Definition Classes
- TestSuite
- final class PlusOrMinusWrapper[T] extends AnyRef
- Definition Classes
- Tolerance
- final class RegexWord extends AnyRef
- Definition Classes
- Matchers
- final class RegexWrapper extends AnyRef
- Definition Classes
- Matchers
- class ResultOfBeWordForAny[T] extends AnyRef
- Definition Classes
- Matchers
- sealed class ResultOfBeWordForCollectedAny[T] extends AnyRef
- Definition Classes
- Matchers
- final class ResultOfBeWordForCollectedArray[T] extends ResultOfBeWordForCollectedAny[Array[T]]
- Definition Classes
- Matchers
- final class ResultOfCollectedAny[T] extends AnyRef
- Definition Classes
- Matchers
- final class ResultOfContainWordForCollectedAny[T] extends AnyRef
- Definition Classes
- Matchers
- final class ResultOfEndWithWordForCollectedString extends AnyRef
- Definition Classes
- Matchers
- final class ResultOfEndWithWordForString extends AnyRef
- Definition Classes
- Matchers
- final class ResultOfFullyMatchWordForCollectedString extends AnyRef
- Definition Classes
- Matchers
- final class ResultOfFullyMatchWordForString extends AnyRef
- Definition Classes
- Matchers
- final class ResultOfHaveWordForCollectedExtent[A] extends AnyRef
- Definition Classes
- Matchers
- final class ResultOfHaveWordForExtent[A] extends AnyRef
- Definition Classes
- Matchers
- final class ResultOfIncludeWordForCollectedString extends AnyRef
- Definition Classes
- Matchers
- final class ResultOfIncludeWordForString extends AnyRef
- Definition Classes
- Matchers
- final class ResultOfNotWordForCollectedAny[T] extends AnyRef
- Definition Classes
- Matchers
- final class ResultOfStartWithWordForCollectedString extends AnyRef
- Definition Classes
- Matchers
- final class ResultOfStartWithWordForString extends AnyRef
- Definition Classes
- Matchers
- trait StringCanWrapperForVerb extends AnyRef
- Definition Classes
- CanVerb
- trait StringMustWrapperForVerb extends AnyRef
- Definition Classes
- MustVerb
- final class StringShouldWrapper extends AnyShouldWrapper[String] with org.scalatest.matchers.should.Matchers.StringShouldWrapperForVerb
- Definition Classes
- Matchers
- trait StringShouldWrapperForVerb extends AnyRef
- Definition Classes
- ShouldVerb
- class TheAfterWord extends AnyRef
- Definition Classes
- Explicitly
- final class TheSameInstanceAsPhrase extends AnyRef
- Definition Classes
- Matchers
- final class TheyVerbString extends AnyRef
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike
- final class TheyVerbStringTaggedAs extends AnyRef
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike
- final class TheyWord extends AnyRef
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike
- final class ValueWord extends AnyRef
- Definition Classes
- Matchers
Value Members
- final def !=(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- def !==[T](right: Spread[T]): TripleEqualsInvocationOnSpread[T]
- Definition Classes
- TripleEqualsSupport
- def !==(right: Null): TripleEqualsInvocation[Null]
- Definition Classes
- TripleEqualsSupport
- def !==[T](right: T): TripleEqualsInvocation[T]
- Definition Classes
- TripleEqualsSupport
- final def ##: Int
- Definition Classes
- AnyRef → Any
- def <[T](right: T)(implicit arg0: Ordering[T]): ResultOfLessThanComparison[T]
- Definition Classes
- Matchers
- def <=[T](right: T)(implicit arg0: Ordering[T]): ResultOfLessThanOrEqualToComparison[T]
- Definition Classes
- Matchers
- final def ==(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- def ===[T](right: Spread[T]): TripleEqualsInvocationOnSpread[T]
- Definition Classes
- TripleEqualsSupport
- def ===(right: Null): TripleEqualsInvocation[Null]
- Definition Classes
- TripleEqualsSupport
- def ===[T](right: T): TripleEqualsInvocation[T]
- Definition Classes
- TripleEqualsSupport
- def >[T](right: T)(implicit arg0: Ordering[T]): ResultOfGreaterThanComparison[T]
- Definition Classes
- Matchers
- def >=[T](right: T)(implicit arg0: Ordering[T]): ResultOfGreaterThanOrEqualToComparison[T]
- Definition Classes
- Matchers
- def a[T](implicit arg0: ClassTag[T]): ResultOfATypeInvocation[T]
- Definition Classes
- Matchers
- val a: AWord
- Definition Classes
- Matchers
- val after: TheAfterWord
- Definition Classes
- Explicitly
- def alert: Alerter
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike → Alerting
- def all(xs: String)(implicit collecting: Collecting[Char, String], prettifier: Prettifier, pos: Position): ResultOfCollectedAny[Char]
- Definition Classes
- Matchers
- def all[K, V, JMAP[k, v] <: Map[k, v]](xs: JMAP[K, V])(implicit collecting: Collecting[Entry[K, V], JMAP[K, V]], prettifier: Prettifier, pos: Position): ResultOfCollectedAny[Entry[K, V]]
- Definition Classes
- Matchers
- def all[K, V, MAP[k, v] <: GenMap[k, v]](xs: MAP[K, V])(implicit collecting: Collecting[(K, V), GenTraversable[(K, V)]], prettifier: Prettifier, pos: Position): ResultOfCollectedAny[(K, V)]
- Definition Classes
- Matchers
- def all[E, C[_]](xs: C[E])(implicit collecting: Collecting[E, C[E]], prettifier: Prettifier, pos: Position): ResultOfCollectedAny[E]
- Definition Classes
- Matchers
- def allElementsOf[R](elements: GenTraversable[R]): ResultOfAllElementsOfApplication
- Definition Classes
- Matchers
- def allOf(firstEle: Any, secondEle: Any, remainingEles: Any*)(implicit pos: Position): ResultOfAllOfApplication
- Definition Classes
- Matchers
- def an[T](implicit arg0: ClassTag[T]): ResultOfAnTypeInvocation[T]
- Definition Classes
- Matchers
- val an: AnWord
- Definition Classes
- Matchers
- final def asInstanceOf[T0]: T0
- Definition Classes
- Any
- macro def assert(condition: Boolean, clue: Any)(implicit prettifier: Prettifier, pos: Position): Assertion
- Definition Classes
- Assertions
- macro def assert(condition: Boolean)(implicit prettifier: Prettifier, pos: Position): Assertion
- Definition Classes
- Assertions
- macro def assertCompiles(code: String)(implicit pos: Position): Assertion
- Definition Classes
- Assertions
- macro def assertDoesNotCompile(code: String)(implicit pos: Position): Assertion
- Definition Classes
- Assertions
- def assertResult(expected: Any)(actual: Any)(implicit prettifier: Prettifier, pos: Position): Assertion
- Definition Classes
- Assertions
- def assertResult(expected: Any, clue: Any)(actual: Any)(implicit prettifier: Prettifier, pos: Position): Assertion
- Definition Classes
- Assertions
- def assertThrows[T <: AnyRef](f: => Any)(implicit classTag: ClassTag[T], pos: Position): Assertion
- Definition Classes
- Assertions
- macro def assertTypeError(code: String)(implicit pos: Position): Assertion
- Definition Classes
- Assertions
- macro def assume(condition: Boolean, clue: Any)(implicit prettifier: Prettifier, pos: Position): Assertion
- Definition Classes
- Assertions
- macro def assume(condition: Boolean)(implicit prettifier: Prettifier, pos: Position): Assertion
- Definition Classes
- Assertions
- def atLeast(num: Int, xs: String)(implicit collecting: Collecting[Char, String], prettifier: Prettifier, pos: Position): ResultOfCollectedAny[Char]
- Definition Classes
- Matchers
- def atLeast[K, V, JMAP[k, v] <: Map[k, v]](num: Int, xs: JMAP[K, V])(implicit collecting: Collecting[Entry[K, V], JMAP[K, V]], prettifier: Prettifier, pos: Position): ResultOfCollectedAny[Entry[K, V]]
- Definition Classes
- Matchers
- def atLeast[K, V, MAP[k, v] <: GenMap[k, v]](num: Int, xs: MAP[K, V])(implicit collecting: Collecting[(K, V), GenTraversable[(K, V)]], prettifier: Prettifier, pos: Position): ResultOfCollectedAny[(K, V)]
- Definition Classes
- Matchers
- def atLeast[E, C[_]](num: Int, xs: C[E])(implicit collecting: Collecting[E, C[E]], prettifier: Prettifier, pos: Position): ResultOfCollectedAny[E]
- Definition Classes
- Matchers
- def atLeastOneElementOf(elements: GenTraversable[Any]): ResultOfAtLeastOneElementOfApplication
- Definition Classes
- Matchers
- def atLeastOneOf(firstEle: Any, secondEle: Any, remainingEles: Any*)(implicit pos: Position): ResultOfAtLeastOneOfApplication
- Definition Classes
- Matchers
- def atMost(num: Int, xs: String)(implicit collecting: Collecting[Char, String], prettifier: Prettifier, pos: Position): ResultOfCollectedAny[Char]
- Definition Classes
- Matchers
- def atMost[K, V, JMAP[k, v] <: Map[k, v]](num: Int, xs: JMAP[K, V])(implicit collecting: Collecting[Entry[K, V], JMAP[K, V]], prettifier: Prettifier, pos: Position): ResultOfCollectedAny[Entry[K, V]]
- Definition Classes
- Matchers
- def atMost[K, V, MAP[k, v] <: GenMap[k, v]](num: Int, xs: MAP[K, V])(implicit collecting: Collecting[(K, V), GenTraversable[(K, V)]], prettifier: Prettifier, pos: Position): ResultOfCollectedAny[(K, V)]
- Definition Classes
- Matchers
- def atMost[E, C[_]](num: Int, xs: C[E])(implicit collecting: Collecting[E, C[E]], prettifier: Prettifier, pos: Position): ResultOfCollectedAny[E]
- Definition Classes
- Matchers
- def atMostOneElementOf[R](elements: GenTraversable[R]): ResultOfAtMostOneElementOfApplication
- Definition Classes
- Matchers
- def atMostOneOf(firstEle: Any, secondEle: Any, remainingEles: Any*)(implicit pos: Position): ResultOfAtMostOneOfApplication
- Definition Classes
- Matchers
- val be: BeWord
- Definition Classes
- MatcherWords
- val behave: BehaveWord
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike
- val behavior: BehaviorWord
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike
- def between(from: Int, upTo: Int, xs: String)(implicit collecting: Collecting[Char, String], prettifier: Prettifier, pos: Position): ResultOfCollectedAny[Char]
- Definition Classes
- Matchers
- def between[K, V, JMAP[k, v] <: Map[k, v]](from: Int, upTo: Int, xs: JMAP[K, V])(implicit collecting: Collecting[Entry[K, V], JMAP[K, V]], prettifier: Prettifier, pos: Position): ResultOfCollectedAny[Entry[K, V]]
- Definition Classes
- Matchers
- def between[E, C[_]](from: Int, upTo: Int, xs: C[E])(implicit collecting: Collecting[E, C[E]], prettifier: Prettifier, pos: Position): ResultOfCollectedAny[E]
- Definition Classes
- Matchers
- def cancel(cause: Throwable)(implicit pos: Position): Nothing
- Definition Classes
- Assertions
- def cancel(message: String, cause: Throwable)(implicit pos: Position): Nothing
- Definition Classes
- Assertions
- def cancel(message: String)(implicit pos: Position): Nothing
- Definition Classes
- Assertions
- def cancel()(implicit pos: Position): Nothing
- Definition Classes
- Assertions
- def clone(): AnyRef
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.CloneNotSupportedException]) @native()
- val compile: CompileWord
- Definition Classes
- MatcherWords
- val contain: ContainWord
- Definition Classes
- MatcherWords
- def convertEquivalenceToAToBConstraint[A, B](equivalenceOfB: Equivalence[B])(implicit ev: <:<[A, B]): CanEqual[A, B]
- Definition Classes
- TripleEquals → TripleEqualsSupport
- def convertEquivalenceToBToAConstraint[A, B](equivalenceOfA: Equivalence[A])(implicit ev: <:<[B, A]): CanEqual[A, B]
- Definition Classes
- TripleEquals → TripleEqualsSupport
- implicit def convertNumericToPlusOrMinusWrapper[T](pivot: T)(implicit arg0: Numeric[T]): PlusOrMinusWrapper[T]
- Definition Classes
- Tolerance
- implicit def convertSymbolToHavePropertyMatcherGenerator(symbol: Symbol)(implicit prettifier: Prettifier, pos: Position): HavePropertyMatcherGenerator
- Definition Classes
- Matchers
- implicit def convertToAnyShouldWrapper[T](o: T)(implicit pos: Position, prettifier: Prettifier): AnyShouldWrapper[T]
- Definition Classes
- Matchers
- def convertToCheckingEqualizer[T](left: T): CheckingEqualizer[T]
- Definition Classes
- TripleEquals → TripleEqualsSupport
- implicit def convertToEqualizer[T](left: T): Equalizer[T]
- Definition Classes
- TripleEquals → TripleEqualsSupport
- implicit def convertToInAndIgnoreMethods(resultOfStringPassedToVerb: ResultOfStringPassedToVerb): InAndIgnoreMethods
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike
- implicit def convertToInAndIgnoreMethodsAfterTaggedAs(resultOfTaggedAsInvocation: ResultOfTaggedAsInvocation): InAndIgnoreMethodsAfterTaggedAs
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike
- implicit def convertToRegexWrapper(o: Regex): RegexWrapper
- Definition Classes
- Matchers
- implicit def convertToStringCanWrapper(o: String)(implicit position: Position): StringCanWrapperForVerb
- Definition Classes
- CanVerb
- implicit def convertToStringMustWrapperForVerb(o: String)(implicit position: Position): StringMustWrapperForVerb
- Definition Classes
- MustVerb
- implicit def convertToStringShouldWrapper(o: String)(implicit pos: Position, prettifier: Prettifier): StringShouldWrapper
- Definition Classes
- Matchers
- implicit def convertToStringShouldWrapperForVerb(o: String)(implicit position: Position): StringShouldWrapperForVerb
- Definition Classes
- ShouldVerb
- val decided: DecidedWord
- Definition Classes
- Explicitly
- def defaultEquality[A]: Equality[A]
- Definition Classes
- TripleEqualsSupport
- val defined: DefinedWord
- Definition Classes
- MatcherWords
- def definedAt[T](right: T): ResultOfDefinedAt[T]
- Definition Classes
- Matchers
- val determined: DeterminedWord
- Definition Classes
- Explicitly
- val empty: EmptyWord
- Definition Classes
- MatcherWords
- val endWith: EndWithWord
- Definition Classes
- MatcherWords
- final def eq(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- def equal(o: Null): Matcher[AnyRef]
- Definition Classes
- Matchers
- def equal[T](spread: Spread[T]): Matcher[T]
- Definition Classes
- Matchers
- def equal(right: Any): MatcherFactory1[Any, Equality]
- Definition Classes
- MatcherWords
- def equals(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef → Any
- def every(xs: String)(implicit collecting: Collecting[Char, String], prettifier: Prettifier, pos: Position): ResultOfCollectedAny[Char]
- Definition Classes
- Matchers
- def every[K, V, JMAP[k, v] <: Map[k, v]](xs: JMAP[K, V])(implicit collecting: Collecting[Entry[K, V], JMAP[K, V]], prettifier: Prettifier, pos: Position): ResultOfCollectedAny[Entry[K, V]]
- Definition Classes
- Matchers
- def every[K, V, MAP[k, v] <: Map[k, v]](xs: MAP[K, V])(implicit collecting: Collecting[(K, V), GenTraversable[(K, V)]], prettifier: Prettifier, pos: Position): ResultOfCollectedAny[(K, V)]
- Definition Classes
- Matchers
- def every[E, C[_]](xs: C[E])(implicit collecting: Collecting[E, C[E]], prettifier: Prettifier, pos: Position): ResultOfCollectedAny[E]
- Definition Classes
- Matchers
- def exactly(num: Int, xs: String)(implicit collecting: Collecting[Char, String], prettifier: Prettifier, pos: Position): ResultOfCollectedAny[Char]
- Definition Classes
- Matchers
- def exactly[K, V, JMAP[k, v] <: Map[k, v]](num: Int, xs: JMAP[K, V])(implicit collecting: Collecting[Entry[K, V], JMAP[K, V]], prettifier: Prettifier, pos: Position): ResultOfCollectedAny[Entry[K, V]]
- Definition Classes
- Matchers
- def exactly[K, V, MAP[k, v] <: GenMap[k, v]](num: Int, xs: MAP[K, V])(implicit collecting: Collecting[(K, V), GenTraversable[(K, V)]], prettifier: Prettifier, pos: Position): ResultOfCollectedAny[(K, V)]
- Definition Classes
- Matchers
- def exactly[E, C[_]](num: Int, xs: C[E])(implicit collecting: Collecting[E, C[E]], prettifier: Prettifier, pos: Position): ResultOfCollectedAny[E]
- Definition Classes
- Matchers
- final def execute(testName: String, configMap: ConfigMap, color: Boolean, durations: Boolean, shortstacks: Boolean, fullstacks: Boolean, stats: Boolean): Unit
- Definition Classes
- Suite
- val exist: ExistWord
- Definition Classes
- MatcherWords
- def expectedTestCount(filter: Filter): Int
- Definition Classes
- Suite
- def fail(cause: Throwable)(implicit pos: Position): Nothing
- Definition Classes
- Assertions
- def fail(message: String, cause: Throwable)(implicit pos: Position): Nothing
- Definition Classes
- Assertions
- def fail(message: String)(implicit pos: Position): Nothing
- Definition Classes
- Assertions
- def fail()(implicit pos: Position): Nothing
- Definition Classes
- Assertions
- def finalize(): Unit
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.Throwable])
- val fullyMatch: FullyMatchWord
- Definition Classes
- MatcherWords
- final def getClass(): Class[_ <: AnyRef]
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
- def hashCode(): Int
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
- val have: HaveWord
- Definition Classes
- MatcherWords
- val ignore: IgnoreWord
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike
- def inOrder(firstEle: Any, secondEle: Any, remainingEles: Any*)(implicit pos: Position): ResultOfInOrderApplication
- Definition Classes
- Matchers
- def inOrderElementsOf[R](elements: GenTraversable[R]): ResultOfInOrderElementsOfApplication
- Definition Classes
- Matchers
- def inOrderOnly[T](firstEle: Any, secondEle: Any, remainingEles: Any*)(implicit pos: Position): ResultOfInOrderOnlyApplication
- Definition Classes
- Matchers
- val include: IncludeWord
- Definition Classes
- MatcherWords
- def info: Informer
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike → Informing
- def intercept[T <: AnyRef](f: => Any)(implicit classTag: ClassTag[T], pos: Position): T
- Definition Classes
- Assertions
- final def isInstanceOf[T0]: Boolean
- Definition Classes
- Any
- val it: ItWord
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike
- val key: KeyWord
- Definition Classes
- Matchers
- def lazyVal(res0: String): Unit
The proposed
LazyList
implementation suffers from a serious potential performance problem: Iftail
is called several times, the corresponding stream will be recomputed each time.Lazy Evaluation
The proposed
LazyList
implementation suffers from a serious potential performance problem: Iftail
is called several times, the corresponding stream will be recomputed each time.This problem can be avoided by storing the result of the first evaluation of
tail
and re-using the stored result instead of recomputingtail
.This optimization is sound, since in a purely functional language an expression produces the same result each time it is evaluated.
We call this scheme lazy evaluation (as opposed to by-name evaluation in the case where everything is recomputed, and strict evaluation for normal parameters and
val
definitions.)Lazy Evaluation in Scala
Haskell is a functional programming language that uses lazy evaluation by default.
Scala uses strict evaluation by default, but allows lazy evaluation of value definitions with the
lazy val
form:lazy val x = expr
Exercise
- val length: LengthWord
- Definition Classes
- MatcherWords
- def llRangeExercise(res0: Int): Unit
Consider the following program that finds the second prime number between 1000 and 10000:
Motivation
Consider the following program that finds the second prime number between 1000 and 10000:
((1000 to 10000) filter isPrime)(1)
This is much shorter than the recursive alternative:
def nthPrime(from: Int, to: Int, n: Int): Int = if (from >= to) throw new Error("no prime") else if (isPrime(from)) if (n == 1) from else nthPrime(from + 1, to, n - 1) else nthPrime(from + 1, to, n)
def secondPrime(from: Int, to: Int) = nthPrime(from, to, 2)
But from a standpoint of performance, the first version is pretty bad; it constructs all prime numbers between
1000
and10000
in a list, but only ever looks at the first two elements of that list.Reducing the upper bound would speed things up, but risks that we miss the second prime number all together.
Delayed Evaluation
However, we can make the short-code efficient by using a trick:
- Avoid computing the tail of a sequence until it is needed for the evaluation result (which might be never)
This idea is implemented in a new class, the
LazyList
.LazyLists are similar to lists, but their elements are evaluated only on demand.
Defining LazyLists
LazyLists are defined from a constructor
LazyList.cons
.For instance,
val xs = LazyList.cons(1, LazyList.cons(2, LazyList.empty))
LazyList Ranges
Let's try to write a function that returns a
LazyList
representing a range of numbers betweenlo
andhi
:def llRange(lo: Int, hi: Int): LazyList[Int] = if (lo >= hi) LazyList.empty else LazyList.cons(lo, llRange(lo + 1, hi))
Compare to the same function that produces a list:
def listRange(lo: Int, hi: Int): List[Int] = if (lo >= hi) Nil else lo :: listRange(lo + 1, hi)
The functions have almost identical structure yet they evaluate quite differently.
listRange(start, end)
will produce a list withend - start
elements and return it.llRange(start, end)
returns a single object of typeLazyList
withstart
as head element.- The other elements are only computed when they are needed, where
“needed” means that someone calls
tail
on the stream.
- The other elements are only computed when they are needed, where
“needed” means that someone calls
Methods on LazyLists
LazyList
supports almost all methods ofList
.For instance, to find the second prime number between 1000 and 10000:
(llRange(1000, 10000) filter isPrime)(1)
The one major exception is
::
.x :: xs
always produces a list, never a lazy list.There is however an alternative operator
#::
which produces a lazy list.x #:: xs == LazyList.cons(x, xs)
#::
can be used in expressions as well as patterns.Implementation of LazyLists
The implementation of lazy lists is quite close to the one of lists.
Here's the class
LazyList
:final class LazyList[+A] ... extends ... { override def isEmpty: Boolean = ... override def head: A = ... override def tail: LazyList[A] = ... ... }
As for lists, all other methods can be defined in terms of these three.
Concrete implementations of streams are defined in the
LazyList.State
companion object. Here's a first draft:private object State { object Empty extends State[Nothing] { def head: Nothing = throw new NoSuchElementException("head of empty lazy list") def tail: LazyList[Nothing] = throw new UnsupportedOperationException("tail of empty lazy list") } final class Cons[A](val head: A, val tail: LazyList[A]) extends State[A] }
The only important difference between the implementations of
List
andLazyList
concerntail
, the second parameter ofLazyList.cons
.For lazy lists, this is a by-name parameter: the type of
tail
starts with=>
. In such a case, this parameter is evaluated by following the rules of the call-by-name model.That's why the second argument to
LazyList.cons
is not evaluated at the point of call.Instead, it will be evaluated each time someone calls
tail
on aLazyList
object.In Scala 2.13, LazyList (previously Stream) became fully lazy from head to tail. To make it possible, methods (
filter
,flatMap
...) are implemented in a way where the head is not being evaluated if is not explicitly indicated.For instance, here's
filter
:object LazyList extends SeqFactory[LazyList] { ... private def filterImpl[A](ll: LazyList[A], p: A => Boolean, isFlipped: Boolean): LazyList[A] = { // DO NOT REFERENCE `ll` ANYWHERE ELSE, OR IT WILL LEAK THE HEAD var restRef = ll // val restRef = new ObjectRef(ll) newLL { var elem: A = null.asInstanceOf[A] var found = false var rest = restRef // var rest = restRef.elem while (!found && !rest.isEmpty) { elem = rest.head found = p(elem) != isFlipped rest = rest.tail restRef = rest // restRef.elem = rest } if (found) sCons(elem, filterImpl(rest, p, isFlipped)) else State.Empty } }
Exercise
Consider the following modification of
llRange
. When you writellRange(1, 10).take(3).toList
what is the value ofrec
?Be careful, head is evaluating too!
- def lowPriorityTypeCheckedConstraint[A, B](implicit equivalenceOfB: Equivalence[B], ev: <:<[A, B]): CanEqual[A, B]
- Definition Classes
- TripleEquals → TripleEqualsSupport
- def markup: Documenter
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike → Documenting
- val matchPattern: MatchPatternWord
- Definition Classes
- MatcherWords
- def message(expectedMessage: String): ResultOfMessageWordApplication
- Definition Classes
- Matchers
- final def ne(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- def nestedSuites: IndexedSeq[Suite]
- Definition Classes
- Suite
- def no(xs: String)(implicit collecting: Collecting[Char, String], prettifier: Prettifier, pos: Position): ResultOfCollectedAny[Char]
- Definition Classes
- Matchers
- def no[K, V, JMAP[k, v] <: Map[k, v]](xs: JMAP[K, V])(implicit collecting: Collecting[Entry[K, V], JMAP[K, V]], prettifier: Prettifier, pos: Position): ResultOfCollectedAny[Entry[K, V]]
- Definition Classes
- Matchers
- def no[E, C[_]](xs: C[E])(implicit collecting: Collecting[E, C[E]], prettifier: Prettifier, pos: Position): ResultOfCollectedAny[E]
- Definition Classes
- Matchers
- def noElementsOf(elements: GenTraversable[Any]): ResultOfNoElementsOfApplication
- Definition Classes
- Matchers
- def noException(implicit pos: Position): NoExceptionWord
- Definition Classes
- MatcherWords
- def noneOf(firstEle: Any, secondEle: Any, remainingEles: Any*)(implicit pos: Position): ResultOfNoneOfApplication
- Definition Classes
- Matchers
- val not: NotWord
- Definition Classes
- MatcherWords
- def note: Notifier
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike → Notifying
- final def notify(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
- final def notifyAll(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
- def of[T](implicit ev: ClassTag[T]): ResultOfOfTypeInvocation[T]
- Definition Classes
- Matchers
- def oneElementOf(elements: GenTraversable[Any]): ResultOfOneElementOfApplication
- Definition Classes
- Matchers
- def oneOf(firstEle: Any, secondEle: Any, remainingEles: Any*)(implicit pos: Position): ResultOfOneOfApplication
- Definition Classes
- Matchers
- def only(xs: Any*)(implicit pos: Position): ResultOfOnlyApplication
- Definition Classes
- Matchers
- def pending: Assertion with PendingStatement
- Definition Classes
- Assertions
- def pendingUntilFixed(f: => Unit)(implicit pos: Position): Assertion with PendingStatement
- Definition Classes
- Assertions
- val readable: ReadableWord
- Definition Classes
- MatcherWords
- val regex: RegexWord
- Definition Classes
- Matchers
- final def registerIgnoredTest(testText: String, testTags: Tag*)(testFun: => Any)(implicit pos: Position): Unit
- Definition Classes
- AnyFlatSpecLike → TestRegistration
- final def registerTest(testText: String, testTags: Tag*)(testFun: => Any)(implicit pos: Position): Unit
- Definition Classes
- AnyFlatSpecLike → TestRegistration
- def rerunner: Option[String]
- Definition Classes
- Suite
- def run(testName: Option[String], args: Args): Status
- Definition Classes
- AnyFlatSpecLike → Suite
- def runNestedSuites(args: Args): Status
- Attributes
- protected
- Definition Classes
- Suite
- def runTest(testName: String, args: Args): Status
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike → TestSuite → Suite
- def runTests(testName: Option[String], args: Args): Status
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike → Suite
- implicit val shorthandSharedTestRegistrationFunction: StringVerbBehaveLikeInvocation
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike
- implicit val shorthandTestRegistrationFunction: StringVerbStringInvocation
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike
- val size: SizeWord
- Definition Classes
- MatcherWords
- val sorted: SortedWord
- Definition Classes
- MatcherWords
- val startWith: StartWithWord
- Definition Classes
- MatcherWords
- final val succeed: Assertion
- Definition Classes
- Assertions
- def suiteId: String
- Definition Classes
- Suite
- def suiteName: String
- Definition Classes
- Suite
- final def synchronized[T0](arg0: => T0): T0
- Definition Classes
- AnyRef
- def tags: Map[String, Set[String]]
- Definition Classes
- AnyFlatSpecLike → Suite
- def testDataFor(testName: String, theConfigMap: ConfigMap): TestData
- Definition Classes
- AnyFlatSpecLike → Suite
- def testNames: Set[String]
- Definition Classes
- AnyFlatSpecLike → Suite
- def the[T](implicit arg0: ClassTag[T], pos: Position): ResultOfTheTypeInvocation[T]
- Definition Classes
- Matchers
- def theSameElementsAs(xs: GenTraversable[_]): ResultOfTheSameElementsAsApplication
- Definition Classes
- Matchers
- def theSameElementsInOrderAs(xs: GenTraversable[_]): ResultOfTheSameElementsInOrderAsApplication
- Definition Classes
- Matchers
- val theSameInstanceAs: TheSameInstanceAsPhrase
- Definition Classes
- Matchers
- val they: TheyWord
- Attributes
- protected
- Definition Classes
- AnyFlatSpecLike
- def thrownBy(fun: => Any): ResultOfThrownByApplication
- Definition Classes
- Matchers
- def toString(): String
- Definition Classes
- AnyFlatSpec → AnyRef → Any
- val typeCheck: TypeCheckWord
- Definition Classes
- MatcherWords
- def typeCheckedConstraint[A, B](implicit equivalenceOfA: Equivalence[A], ev: <:<[B, A]): CanEqual[A, B]
- Definition Classes
- TripleEquals → TripleEqualsSupport
- implicit def unconstrainedEquality[A, B](implicit equalityOfA: Equality[A]): CanEqual[A, B]
- Definition Classes
- TripleEquals → TripleEqualsSupport
- val value: ValueWord
- Definition Classes
- Matchers
- final def wait(): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
- final def wait(arg0: Long, arg1: Int): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
- final def wait(arg0: Long): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException]) @native()
- def withClue[T](clue: Any)(fun: => T): T
- Definition Classes
- Assertions
- def withFixture(test: NoArgTest): Outcome
- Attributes
- protected
- Definition Classes
- TestSuite
- val writable: WritableWord
- Definition Classes
- MatcherWords
Deprecated Value Members
- def conversionCheckedConstraint[A, B](implicit equivalenceOfA: Equivalence[A], cnv: (B) => A): CanEqual[A, B]
- Definition Classes
- TripleEquals → TripleEqualsSupport
- Annotations
- @deprecated
- Deprecated
(Since version 3.1.0) The conversionCheckedConstraint method has been deprecated and will be removed in a future version of ScalaTest. It is no longer needed now that the deprecation period of ConversionCheckedTripleEquals has expired. It will not be replaced.
- def convertEquivalenceToAToBConversionConstraint[A, B](equivalenceOfB: Equivalence[B])(implicit ev: (A) => B): CanEqual[A, B]
- Definition Classes
- TripleEquals → TripleEqualsSupport
- Annotations
- @deprecated
- Deprecated
(Since version 3.1.0) The convertEquivalenceToAToBConversionConstraint method has been deprecated and will be removed in a future version of ScalaTest. It is no longer needed now that the deprecation period of ConversionCheckedTripleEquals has expired. It will not be replaced.
- def convertEquivalenceToBToAConversionConstraint[A, B](equivalenceOfA: Equivalence[A])(implicit ev: (B) => A): CanEqual[A, B]
- Definition Classes
- TripleEquals → TripleEqualsSupport
- Annotations
- @deprecated
- Deprecated
(Since version 3.1.0) The convertEquivalenceToBToAConversionConstraint method has been deprecated and will be removed in a future version of ScalaTest. It is no longer needed now that the deprecation period of ConversionCheckedTripleEquals has expired. It will not be replaced.
- def lowPriorityConversionCheckedConstraint[A, B](implicit equivalenceOfB: Equivalence[B], cnv: (A) => B): CanEqual[A, B]
- Definition Classes
- TripleEquals → TripleEqualsSupport
- Annotations
- @deprecated
- Deprecated
(Since version 3.1.0) The lowPriorityConversionCheckedConstraint method has been deprecated and will be removed in a future version of ScalaTest. It is no longer needed now that the deprecation period of ConversionCheckedTripleEquals has expired. It will not be replaced.
- final val styleName: String
- Definition Classes
- AnyFlatSpecLike → Suite
- Annotations
- @deprecated
- Deprecated
(Since version 3.1.0) The styleName lifecycle method has been deprecated and will be removed in a future version of ScalaTest with no replacement.