{"id":28434129,"url":"https://github.com/travisbrown/scala-quickstart","last_synced_at":"2025-08-30T17:13:33.226Z","repository":{"id":139820160,"uuid":"51286410","full_name":"travisbrown/scala-quickstart","owner":"travisbrown","description":"Getting started in the Scala REPL","archived":false,"fork":false,"pushed_at":"2016-03-28T10:45:53.000Z","size":471,"stargazers_count":28,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-06-30T09:42:20.275Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/travisbrown.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-02-08T08:30:50.000Z","updated_at":"2020-05-09T14:16:21.000Z","dependencies_parsed_at":"2023-04-23T04:31:19.415Z","dependency_job_id":null,"html_url":"https://github.com/travisbrown/scala-quickstart","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/travisbrown/scala-quickstart","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/travisbrown%2Fscala-quickstart","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/travisbrown%2Fscala-quickstart/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/travisbrown%2Fscala-quickstart/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/travisbrown%2Fscala-quickstart/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/travisbrown","download_url":"https://codeload.github.com/travisbrown/scala-quickstart/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/travisbrown%2Fscala-quickstart/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272878320,"owners_count":25008336,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-30T02:00:09.474Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-06-05T19:06:49.799Z","updated_at":"2025-08-30T17:13:33.220Z","avatar_url":"https://github.com/travisbrown.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Scala quickstart\n\nThis is a basic [SBT][sbt] project designed to help you start working\neffectively in a Scala REPL (read-eval-print loop) as quickly as possible. Once\nyou've cloned the project, you can open the SBT console with the following\ncommand:\n\n```bash\n./sbt\n```\n\nNote that you'll need to have [Java][java] installed on your machine for this to\nwork. Once you're in the SBT console you can type `console` to open a Scala\nREPL. You should see something like this:\n\n```scala\n\u003e console\n[info] Starting scala interpreter...\n[info] \nWelcome to Scala version 2.11.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_66).\nType in expressions to have them evaluated.\nType :help for more information.\n\nscala\u003e \n```\n\nYou can now type Scala definitions and expressions and they will be evaluated\nimmediately.\n\n## REPL tips\n\nMost of the time the REPL should just do what you'd expect it to do (try to\nevaluate code and print the result), but in some cases you may need or want to\nuse special REPL-specific commands that it provides to accomplish certain\nthings.\n\n### Defining companions\n\nIf you simply type the following definitions into the REPL as two separate\nlines, you'll get an error, since the case class and the object won't be treated\nas companions:\n\n```scala\ncase class Foo(i: Int)\nobject Foo { def empty: Foo = Foo(0) }\n```\n\nIn these situations you can use `:paste` to combine definitions into a single\ncompilation unit:\n\n```scala\nscala\u003e :paste\n// Entering paste mode (ctrl-D to finish)\n\ncase class Foo(i: Int)\nobject Foo { def empty: Foo = Foo(0) }\n\n// Exiting paste mode, now interpreting.\n\ndefined class Foo\ndefined object Foo\n```\n\n### Copying and pasting entire session entries\n\nSuppose you've got the following in a REPL session:\n\n```scala\nscala\u003e val doubled = \"a\" * 2\ndoubled: String = aa\n\nscala\u003e doubled.size\nres1: Int = 2\n```\n\nIf you want to evaluate these definitions again (either in the same session or a\nnew one), you can copy and paste the entire block of text, including the\n`scala\u003e` prompts and the result output, and the REPL will recognize that that's\nwhat's going on:\n\n```scala\nscala\u003e scala\u003e val doubled = \"a\" * 2\n\n// Detected repl transcript paste: ctrl-D to finish.\n\ndoubled: String = aa\n\nscala\u003e doubled.size\nres1: Int = 2\n\n// Replaying 2 commands from transcript.\n```\n\nFinding the type of an expression:\n\nYou can use the `:type` command to make the REPL tell you the type of any\nexpression, even if that expression doesn't evaluate to a value:\n\n```scala\nscala\u003e :type 1 / 0\nInt\n```\n\n### Saving a REPL session to a file\n\nYou can use `:save` to write a REPL session to a file in the current directory:\n\n```scala\nscala\u003e val doubled = \"a\" * 2\ndoubled: String = aa\n\nscala\u003e doubled.size\nres0: Int = 2\n\nscala\u003e :save doubling.sc\n```\n\n`doubling.sc` will now contain the following:\n\n```scala\nval doubled = \"a\" * 2\ndoubled.size\n```\n\nNote that these definitions won't necessarily be a valid `.scala` file. I'm\nusing the `.sc` extension here so that SBT won't try to parse the file as Scala,\nbut you can use any other extension you wish.\n\n### Loading Scala definitions into the REPL from a file\n\nYou can also use `:load` to import definitions from a file into the REPL:\n\n```scala\nscala\u003e :load doubling.sc\nLoading doubling.sc...\ndoubled: String = aa\nres0: Int = 2\n```\n\n### Desugaring extension methods and other syntactic magic\n\nThanks to the magic of extension methods and implicit conversions, it's often\nvery difficult to determine why you can call certain methods on certain\nexpressions and where these methods are coming from. We've been writing the\nfollowing, for example:\n\n```scala\nscala\u003e val doubled = \"a\" * 2\ndoubled: String = aa\n\nscala\u003e doubled.size\nres0: Int = 2\n```\n\nBut Scala's `String` is just an alias for `java.lang.String`, which doesn't have\n`*` or `size` methods. If we want to know where these are coming from, we can\nuse Scala's reflection API in the REPL to find out:\n\n```scala\nscala\u003e import scala.reflect.runtime.universe.{ reify, showCode }\nimport scala.reflect.runtime.universe.{reify, showCode}\n\nscala\u003e showCode(reify(\"a\" * 2).tree)\nres0: String = Predef.augmentString(\"a\").*(2)\n```\n\nNow we can look up the `augmentString` method on `Predef` in the standard\nlibrary's API docs, which will lead us to [`StringOps`][string-ops].\n\nThis approach also works for syntactic sugar like `for`-comprehensions. For\nexample, it might not be clear why we can mix and match sequences and options in\na `for`-comprehension:\n\n```scala\nscala\u003e showCode(reify(for { i \u003c- 1 to 3; j \u003c- Option(4) } yield i + j).tree)\n```\n\nThis will print the following (which I've reformatted for clarity):\n\n```scala\nPredef.intWrapper(1).to(3).flatMap(\n  ((i) =\u003e Option.option2Iterable(Option.apply(4).map(((j) =\u003e i.+(j)))))\n)(IndexedSeq.canBuildFrom)\n```\n\nThis takes some processing to understand, but at least everything is explicit.\n\n### Viewing bytecode and JVM method signatures\n\nMany Scala language features (such as case classes) involve the generation of\nsynthetic methods, and even user-defined methods often end up having signatures\nat the JVM level that you might not expect. It's possible to use `:javap` in the\nScala REPL to inspect the signatures and bytecode generated by the Scala\ncompiler for any classes in your project (or that you have defined in the REPL):\n\n```scala\nscala\u003e :javap -p IntOption\nCompiled from \"MyIntList.scala\"\npublic interface IntOption {\n  public abstract \u003cZ\u003e Z fold(Z, scala.Function1\u003cjava.lang.Object, Z\u003e);\n}\n\nscala\u003e :javap -p SomeInt\nCompiled from \"MyIntList.scala\"\npublic final class SomeInt implements IntOption,scala.Product,scala.Serializable {\n  private final int value;\n  public static scala.Option\u003cjava.lang.Object\u003e unapply(SomeInt);\n  public static SomeInt apply(int);\n  public static \u003cA\u003e scala.Function1\u003cjava.lang.Object, A\u003e andThen(scala.Function1\u003cSomeInt, A\u003e);\n  public static \u003cA\u003e scala.Function1\u003cA, SomeInt\u003e compose(scala.Function1\u003cA, java.lang.Object\u003e);\n  public \u003cZ\u003e Z fold(Z, scala.Function1\u003cjava.lang.Object, Z\u003e);\n  public int value();\n  public SomeInt copy(int);\n  public int copy$default$1();\n  public java.lang.String productPrefix();\n  public int productArity();\n  public java.lang.Object productElement(int);\n  public scala.collection.Iterator\u003cjava.lang.Object\u003e productIterator();\n  public boolean canEqual(java.lang.Object);\n  public int hashCode();\n  public java.lang.String toString();\n  public boolean equals(java.lang.Object);\n  public SomeInt(int);\n}\n```\n\n`:javap` has most of the same options as the `javap` command-line tool, and you\n`javap -help` is useful for understanding what `:javap` can do.\n\n## Scaladoc tips\n\nThe Scala standard library has [extensive API documentation][scala-scaladocs],\nbut some useful features of the Scaladoc interface aren't immediately obvious.\n\n### Browsing symbolic operators\n\nFor example, suppose you see the symbol `/:` in some Scala code. You\ncould try to figure out what type it's being called on and search for that type,\nbut you can also browse symbolic operators like this directly in the Scaladoc\ninterface. To do this, click the small `#` in the upper left corner of the\nscreen.\n\n![Operator list link](/screenshots/operators-01.png)\n\nNow you can search the page for `/:`:\n\n![Operator list](/screenshots/operators-02.png)\n\n### Instance and companion object definitions\n\nAnother simple but useful feature (which I personally only discovered after\nwriting Scala for an embarrassingly long time) is the ability to switch easily\nbetween the docs for a class or trait and its companion object. If you're\nreading the docs for the `List` class, for example:\n\n![Operator list link](/screenshots/class.png)\n\nThe circle with a \"C\" in it is a link that will take you to the docs for the\n`List` companion object:\n\n![Operator list link](/screenshots/object.png)\n\nThere's no need to search for `List` again to be able to select the object\ninstead of the class. Clicking the \"O\" will take you back to the class.\n\n[java]: https://www.java.com/en/download/\n[sbt]: http://www.scala-sbt.org\n[scala-scaladocs]: http://www.scala-lang.org/api/2.11.7/#package\n[string-ops]: http://www.scala-lang.org/api/2.11.7/#scala.collection.immutable.StringOps\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftravisbrown%2Fscala-quickstart","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftravisbrown%2Fscala-quickstart","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftravisbrown%2Fscala-quickstart/lists"}