Mike Slinn

Learning Scala Using The REPL 3/3

— Draft —

Published 2013-12-21. Last modified 2024-07-18.
Time to read: 2 minutes.

This lecture continues our exploration of the Scala REPL. Here documents and tab completion in the REPL are discussed.

Scala REPL Here Documents

Scala 2.11.8 made it easier to paste a block of script (as opposed to transcript, which we saw earlier in this lecture).

If you use a Scala REPL here doc you won’t accidentally press Ctrl-d once too many times and exit the REPL. To cause the Scala REPL to begin reading a here doc, type :paste < DELIMITER, where DELIMITER is an arbitrary sequence of characters not found in the pasted input. Provide as many lines of Scala code as you wish, and then terminate the here doc by providing the DELIMITER on a separate line. Here is an example:

Shell
$ scala
Welcome to Scala 2.11.12 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_74).
Type in expressions for evaluation. Or try :help.

scala> :paste < EOF
// Entering paste mode (EOF to finish) 
object C { val c = 21 } class C { val c = C.c * 2 } EOF
// Exiting paste mode, now interpreting. defined class C scala> new C().c res0: Int = 42

There is a second syntax for Scala REPL here docs, which uses the <| operator instead of the < operator between :paste and the DELIMITER. This syntax is useful when pasting code that has a margin character in front, like this:

Shell
scala> :paste <| EOF
// Entering paste mode (EOF to finish) 
|def inhale(i: Int): Unit = 1 to i foreach { j => | println(s"I will smell $j flowers each day!") |} |inhale(3) EOF %}
// Exiting paste mode, now interpreting.
I will smell 1 flowers each day! I will smell 2 flowers each day! I will smell 3 flowers each day! inhale: (i: Int)Unit

Finally, a third syntax removed leading white space. This isn’t very useful, but I include it for completeness:

Shell
scala> :paste <- EOF
// Entering paste mode (EOF to finish) 
def inhale(i: Int): Unit = 1 to i foreach { j => println(s"I will smell $j flowers each day!") } inhale(3) EOF
// Exiting paste mode, now interpreting.
I will smell 1 flowers each day! I will smell 2 flowers each day! I will smell 3 flowers each day! inhale: (i: Int)Unit

Scala REPL Tab Completion

This section is paraphrased from the Scala 2.12 release notes.

Reliable Completion

Partially complete expressions and syntactically incorrect programs now enjoy tab completion.

The following example uses a List, which is a type of collection. Collections will be discussed in the Collections Overview lecture of the Intermediate Scala course.

Scala REPL
scala> def f(list: List[Int]) = list.TAB
scala: do you wish to see all 184 possibilities (62 lines)?y
##               (universal)   groupMapReduce(                reverse
+(              (deprecated)   grouped(                       reverseIterator
++(                            hasDefiniteSize (deprecated)   reverseMap(     (deprecated)
++:(                           hashCode()                     reverse_:::(
+:(                            head                           runWith(
->(              (universal)   headOption                     sameElements(
/:(             (deprecated)   indexOf(                       scan(
:+(                            indexOfSlice(                  scanLeft(
:++(                           indexWhere(                    scanRight(
::(                            indices                        search(
:::(                           init                           segmentLength(
:\(             (deprecated)   inits                          seq             (deprecated)
==(              (universal)   intersect(                     size
addString(                     isDefinedAt(                   sizeCompare(
aggregate(      (deprecated)   isEmpty                        sizeIs
andThen(                       isInstanceOf     (universal)   slice(
appended(                      isTraversableAgain             sliding(
appendedAll(                   iterableFactory                sortBy(
apply(                         iterator                       sortWith(
applyOrElse(                   knownSize                      sorted(
asInstanceOf     (universal)   last                           span(
canEqual(                      lastIndexOf(                   splitAt(
collect(                       lastIndexOfSlice(              startsWith(
collectFirst(                  lastIndexWhere(                stepper(
combinations(                  lastOption                     sum(
companion       (deprecated)   lazyZip(                       synchronized(    (universal)
compose(                       length                         tail
concat(                        lengthCompare(                 tails
contains(                      lengthIs                       take(
scala> def f(list: List[Int]) = list.
s sameElements( seq (deprecated) sortBy( stepper( scan( size sortWith( sum( scanLeft( sizeCompare( sorted( synchronized( (universal) scanRight( sizeIs span( search( slice( splitAt( segmentLength( sliding( startsWith(
scala> def f(list: List[Int]) = list.s
u sum(
scala> def f(list: List[Int]) = list.su
m }
scala> f(List(1, 2, 3)) val res9: Int = 6

CamelCase Completion

The following example uses the reduceRightOption method, which is a high-order funciton. Higher-order functions will be discussed in the Higher-Order Functions lecture of the Intermediate Scala course.

Scala REPL
scala> List(1, 2, 3).rroTAB

Expands to:

Scala REPL
scala> (l: List[Int]).reduceRightOption

Now we can complete the expression:

Scala REPL
scala> (l: List[Int]).reduceRightOption(_ + _)
res5: Option[Int] = Some(6) 

Show Desugarings Performed By the Compiler

Adding //print to an expression and then pressing TAB causes the REPL to display the desugared syntax of the expression that you are typing. This example uses for-expressions and lambda functions. For-expressions will be discussed in the For-Loops and For-Comprehensions lecture of the Intermediate Scala course. Lambda functions will be discussed in the More Fun With Functions and Lambda Review & Drill lectures of this course.

Scala REPL
scala> for (x <- 1 to 10) println(x) //printTAB
scala.Predef.intWrapper(1).to(10).foreach[Unit](((x: Int) => scala.Predef.println(x))) // : Unit
scala> for (x <- 1 to 10) println(x) //print

Complete Bean Getters

Getters will be discussed in the Setters, Getters and the Uniform Access Principle lecture.

This feature seems to be of limited use. You do not need to type get:

Scala REPL
scala> def dayOf(d: java.util.Date) = d.dayTAB

Expands to:

Scala REPL
scala> def dayOf(d: java.util.Date) = d.getDay

Find Members by Typing any CamelCased Part of the Name

Scala REPL
scala> classOf[String].typTAB

Expands to:

Scala REPL
scala> classOf[String].typ
   getAnnotationsByType   getComponentType   getDeclaredAnnotationsByType   getTypeName   getTypeParameters
scala> classOf[String].typnTAB

Expands to:

Scala REPL
scala> classOf[String].getTypeName
res0: String = java.lang.String 

Complete Non-Qualified Names, Including Types

Scala REPL
scala> def f(s: StrTAB

Expands to:

Scala REPL
scala> def f(s: Str
Stream       String         StringBuilder        StringContext   StringIndexOutOfBoundsException
StrictMath   StringBuffer   StringCanBuildFrom   StringFormat

Press Tab Twice to See the Method Signature

Scala REPL
scala> List(1,2,3).partTAB

Expands to:

Scala REPL
scala> List(1,2,3).partition

Press TAB again:

Scala REPL
scala> List(1,2,3).partition
  def partition(p: Int => Boolean): (List[Int], List[Int])

* indicates a required field.

Please select the following to receive Mike Slinn’s newsletter:

You can unsubscribe at any time by clicking the link in the footer of emails.

Mike Slinn uses Mailchimp as his marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp’s privacy practices.